@@ -2,6 +2,7 @@ use crate::clean::Attributes;
2
2
use crate::core::ResolverCaches;
3
3
use crate::passes::collect_intra_doc_links::preprocessed_markdown_links;
4
4
use crate::passes::collect_intra_doc_links::{Disambiguator, PreprocessedMarkdownLink};
5
+ use crate::visit_lib::early_lib_embargo_visit_item;
5
6
6
7
use rustc_ast::visit::{self, AssocCtxt, Visitor};
7
8
use rustc_ast::{self as ast, ItemKind};
@@ -34,6 +35,8 @@ pub(crate) fn early_resolve_intra_doc_links(
34
35
traits_in_scope: Default::default(),
35
36
all_trait_impls: Default::default(),
36
37
all_macro_rules: Default::default(),
38
+ extern_doc_reachable: Default::default(),
39
+ local_doc_reachable: Default::default(),
37
40
document_private_items,
38
41
};
39
42
@@ -61,6 +64,7 @@ pub(crate) fn early_resolve_intra_doc_links(
61
64
traits_in_scope: link_resolver.traits_in_scope,
62
65
all_trait_impls: Some(link_resolver.all_trait_impls),
63
66
all_macro_rules: link_resolver.all_macro_rules,
67
+ extern_doc_reachable: link_resolver.extern_doc_reachable,
64
68
}
65
69
}
66
70
@@ -77,6 +81,15 @@ struct EarlyDocLinkResolver<'r, 'ra> {
77
81
traits_in_scope: DefIdMap<Vec<TraitCandidate>>,
78
82
all_trait_impls: Vec<DefId>,
79
83
all_macro_rules: FxHashMap<Symbol, Res<ast::NodeId>>,
84
+ /// This set is used as a seed for `effective_visibilities`, which are then extended by some
85
+ /// more items using `lib_embargo_visit_item` during doc inlining.
86
+ extern_doc_reachable: DefIdSet,
87
+ /// This is an easily identifiable superset of items added to `effective_visibilities`
88
+ /// using `lib_embargo_visit_item` during doc inlining.
89
+ /// The union of `(extern,local)_doc_reachable` is therefore a superset of
90
+ /// `effective_visibilities` and can be used for pruning extern impls here
91
+ /// in early doc link resolution.
92
+ local_doc_reachable: DefIdSet,
80
93
document_private_items: bool,
81
94
}
82
95
@@ -105,6 +118,10 @@ impl<'ra> EarlyDocLinkResolver<'_, 'ra> {
105
118
}
106
119
}
107
120
121
+ fn is_doc_reachable(&self, def_id: DefId) -> bool {
122
+ self.extern_doc_reachable.contains(&def_id) || self.local_doc_reachable.contains(&def_id)
123
+ }
124
+
108
125
/// Add traits in scope for links in impls collected by the `collect-intra-doc-links` pass.
109
126
/// That pass filters impls using type-based information, but we don't yet have such
110
127
/// information here, so we just conservatively calculate traits in scope for *all* modules
@@ -114,6 +131,14 @@ impl<'ra> EarlyDocLinkResolver<'_, 'ra> {
114
131
let mut start_cnum = 0;
115
132
loop {
116
133
let crates = Vec::from_iter(self.resolver.cstore().crates_untracked());
134
+ for cnum in &crates[start_cnum..] {
135
+ early_lib_embargo_visit_item(
136
+ self.resolver,
137
+ &mut self.extern_doc_reachable,
138
+ cnum.as_def_id(),
139
+ true,
140
+ );
141
+ }
117
142
for &cnum in &crates[start_cnum..] {
118
143
let all_trait_impls =
119
144
Vec::from_iter(self.resolver.cstore().trait_impls_in_crate_untracked(cnum));
@@ -127,28 +152,26 @@ impl<'ra> EarlyDocLinkResolver<'_, 'ra> {
127
152
// privacy, private traits and impls from other crates are never documented in
128
153
// the current crate, and links in their doc comments are not resolved.
129
154
for &(trait_def_id, impl_def_id, simplified_self_ty) in &all_trait_impls {
130
- if self.resolver.cstore().visibility_untracked( trait_def_id).is_public( )
131
- && simplified_self_ty.and_then(|ty| ty.def()).map_or(true, |ty_def_id| {
132
- self.resolver.cstore().visibility_untracked(ty_def_id).is_public( )
133
- } )
155
+ if self.is_doc_reachable( trait_def_id)
156
+ && simplified_self_ty
157
+ .and_then(|ty| ty.def() )
158
+ .map_or(true, |ty_def_id| self.is_doc_reachable(ty_def_id) )
134
159
{
135
160
if self.visited_mods.insert(trait_def_id) {
136
161
self.resolve_doc_links_extern_impl(trait_def_id, false);
137
162
}
138
163
self.resolve_doc_links_extern_impl(impl_def_id, false);
139
164
}
165
+ self.all_trait_impls.push(impl_def_id);
140
166
}
141
167
for (ty_def_id, impl_def_id) in all_inherent_impls {
142
- if self.resolver.cstore().visibility_untracked( ty_def_id).is_public( ) {
168
+ if self.is_doc_reachable( ty_def_id) {
143
169
self.resolve_doc_links_extern_impl(impl_def_id, true);
144
170
}
145
171
}
146
172
for impl_def_id in all_incoherent_impls {
147
173
self.resolve_doc_links_extern_impl(impl_def_id, true);
148
174
}
149
-
150
- self.all_trait_impls
151
- .extend(all_trait_impls.into_iter().map(|(_, def_id, _)| def_id));
152
175
}
153
176
154
177
if crates.len() > start_cnum {
@@ -298,6 +321,7 @@ impl<'ra> EarlyDocLinkResolver<'_, 'ra> {
298
321
&& module_id.is_local()
299
322
{
300
323
if let Some(def_id) = child.res.opt_def_id() && !def_id.is_local() {
324
+ self.local_doc_reachable.insert(def_id);
301
325
let scope_id = match child.res {
302
326
Res::Def(
303
327
DefKind::Variant
0 commit comments