Skip to content

Commit

Permalink
Rollup merge of #93441 - notriddle:notriddle/collect-crate-doc-links-…
Browse files Browse the repository at this point in the history
…very-early, r=petrochenkov

rustdoc: load the set of in-scope traits for modules with no docstring

Fixes #93428

This fix is a response to a couple of special cases related to the `module_id`, which is eventually used for trait candidates:

  * The module id is always set to the current crate, when checking `crate::`.

    Normally, the set of in-scope traits would be set in `load_links_in_attrs`, but if there are no doc comments, then that loop will never run.

  * the module id is set to the parent module, when resolving a module that is spelled like this:

        // Notice how we use an outlined doc comment here!
        // [`Test::my_fn`]
        mod something {
        }

    As with the above problem with `crate::`, we need to make sure the module gets its traits in scope resolved, even if it has no doc comments of its own.
  • Loading branch information
matthiaskrgr authored Jan 29, 2022
2 parents 329753e + 3903ca1 commit 605ffd6
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/librustdoc/passes/collect_intra_doc_links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,7 @@ fn trait_assoc_to_impl_assoc_item<'tcx>(
///
/// NOTE: this cannot be a query because more traits could be available when more crates are compiled!
/// So it is not stable to serialize cross-crate.
#[instrument(level = "debug", skip(cx))]
fn trait_impls_for<'a>(
cx: &mut DocContext<'a>,
ty: Ty<'a>,
Expand Down
10 changes: 10 additions & 0 deletions src/librustdoc/passes/collect_intra_doc_links/early.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ crate fn early_resolve_intra_doc_links(
all_trait_impls: Default::default(),
};

// Because of the `crate::` prefix, any doc comment can reference
// the crate root's set of in-scope traits. This line makes sure
// it's available.
loader.add_traits_in_scope(CRATE_DEF_ID.to_def_id());

// Overridden `visit_item` below doesn't apply to the crate root,
// so we have to visit its attributes and reexports separately.
loader.load_links_in_attrs(&krate.attrs, krate.span);
Expand Down Expand Up @@ -180,6 +185,11 @@ impl Visitor<'_> for IntraLinkCrateLoader<'_, '_> {
if let ItemKind::Mod(..) = item.kind {
let old_mod = mem::replace(&mut self.current_mod, self.resolver.local_def_id(item.id));

// A module written with a outline doc comments will resolve traits relative
// to the parent module. Make sure the parent module's traits-in-scope are
// loaded, even if the module itself has no doc comments.
self.add_traits_in_parent_scope(self.current_mod.to_def_id());

self.load_links_in_attrs(&item.attrs, item.span);
self.process_module_children_or_reexports(self.current_mod.to_def_id());
visit::walk_item(self, item);
Expand Down
13 changes: 13 additions & 0 deletions src/test/rustdoc/intra-doc/crate-relative.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
pub struct Test<'a> {
data: &'a (),
}

impl<'a> Test<'a> {
pub fn do_test(&self) {}
}

// @has crate_relative/demo/index.html
// @has - '//a/@href' '../struct.Test.html#method.do_test'
pub mod demo {
//! [`crate::Test::do_test`]
}
17 changes: 17 additions & 0 deletions src/test/rustdoc/intra-doc/mod-relative.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
pub mod wrapper {

pub struct Test<'a> {
data: &'a (),
}

impl<'a> Test<'a> {
pub fn do_test(&self) {}
}

// @has mod_relative/wrapper/demo/index.html
// @has - '//a/@href' '../struct.Test.html#method.do_test'
/// [`Test::do_test`]
pub mod demo {
}

}

0 comments on commit 605ffd6

Please sign in to comment.