@@ -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