diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index da6840c72f5b1..a4cbef8c39177 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -24,6 +24,7 @@ use tracing::instrument; use crate::clean::types::{Function, Generics, ItemId, Type, WherePredicate}; use crate::clean::{self, utils}; +use crate::config::ShouldMerge; use crate::error::Error; use crate::formats::cache::{Cache, OrphanImplItem}; use crate::formats::item_type::ItemType; @@ -721,7 +722,9 @@ impl SerializedSearchIndex { } }, ), - self.alias_pointers[id].and_then(|alias| map.get(&alias).copied()), + self.alias_pointers[id].and_then(|alias| { + if self.names[alias].is_empty() { None } else { map.get(&alias).copied() } + }), ); } new.generic_inverted_index = self @@ -1248,6 +1251,7 @@ pub(crate) fn build_index( tcx: TyCtxt<'_>, doc_root: &Path, resource_suffix: &str, + should_merge: &ShouldMerge, ) -> Result { let mut search_index = std::mem::take(&mut cache.search_index); @@ -1298,7 +1302,11 @@ pub(crate) fn build_index( // // if there's already a search index, load it into memory and add the new entries to it // otherwise, do nothing - let mut serialized_index = SerializedSearchIndex::load(doc_root, resource_suffix)?; + let mut serialized_index = if should_merge.read_rendered_cci { + SerializedSearchIndex::load(doc_root, resource_suffix)? + } else { + SerializedSearchIndex::default() + }; // The crate always goes first in this list let crate_name = krate.name(tcx); diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 9a8df53931394..6bf116c3b75ad 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -66,8 +66,14 @@ pub(crate) fn write_shared( // Write shared runs within a flock; disable thread dispatching of IO temporarily. let _lock = try_err!(flock::Lock::new(&lock_file, true, true, true), &lock_file); - let search_index = - build_index(krate, &mut cx.shared.cache, tcx, &cx.dst, &cx.shared.resource_suffix)?; + let search_index = build_index( + krate, + &mut cx.shared.cache, + tcx, + &cx.dst, + &cx.shared.resource_suffix, + &opt.should_merge, + )?; let crate_name = krate.name(cx.tcx()); let crate_name = crate_name.as_str(); // rand diff --git a/tests/run-make/rustdoc-merge-directory-alias/dep1.rs b/tests/run-make/rustdoc-merge-directory-alias/dep1.rs new file mode 100644 index 0000000000000..b62f31c982b7f --- /dev/null +++ b/tests/run-make/rustdoc-merge-directory-alias/dep1.rs @@ -0,0 +1,10 @@ +pub struct Dep1; +pub struct Dep2; +pub struct Dep3; +pub struct Dep4; + +//@ hasraw crates.js 'dep1' +//@ hasraw search.index/name/*.js 'Dep1' +//@ has dep1/index.html +#[doc(alias = "dep1_missing")] +pub struct Dep5; diff --git a/tests/run-make/rustdoc-merge-directory-alias/dep2.rs b/tests/run-make/rustdoc-merge-directory-alias/dep2.rs new file mode 100644 index 0000000000000..2df4452413c21 --- /dev/null +++ b/tests/run-make/rustdoc-merge-directory-alias/dep2.rs @@ -0,0 +1,4 @@ +//@ hasraw crates.js 'dep2' +//@ hasraw search.index/name/*.js 'Second' +//@ has dep2/index.html +pub struct Second; diff --git a/tests/run-make/rustdoc-merge-directory-alias/dep_missing.rs b/tests/run-make/rustdoc-merge-directory-alias/dep_missing.rs new file mode 100644 index 0000000000000..74236aef47ea5 --- /dev/null +++ b/tests/run-make/rustdoc-merge-directory-alias/dep_missing.rs @@ -0,0 +1,4 @@ +//@ !hasraw crates.js 'dep_missing' +//@ !hasraw search.index/name/*.js 'DepMissing' +//@ has dep_missing/index.html +pub struct DepMissing; diff --git a/tests/run-make/rustdoc-merge-directory-alias/rmake.rs b/tests/run-make/rustdoc-merge-directory-alias/rmake.rs new file mode 100644 index 0000000000000..096eb4a487c15 --- /dev/null +++ b/tests/run-make/rustdoc-merge-directory-alias/rmake.rs @@ -0,0 +1,88 @@ +// Running --merge=finalize without an input crate root should not trigger ICE. +// Issue: https://github.com/rust-lang/rust/issues/146646 + +//@ needs-target-std + +use run_make_support::{htmldocck, path, rustdoc}; + +fn main() { + let out_dir = path("out"); + let merged_dir = path("merged"); + let parts_out_dir = path("parts"); + + rustdoc() + .input("dep1.rs") + .out_dir(&out_dir) + .arg("-Zunstable-options") + .arg(format!("--parts-out-dir={}", parts_out_dir.display())) + .arg("--merge=none") + .run(); + assert!(parts_out_dir.join("dep1.json").exists()); + + let output = rustdoc() + .arg("-Zunstable-options") + .out_dir(&out_dir) + .arg(format!("--include-parts-dir={}", parts_out_dir.display())) + .arg("--merge=finalize") + .run(); + output.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug."); + + rustdoc() + .input("dep2.rs") + .out_dir(&out_dir) + .arg("-Zunstable-options") + .arg(format!("--parts-out-dir={}", parts_out_dir.display())) + .arg("--merge=none") + .run(); + assert!(parts_out_dir.join("dep2.json").exists()); + + let output2 = rustdoc() + .arg("-Zunstable-options") + .out_dir(&out_dir) + .arg(format!("--include-parts-dir={}", parts_out_dir.display())) + .arg("--merge=finalize") + .run(); + output2.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug."); + + rustdoc() + .input("dep1.rs") + .out_dir(&out_dir) + .arg("-Zunstable-options") + .arg(format!("--parts-out-dir={}", parts_out_dir.display())) + .arg("--merge=none") + .run(); + assert!(parts_out_dir.join("dep1.json").exists()); + + let output3 = rustdoc() + .arg("-Zunstable-options") + .out_dir(&out_dir) + .arg(format!("--include-parts-dir={}", parts_out_dir.display())) + .arg("--merge=finalize") + .run(); + output3.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug."); + + // dep_missing is different, because --parts-out-dir is not supplied + rustdoc().input("dep_missing.rs").out_dir(&out_dir).run(); + assert!(parts_out_dir.join("dep2.json").exists()); + + rustdoc() + .input("dep1.rs") + .out_dir(&out_dir) + .arg("-Zunstable-options") + .arg(format!("--parts-out-dir={}", parts_out_dir.display())) + .arg("--merge=none") + .run(); + assert!(parts_out_dir.join("dep1.json").exists()); + + let output4 = rustdoc() + .arg("-Zunstable-options") + .out_dir(&out_dir) + .arg(format!("--include-parts-dir={}", parts_out_dir.display())) + .arg("--merge=finalize") + .run(); + output4.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug."); + + htmldocck().arg(&out_dir).arg("dep1.rs").run(); + htmldocck().arg(&out_dir).arg("dep2.rs").run(); + htmldocck().arg(&out_dir).arg("dep_missing.rs").run(); +}