From e0b71fff2a052a83ad00ead18b01149581f4e0e2 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 21 Apr 2022 01:09:48 +0300 Subject: [PATCH] [WIP] rustdoc: Resolve some more doc links early --- .../src/rmeta/decoder/cstore_impl.rs | 8 ++++++ src/librustdoc/lib.rs | 1 + .../passes/collect_intra_doc_links/early.rs | 26 ++++++++++++++----- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 6b1f7d55026..1156a78e8a9 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -532,6 +532,14 @@ impl CStore { self.get_crate_data(cnum).get_all_incoherent_impls() } + pub fn associated_item_def_ids_untracked<'a>( + &'a self, + def_id: DefId, + sess: &'a Session, + ) -> impl Iterator + 'a { + self.get_crate_data(def_id.krate).get_associated_item_def_ids(def_id.index, sess) + } + pub fn may_have_doc_links_untracked(&self, def_id: DefId) -> bool { self.get_crate_data(def_id.krate).get_may_have_doc_links(def_id.index) } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 0fcfabba4c0..cd196a01847 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -795,6 +795,7 @@ fn main_options(options: config::Options) -> MainResult { let resolver_caches = resolver.borrow_mut().access(|resolver| { collect_intra_doc_links::early_resolve_intra_doc_links( resolver, + sess, krate, externs, document_private, diff --git a/src/librustdoc/passes/collect_intra_doc_links/early.rs b/src/librustdoc/passes/collect_intra_doc_links/early.rs index e2359da870e..98dba658cc6 100644 --- a/src/librustdoc/passes/collect_intra_doc_links/early.rs +++ b/src/librustdoc/passes/collect_intra_doc_links/early.rs @@ -14,6 +14,7 @@ use rustc_hir::TraitCandidate; use rustc_middle::ty::{DefIdTree, Visibility}; use rustc_resolve::{ParentScope, Resolver}; use rustc_session::config::Externs; +use rustc_session::Session; use rustc_span::{Symbol, SyntaxContext}; use std::collections::hash_map::Entry; @@ -21,12 +22,14 @@ use std::mem; crate fn early_resolve_intra_doc_links( resolver: &mut Resolver<'_>, + sess: &Session, krate: &ast::Crate, externs: Externs, document_private_items: bool, ) -> ResolverCaches { let mut link_resolver = EarlyDocLinkResolver { resolver, + sess, current_mod: CRATE_DEF_ID, visited_mods: Default::default(), markdown_links: Default::default(), @@ -70,6 +73,7 @@ fn doc_attrs<'a>(attrs: impl Iterator) -> Attributes struct EarlyDocLinkResolver<'r, 'ra> { resolver: &'r mut Resolver<'ra>, + sess: &'r Session, current_mod: LocalDefId, visited_mods: DefIdSet, markdown_links: FxHashMap>, @@ -167,14 +171,22 @@ impl EarlyDocLinkResolver<'_, '_> { } } - fn resolve_doc_links_extern_impl(&mut self, def_id: DefId, _is_inherent: bool) { - // FIXME: Resolve links in associated items in addition to traits themselves, - // `force` is used to provide traits in scope for the associated items. - self.resolve_doc_links_extern_outer(def_id, def_id, true); + fn resolve_doc_links_extern_impl(&mut self, def_id: DefId, is_inherent: bool) { + self.resolve_doc_links_extern_outer(def_id, def_id); + let assoc_item_def_ids = Vec::from_iter( + self.resolver.cstore().associated_item_def_ids_untracked(def_id, self.sess), + ); + for assoc_def_id in assoc_item_def_ids { + if !is_inherent + || self.resolver.cstore().visibility_untracked(assoc_def_id) == Visibility::Public + { + self.resolve_doc_links_extern_outer(assoc_def_id, def_id); + } + } } - fn resolve_doc_links_extern_outer(&mut self, def_id: DefId, scope_id: DefId, force: bool) { - if !force && !self.resolver.cstore().may_have_doc_links_untracked(def_id) { + fn resolve_doc_links_extern_outer(&mut self, def_id: DefId, scope_id: DefId) { + if !self.resolver.cstore().may_have_doc_links_untracked(def_id) { return; } // FIXME: actually resolve links, not just add traits in scope. @@ -246,7 +258,7 @@ impl EarlyDocLinkResolver<'_, '_> { Res::Def(DefKind::Variant, ..) => self.resolver.parent(def_id).unwrap(), _ => def_id, }; - self.resolve_doc_links_extern_outer(def_id, scope_id, false); // Outer attribute scope + self.resolve_doc_links_extern_outer(def_id, scope_id); // Outer attribute scope if let Res::Def(DefKind::Mod, ..) = child.res { self.resolve_doc_links_extern_inner(def_id); // Inner attribute scope }