diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index fb1c71fb8cdbedfae8aa0ae88c53301f03fed952..bb729807cad9a9cc56af1a1e5107d607a41e8a6e 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1369,10 +1369,27 @@ fn get_inherent_implementations_for_type( ) } + /// Decodes all inherent impls in the crate (for rustdoc). + fn get_inherent_impls(self) -> impl Iterator + 'a { + (0..self.root.tables.inherent_impls.size()).flat_map(move |i| { + let ty_index = DefIndex::from_usize(i); + let ty_def_id = self.local_def_id(ty_index); + self.root + .tables + .inherent_impls + .get(self, ty_index) + .unwrap_or_else(Lazy::empty) + .decode(self) + .map(move |impl_index| (ty_def_id, self.local_def_id(impl_index))) + }) + } + + /// Decodes all traits in the crate (for rustdoc and rustc diagnostics). fn get_traits(self) -> impl Iterator + 'a { self.root.traits.decode(self).map(move |index| self.local_def_id(index)) } + /// Decodes all trait impls in the crate (for rustdoc). fn get_trait_impls(self) -> impl Iterator)> + 'a { self.cdata.trait_impls.iter().flat_map(move |((trait_cnum_raw, trait_index), impls)| { let trait_def_id = DefId { diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 2f8e35648ec2d6f8c31e5ddab6a0ba1e2feda36c..a94c4e2f4e0e88d72a93f49c79c677053d777f67 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -486,16 +486,26 @@ pub fn get_proc_macro_quoted_span_untracked( self.get_crate_data(cnum).get_proc_macro_quoted_span(id, sess) } + /// Decodes all traits in the crate (for rustdoc). pub fn traits_in_crate_untracked(&self, cnum: CrateNum) -> impl Iterator + '_ { self.get_crate_data(cnum).get_traits() } + /// Decodes all trait impls in the crate (for rustdoc). pub fn trait_impls_in_crate_untracked( &self, cnum: CrateNum, ) -> impl Iterator)> + '_ { self.get_crate_data(cnum).get_trait_impls() } + + /// Decodes all inherent impls in the crate (for rustdoc). + pub fn inherent_impls_in_crate_untracked( + &self, + cnum: CrateNum, + ) -> impl Iterator + '_ { + self.get_crate_data(cnum).get_inherent_impls() + } } impl CrateStore for CStore { diff --git a/src/librustdoc/passes/collect_intra_doc_links/early.rs b/src/librustdoc/passes/collect_intra_doc_links/early.rs index edd4e9da66d99043010da3582f9a6163278b457d..e28034b2b0d7a0cd4e26b2309b4a2f5f4ea0972b 100644 --- a/src/librustdoc/passes/collect_intra_doc_links/early.rs +++ b/src/librustdoc/passes/collect_intra_doc_links/early.rs @@ -116,6 +116,8 @@ fn add_foreign_traits_in_scope(&mut self) { let all_traits = Vec::from_iter(self.resolver.cstore().traits_in_crate_untracked(cnum)); let all_trait_impls = Vec::from_iter(self.resolver.cstore().trait_impls_in_crate_untracked(cnum)); + let all_inherent_impls = + Vec::from_iter(self.resolver.cstore().inherent_impls_in_crate_untracked(cnum)); // Querying traits in scope is expensive so we try to prune the impl and traits lists // using privacy, private traits and impls from other crates are never documented in @@ -134,6 +136,11 @@ fn add_foreign_traits_in_scope(&mut self) { self.add_traits_in_parent_scope(impl_def_id); } } + for (ty_def_id, impl_def_id) in all_inherent_impls { + if self.resolver.cstore().visibility_untracked(ty_def_id) == Visibility::Public { + self.add_traits_in_parent_scope(impl_def_id); + } + } self.all_traits.extend(all_traits); self.all_trait_impls.extend(all_trait_impls.into_iter().map(|(_, def_id, _)| def_id)); diff --git a/src/test/rustdoc/intra-doc/auxiliary/extern-inherent-impl-dep.rs b/src/test/rustdoc/intra-doc/auxiliary/extern-inherent-impl-dep.rs new file mode 100644 index 0000000000000000000000000000000000000000..ee4138b6865a014c8cbedddb043256a0e7cec875 --- /dev/null +++ b/src/test/rustdoc/intra-doc/auxiliary/extern-inherent-impl-dep.rs @@ -0,0 +1,11 @@ +#[derive(Clone)] +pub struct PublicStruct; + +mod inner { + use super::PublicStruct; + + impl PublicStruct { + /// [PublicStruct::clone] + pub fn method() {} + } +} diff --git a/src/test/rustdoc/intra-doc/extern-inherent-impl.rs b/src/test/rustdoc/intra-doc/extern-inherent-impl.rs new file mode 100644 index 0000000000000000000000000000000000000000..2e41c2214f4fe87664ef3ae870c88b0de162e38b --- /dev/null +++ b/src/test/rustdoc/intra-doc/extern-inherent-impl.rs @@ -0,0 +1,8 @@ +// Reexport of a structure with public inherent impls having doc links in their comments. The doc +// link points to an associated item, so we check that traits in scope for that link are populated. + +// aux-build:extern-inherent-impl-dep.rs + +extern crate extern_inherent_impl_dep; + +pub use extern_inherent_impl_dep::PublicStruct;