From 27d47d93be38911c365b11ad36536e4ed926fc76 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 28 Oct 2021 20:58:53 -0700 Subject: [PATCH 1/5] rustdoc: Add static size assertion for `clean::Crate` --- src/librustdoc/clean/types.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 6ae057abb3d..4604315ac69 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -125,6 +125,10 @@ crate struct Crate { crate collapsed: bool, } +// `Crate` is frequently moved by-value. Make sure it doesn't unintentionally get bigger. +#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] +rustc_data_structures::static_assert_size!(Crate, 168); + /// This struct is used to wrap additional information added by rustdoc on a `trait` item. #[derive(Clone, Debug)] crate struct TraitWithExtraInfo { From 47b0059dba00a9982721f346b46ceca32620700e Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Fri, 29 Oct 2021 19:59:49 -0700 Subject: [PATCH 2/5] rustdoc: Document that `Crate` is always local --- src/librustdoc/clean/types.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 4604315ac69..c0ceb9a09f4 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -113,6 +113,7 @@ impl From for ItemId { } } +/// The crate currently being documented. #[derive(Clone, Debug)] crate struct Crate { crate name: Symbol, @@ -142,6 +143,8 @@ crate struct ExternalCrate { } impl ExternalCrate { + const LOCAL: Self = Self { crate_num: LOCAL_CRATE }; + #[inline] crate fn def_id(&self) -> DefId { DefId { krate: self.crate_num, index: CRATE_DEF_INDEX } From 85f8ae8ec49683df08a598b0f2594dd066f24a11 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 28 Oct 2021 20:48:48 -0700 Subject: [PATCH 3/5] rustdoc: Remove `Crate.src` and instead compute it on-demand It is only used in one place; `src` was about a third of `Crate`'s total size; `Crate` is frequently moved by-value; and `src` can be easily computed on-demand. --- src/librustdoc/clean/types.rs | 9 +++++++-- src/librustdoc/clean/utils.rs | 2 -- src/librustdoc/html/render/context.rs | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index c0ceb9a09f4..24a51a3f154 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -117,7 +117,6 @@ impl From for ItemId { #[derive(Clone, Debug)] crate struct Crate { crate name: Symbol, - crate src: FileName, crate module: Item, crate externs: Vec, crate primitives: ThinVec<(DefId, PrimitiveType)>, @@ -128,7 +127,13 @@ crate struct Crate { // `Crate` is frequently moved by-value. Make sure it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(Crate, 168); +rustc_data_structures::static_assert_size!(Crate, 104); + +impl Crate { + crate fn src(&self, tcx: TyCtxt<'_>) -> FileName { + ExternalCrate::LOCAL.src(tcx) + } +} /// This struct is used to wrap additional information added by rustdoc on a `trait` item. #[derive(Clone, Debug)] diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 0573a1ada3a..c000b656e6a 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -57,7 +57,6 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate { } let local_crate = ExternalCrate { crate_num: LOCAL_CRATE }; - let src = local_crate.src(cx.tcx); let name = local_crate.name(cx.tcx); let primitives = local_crate.primitives(cx.tcx); let keywords = local_crate.keywords(cx.tcx); @@ -81,7 +80,6 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate { Crate { name, - src, module, externs, primitives, diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 0e29cc85f9e..4a0bcd0e99c 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -405,7 +405,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { .. } = options; - let src_root = match krate.src { + let src_root = match krate.src(tcx) { FileName::Real(ref p) => match p.local_path_if_available().parent() { Some(p) => p.to_path_buf(), None => PathBuf::new(), From ebe9a11f71f2998e0be4d9b95f4eac5d1e1f82a0 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Thu, 28 Oct 2021 20:55:02 -0700 Subject: [PATCH 4/5] rustdoc: Remove `Crate.name` and instead compute it on-demand It is not as large as `Crate.src` was, but it's still 8 bytes, and `clean::Crate` is moved by-value a lot. --- src/librustdoc/clean/types.rs | 5 ++++- src/librustdoc/clean/utils.rs | 2 -- src/librustdoc/html/render/cache.rs | 2 +- src/librustdoc/html/render/context.rs | 6 +++--- src/librustdoc/html/render/write_shared.rs | 13 +++++++------ src/librustdoc/html/sources.rs | 2 +- 6 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 24a51a3f154..88fffaecb93 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -116,7 +116,6 @@ impl From for ItemId { /// The crate currently being documented. #[derive(Clone, Debug)] crate struct Crate { - crate name: Symbol, crate module: Item, crate externs: Vec, crate primitives: ThinVec<(DefId, PrimitiveType)>, @@ -130,6 +129,10 @@ crate struct Crate { rustc_data_structures::static_assert_size!(Crate, 104); impl Crate { + crate fn name(&self, tcx: TyCtxt<'_>) -> Symbol { + ExternalCrate::LOCAL.name(tcx) + } + crate fn src(&self, tcx: TyCtxt<'_>) -> FileName { ExternalCrate::LOCAL.src(tcx) } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index c000b656e6a..b0da92081c1 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -57,7 +57,6 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate { } let local_crate = ExternalCrate { crate_num: LOCAL_CRATE }; - let name = local_crate.name(cx.tcx); let primitives = local_crate.primitives(cx.tcx); let keywords = local_crate.keywords(cx.tcx); { @@ -79,7 +78,6 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate { } Crate { - name, module, externs, primitives, diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 0bbc510f7cb..7a6d70e8fbc 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -172,7 +172,7 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt< // Collect the index into a string format!( r#""{}":{}"#, - krate.name, + krate.name(tcx), serde_json::to_string(&CrateData { doc: crate_doc, items: crate_items, diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 4a0bcd0e99c..e4c759a5705 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -416,14 +416,14 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { let mut playground = None; if let Some(url) = playground_url { playground = - Some(markdown::Playground { crate_name: Some(krate.name.to_string()), url }); + Some(markdown::Playground { crate_name: Some(krate.name(tcx).to_string()), url }); } let mut layout = layout::Layout { logo: String::new(), favicon: String::new(), external_html, default_settings, - krate: krate.name.to_string(), + krate: krate.name(tcx).to_string(), css_file_extension: extension_css, generate_search_filter, scrape_examples_extension: !call_locations.is_empty(), @@ -444,7 +444,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { } (sym::html_playground_url, Some(s)) => { playground = Some(markdown::Playground { - crate_name: Some(krate.name.to_string()), + crate_name: Some(krate.name(tcx).to_string()), url: s.to_string(), }); } diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 34f1b4cd684..08f4435c45c 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -455,10 +455,10 @@ pub(super) fn write_shared( let dst = cx.dst.join(&format!("source-files{}.js", cx.shared.resource_suffix)); let make_sources = || { let (mut all_sources, _krates) = - try_err!(collect(&dst, &krate.name.as_str(), "sourcesIndex"), &dst); + try_err!(collect(&dst, &krate.name(cx.tcx()).as_str(), "sourcesIndex"), &dst); all_sources.push(format!( "sourcesIndex[\"{}\"] = {};", - &krate.name, + &krate.name(cx.tcx()), hierarchy.to_json_string() )); all_sources.sort(); @@ -473,9 +473,10 @@ pub(super) fn write_shared( // Update the search index and crate list. let dst = cx.dst.join(&format!("search-index{}.js", cx.shared.resource_suffix)); - let (mut all_indexes, mut krates) = try_err!(collect_json(&dst, &krate.name.as_str()), &dst); + let (mut all_indexes, mut krates) = + try_err!(collect_json(&dst, &krate.name(cx.tcx()).as_str()), &dst); all_indexes.push(search_index); - krates.push(krate.name.to_string()); + krates.push(krate.name(cx.tcx()).to_string()); krates.sort(); // Sort the indexes by crate so the file will be generated identically even @@ -599,7 +600,7 @@ pub(super) fn write_shared( let implementors = format!( r#"implementors["{}"] = {};"#, - krate.name, + krate.name(cx.tcx()), serde_json::to_string(&implementors).unwrap() ); @@ -611,7 +612,7 @@ pub(super) fn write_shared( mydst.push(&format!("{}.{}.js", remote_item_type, remote_path[remote_path.len() - 1])); let (mut all_implementors, _) = - try_err!(collect(&mydst, &krate.name.as_str(), "implementors"), &mydst); + try_err!(collect(&mydst, &krate.name(cx.tcx()).as_str(), "implementors"), &mydst); all_implementors.push(implementors); // Sort the implementors by crate so the file will be generated // identically even with rustdoc running in parallel. diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index 667bbc24ba5..9422f84f997 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -18,7 +18,7 @@ use std::path::{Component, Path, PathBuf}; crate fn render(cx: &mut Context<'_>, krate: clean::Crate) -> Result { info!("emitting source files"); - let dst = cx.dst.join("src").join(&*krate.name.as_str()); + let dst = cx.dst.join("src").join(&*krate.name(cx.tcx()).as_str()); cx.shared.ensure_dir(&dst)?; let mut folder = SourceCollector { dst, cx, emitted_local_sources: FxHashSet::default() }; Ok(folder.fold_crate(krate)) From a58e21489424de9ce1fb48c2d4a7113dcd62f095 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Fri, 29 Oct 2021 20:57:12 -0700 Subject: [PATCH 5/5] rustdoc: Stop sorting external crates Now that #73423 is fixed, sorting should no longer be necessary. See also this discussion [1]. [1]: https://github.com/rust-lang/rust/pull/86889#discussion_r664134963 --- src/librustdoc/clean/utils.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index b0da92081c1..2fae3163a1a 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -29,12 +29,11 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate { let module = crate::visit_ast::RustdocVisitor::new(cx).visit(); let mut externs = Vec::new(); - for &cnum in cx.tcx.crates(()).iter() { + for &cnum in cx.tcx.crates(()) { externs.push(ExternalCrate { crate_num: cnum }); // Analyze doc-reachability for extern items LibEmbargoVisitor::new(cx).visit_lib(cnum); } - externs.sort_unstable_by_key(|e| e.crate_num); // Clean the crate, translating the entire librustc_ast AST to one that is // understood by rustdoc.