Skip to content

Commit 2093084

Browse files
committed
Auto merge of #38105 - ollie27:rustdoc_deterministic_js, r=GuillaumeGomez
rustdoc: Sort lines in search index and implementors js This means the files are generated deterministically even with rustdoc running in parallel. Fixes the first part of #30220.
2 parents 7846610 + d6ec686 commit 2093084

File tree

1 file changed

+26
-24
lines changed

1 file changed

+26
-24
lines changed

src/librustdoc/html/render.rs

+26-24
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use std::cmp::Ordering;
4040
use std::collections::BTreeMap;
4141
use std::default::Default;
4242
use std::error;
43-
use std::fmt::{self, Display, Formatter};
43+
use std::fmt::{self, Display, Formatter, Write as FmtWrite};
4444
use std::fs::{self, File, OpenOptions};
4545
use std::io::prelude::*;
4646
use std::io::{self, BufWriter, BufReader};
@@ -726,18 +726,20 @@ fn write_shared(cx: &Context,
726726

727727
// Update the search index
728728
let dst = cx.dst.join("search-index.js");
729-
let all_indexes = try_err!(collect(&dst, &krate.name, "searchIndex"), &dst);
729+
let mut all_indexes = try_err!(collect(&dst, &krate.name, "searchIndex"), &dst);
730+
all_indexes.push(search_index);
731+
// Sort the indexes by crate so the file will be generated identically even
732+
// with rustdoc running in parallel.
733+
all_indexes.sort();
730734
let mut w = try_err!(File::create(&dst), &dst);
731735
try_err!(writeln!(&mut w, "var searchIndex = {{}};"), &dst);
732-
try_err!(writeln!(&mut w, "{}", search_index), &dst);
733736
for index in &all_indexes {
734737
try_err!(writeln!(&mut w, "{}", *index), &dst);
735738
}
736739
try_err!(writeln!(&mut w, "initSearch(searchIndex);"), &dst);
737740

738741
// Update the list of all implementors for traits
739742
let dst = cx.dst.join("implementors");
740-
try_err!(mkdir(&dst), &dst);
741743
for (&did, imps) in &cache.implementors {
742744
// Private modules can leak through to this phase of rustdoc, which
743745
// could contain implementations for otherwise private types. In some
@@ -754,37 +756,37 @@ fn write_shared(cx: &Context,
754756
}
755757
};
756758

759+
let mut implementors = format!(r#"implementors["{}"] = ["#, krate.name);
760+
for imp in imps {
761+
// If the trait and implementation are in the same crate, then
762+
// there's no need to emit information about it (there's inlining
763+
// going on). If they're in different crates then the crate defining
764+
// the trait will be interested in our implementation.
765+
if imp.def_id.krate == did.krate { continue }
766+
write!(implementors, r#""{}","#, imp.impl_).unwrap();
767+
}
768+
implementors.push_str("];");
769+
757770
let mut mydst = dst.clone();
758771
for part in &remote_path[..remote_path.len() - 1] {
759772
mydst.push(part);
760-
try_err!(mkdir(&mydst), &mydst);
761773
}
774+
try_err!(fs::create_dir_all(&mydst), &mydst);
762775
mydst.push(&format!("{}.{}.js",
763776
remote_item_type.css_class(),
764777
remote_path[remote_path.len() - 1]));
765-
let all_implementors = try_err!(collect(&mydst, &krate.name,
766-
"implementors"),
767-
&mydst);
768778

769-
try_err!(mkdir(mydst.parent().unwrap()),
770-
&mydst.parent().unwrap().to_path_buf());
771-
let mut f = BufWriter::new(try_err!(File::create(&mydst), &mydst));
772-
try_err!(writeln!(&mut f, "(function() {{var implementors = {{}};"), &mydst);
779+
let mut all_implementors = try_err!(collect(&mydst, &krate.name, "implementors"), &mydst);
780+
all_implementors.push(implementors);
781+
// Sort the implementors by crate so the file will be generated
782+
// identically even with rustdoc running in parallel.
783+
all_implementors.sort();
773784

785+
let mut f = try_err!(File::create(&mydst), &mydst);
786+
try_err!(writeln!(&mut f, "(function() {{var implementors = {{}};"), &mydst);
774787
for implementor in &all_implementors {
775-
try_err!(write!(&mut f, "{}", *implementor), &mydst);
776-
}
777-
778-
try_err!(write!(&mut f, r#"implementors["{}"] = ["#, krate.name), &mydst);
779-
for imp in imps {
780-
// If the trait and implementation are in the same crate, then
781-
// there's no need to emit information about it (there's inlining
782-
// going on). If they're in different crates then the crate defining
783-
// the trait will be interested in our implementation.
784-
if imp.def_id.krate == did.krate { continue }
785-
try_err!(write!(&mut f, r#""{}","#, imp.impl_), &mydst);
788+
try_err!(writeln!(&mut f, "{}", *implementor), &mydst);
786789
}
787-
try_err!(writeln!(&mut f, r"];"), &mydst);
788790
try_err!(writeln!(&mut f, "{}", r"
789791
if (window.register_implementors) {
790792
window.register_implementors(implementors);

0 commit comments

Comments
 (0)