From 56aba6d1bb319592d41b692e7f3b263f6a710c0d Mon Sep 17 00:00:00 2001 From: Lamb Date: Sat, 15 Jan 2022 23:13:56 +0000 Subject: [PATCH 1/4] track inlined items and merge their docstrings later --- src/librustdoc/clean/types.rs | 9 ++++++++- src/librustdoc/formats/cache.rs | 4 ++++ src/librustdoc/visit_ast.rs | 9 +++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 00c6e38839f54..f2b6357b8ebdd 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -445,12 +445,19 @@ impl Item { cx: &mut DocContext<'_>, ) -> Item { let ast_attrs = cx.tcx.get_attrs(def_id); + let mut clean_attrs = box ast_attrs.clean(cx); + + if let Some(items) = cx.cache.inlined_items.get(&def_id) { + tracing::debug!("associating attributes from associated inlined items: {:?}", items); + let other_attrs = box cx.tcx.get_attrs(def_id).clean(cx); + clean_attrs.doc_strings.extend(other_attrs.doc_strings); + } Self::from_def_id_and_attrs_and_parts( def_id, name, kind, - box ast_attrs.clean(cx), + clean_attrs, cx, ast_attrs.cfg(cx.tcx, &cx.cache.hidden_cfg), ) diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index a8fef4a317802..fe3608d856df7 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -58,6 +58,10 @@ crate struct Cache { /// the impl for the inlined type. crate exact_paths: FxHashMap>, + /// Associates every items with all of its public reexports. This is used to merge + /// every docstrings that are relevant to show. + crate inlined_items: FxHashMap>, + /// This map contains information about all known traits of this crate. /// Implementations of a crate should inherit the documentation of the /// parent trait if no extra documentation is specified, and default methods diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 90cb5d586c211..99bc97e1f76aa 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -68,6 +68,7 @@ crate struct RustdocVisitor<'a, 'tcx> { /// Are the current module and all of its parents public? inside_public_path: bool, exact_paths: FxHashMap>, + inlined_items: FxHashMap>, } impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { @@ -78,6 +79,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { RustdocVisitor { cx, view_item_stack: stack, + inlined_items: FxHashMap::default(), inlining: false, inside_public_path: true, exact_paths: FxHashMap::default(), @@ -144,6 +146,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { .collect(); self.cx.cache.exact_paths = self.exact_paths; + self.cx.cache.inlined_items = self.inlined_items; + top_level_module } @@ -194,6 +198,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { }; let use_attrs = tcx.hir().attrs(id); + // Don't inline `doc(hidden)` imports so they can be stripped at a later stage. let is_no_inline = use_attrs.lists(sym::doc).has_word(sym::no_inline) || use_attrs.lists(sym::doc).has_word(sym::hidden); @@ -320,6 +325,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { om, please_inline, ) { + self.inlined_items + .entry(path.res.def_id()) + .or_default() + .push(item.def_id.to_def_id()); return; } } From bf47b8b91cb06a34fccf234c9fde307ae3c35e30 Mon Sep 17 00:00:00 2001 From: Lamb Date: Sat, 15 Jan 2022 23:26:04 +0000 Subject: [PATCH 2/4] removing useless box --- src/librustdoc/clean/types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index f2b6357b8ebdd..88cca376a5bc5 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -449,7 +449,7 @@ impl Item { if let Some(items) = cx.cache.inlined_items.get(&def_id) { tracing::debug!("associating attributes from associated inlined items: {:?}", items); - let other_attrs = box cx.tcx.get_attrs(def_id).clean(cx); + let other_attrs = cx.tcx.get_attrs(def_id).clean(cx); clean_attrs.doc_strings.extend(other_attrs.doc_strings); } From 6422547a77b8ee3210732a85434071aad44b4520 Mon Sep 17 00:00:00 2001 From: Lamb Date: Sat, 15 Jan 2022 23:39:27 +0000 Subject: [PATCH 3/4] forgot to loop over the inlined item def ids... --- src/librustdoc/clean/types.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 88cca376a5bc5..f0991306307a1 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -447,10 +447,12 @@ impl Item { let ast_attrs = cx.tcx.get_attrs(def_id); let mut clean_attrs = box ast_attrs.clean(cx); - if let Some(items) = cx.cache.inlined_items.get(&def_id) { - tracing::debug!("associating attributes from associated inlined items: {:?}", items); - let other_attrs = cx.tcx.get_attrs(def_id).clean(cx); - clean_attrs.doc_strings.extend(other_attrs.doc_strings); + if let Some(inlined_ids) = cx.cache.inlined_items.get(&def_id).cloned() { + tracing::debug!("extending docstrings of {:?} with {:?}", def_id, inlined_ids); + for &inlined_id in inlined_ids.iter() { + let other_attrs = cx.tcx.get_attrs(inlined_id).clean(cx); + clean_attrs.doc_strings.extend(other_attrs.doc_strings); + } } Self::from_def_id_and_attrs_and_parts( From a5581ba1c26a6b63ec314d19b7fde793e2a160c3 Mon Sep 17 00:00:00 2001 From: Lamb Date: Sun, 16 Jan 2022 00:19:07 +0000 Subject: [PATCH 4/4] use local def id when possible --- src/librustdoc/formats/cache.rs | 5 +++-- src/librustdoc/visit_ast.rs | 9 +++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index fe3608d856df7..182d484cb34ef 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -1,7 +1,7 @@ use std::mem; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; +use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX}; use rustc_middle::middle::privacy::AccessLevels; use rustc_middle::ty::TyCtxt; use rustc_span::{sym, Symbol}; @@ -53,6 +53,7 @@ crate struct Cache { /// This map is used when writing out the special 'implementors' /// javascript file. By using the exact path that the type /// is declared with, we ensure that each path will be identical + /// /// to the path used if the corresponding type is inlined. By /// doing this, we can detect duplicate impls on a trait page, and only display /// the impl for the inlined type. @@ -60,7 +61,7 @@ crate struct Cache { /// Associates every items with all of its public reexports. This is used to merge /// every docstrings that are relevant to show. - crate inlined_items: FxHashMap>, + crate inlined_items: FxHashMap>, /// This map contains information about all known traits of this crate. /// Implementations of a crate should inherit the documentation of the diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 99bc97e1f76aa..2f48100e5b328 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -4,7 +4,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::Node; use rustc_hir::CRATE_HIR_ID; use rustc_middle::middle::privacy::AccessLevel; @@ -68,7 +68,7 @@ crate struct RustdocVisitor<'a, 'tcx> { /// Are the current module and all of its parents public? inside_public_path: bool, exact_paths: FxHashMap>, - inlined_items: FxHashMap>, + inlined_items: FxHashMap>, } impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { @@ -325,10 +325,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { om, please_inline, ) { - self.inlined_items - .entry(path.res.def_id()) - .or_default() - .push(item.def_id.to_def_id()); + self.inlined_items.entry(path.res.def_id()).or_default().push(item.def_id); return; } }