Skip to content

Commit

Permalink
rustdoc: Collect traits in scope for foreign inherent impls
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Feb 4, 2022
1 parent 4e8fb74 commit afc0030
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 0 deletions.
17 changes: 17 additions & 0 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1369,10 +1369,27 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
)
}

/// Decodes all inherent impls in the crate (for rustdoc).
fn get_inherent_impls(self) -> impl Iterator<Item = (DefId, DefId)> + '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<Item = DefId> + '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<Item = (DefId, DefId, Option<SimplifiedType>)> + 'a {
self.cdata.trait_impls.iter().flat_map(move |((trait_cnum_raw, trait_index), impls)| {
let trait_def_id = DefId {
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,16 +486,26 @@ impl CStore {
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<Item = DefId> + '_ {
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<Item = (DefId, DefId, Option<SimplifiedType>)> + '_ {
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<Item = (DefId, DefId)> + '_ {
self.get_crate_data(cnum).get_inherent_impls()
}
}

impl CrateStore for CStore {
Expand Down
7 changes: 7 additions & 0 deletions src/librustdoc/passes/collect_intra_doc_links/early.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ impl IntraLinkCrateLoader<'_, '_> {
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
Expand All @@ -134,6 +136,11 @@ impl IntraLinkCrateLoader<'_, '_> {
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));
Expand Down
11 changes: 11 additions & 0 deletions src/test/rustdoc/intra-doc/auxiliary/extern-inherent-impl-dep.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#[derive(Clone)]
pub struct PublicStruct;

mod inner {
use super::PublicStruct;

impl PublicStruct {
/// [PublicStruct::clone]
pub fn method() {}
}
}
8 changes: 8 additions & 0 deletions src/test/rustdoc/intra-doc/extern-inherent-impl.rs
Original file line number Diff line number Diff line change
@@ -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;

0 comments on commit afc0030

Please sign in to comment.