@@ -24,13 +24,13 @@ use rustc_hir::{BindingAnnotation, PrimTy, TraitCandidate};
24
24
use rustc_middle:: middle:: resolve_lifetime:: Set1 ;
25
25
use rustc_middle:: ty:: DefIdTree ;
26
26
use rustc_middle:: { bug, span_bug} ;
27
- use rustc_session:: config:: CrateType ;
27
+ use rustc_session:: config:: { CrateType , ResolveDocLinks } ;
28
28
use rustc_session:: lint;
29
+ use rustc_span:: source_map:: { respan, Spanned } ;
29
30
use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
30
31
use rustc_span:: { BytePos , Span , SyntaxContext } ;
31
32
use smallvec:: { smallvec, SmallVec } ;
32
33
33
- use rustc_span:: source_map:: { respan, Spanned } ;
34
34
use std:: assert_matches:: debug_assert_matches;
35
35
use std:: borrow:: Cow ;
36
36
use std:: collections:: { hash_map:: Entry , BTreeSet } ;
@@ -494,6 +494,30 @@ impl<'a> PathSource<'a> {
494
494
}
495
495
}
496
496
497
+ /// At this point for most items we can answer whether that item is exported or not,
498
+ /// but some items like impls require type information to determine exported-ness, so we make a
499
+ /// conservative estimate for them (e.g. based on nominal visibility).
500
+ #[ derive( Clone , Copy ) ]
501
+ enum MaybeExported < ' a > {
502
+ Ok ( NodeId ) ,
503
+ Impl ( Option < DefId > ) ,
504
+ ImplItem ( Result < DefId , & ' a Visibility > ) ,
505
+ }
506
+
507
+ impl MaybeExported < ' _ > {
508
+ fn eval ( self , r : & Resolver < ' _ > ) -> bool {
509
+ let def_id = match self {
510
+ MaybeExported :: Ok ( node_id) => Some ( r. local_def_id ( node_id) ) ,
511
+ MaybeExported :: Impl ( Some ( trait_def_id) ) | MaybeExported :: ImplItem ( Ok ( trait_def_id) ) => {
512
+ trait_def_id. as_local ( )
513
+ }
514
+ MaybeExported :: Impl ( None ) => return true ,
515
+ MaybeExported :: ImplItem ( Err ( vis) ) => return vis. kind . is_pub ( ) ,
516
+ } ;
517
+ def_id. map_or ( true , |def_id| r. effective_visibilities . is_exported ( def_id) )
518
+ }
519
+ }
520
+
497
521
#[ derive( Default ) ]
498
522
struct DiagnosticMetadata < ' ast > {
499
523
/// The current trait's associated items' ident, used for diagnostic suggestions.
@@ -774,7 +798,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
774
798
) ;
775
799
}
776
800
fn visit_foreign_item ( & mut self , foreign_item : & ' ast ForeignItem ) {
777
- self . resolve_doc_links ( & foreign_item. attrs ) ;
801
+ self . resolve_doc_links ( & foreign_item. attrs , MaybeExported :: Ok ( foreign_item . id ) ) ;
778
802
match foreign_item. kind {
779
803
ForeignItemKind :: TyAlias ( box TyAlias { ref generics, .. } ) => {
780
804
self . with_generic_param_rib (
@@ -1165,12 +1189,12 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
1165
1189
}
1166
1190
1167
1191
fn visit_variant ( & mut self , v : & ' ast Variant ) {
1168
- self . resolve_doc_links ( & v. attrs ) ;
1192
+ self . resolve_doc_links ( & v. attrs , MaybeExported :: Ok ( v . id ) ) ;
1169
1193
visit:: walk_variant ( self , v)
1170
1194
}
1171
1195
1172
1196
fn visit_field_def ( & mut self , f : & ' ast FieldDef ) {
1173
- self . resolve_doc_links ( & f. attrs ) ;
1197
+ self . resolve_doc_links ( & f. attrs , MaybeExported :: Ok ( f . id ) ) ;
1174
1198
visit:: walk_field_def ( self , f)
1175
1199
}
1176
1200
}
@@ -2201,8 +2225,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
2201
2225
fn resolve_item ( & mut self , item : & ' ast Item ) {
2202
2226
let mod_inner_docs =
2203
2227
matches ! ( item. kind, ItemKind :: Mod ( ..) ) && rustdoc:: inner_docs ( & item. attrs ) ;
2204
- if !mod_inner_docs {
2205
- self . resolve_doc_links ( & item. attrs ) ;
2228
+ if !mod_inner_docs && ! matches ! ( item . kind , ItemKind :: Impl ( .. ) ) {
2229
+ self . resolve_doc_links ( & item. attrs , MaybeExported :: Ok ( item . id ) ) ;
2206
2230
}
2207
2231
2208
2232
let name = item. ident . name ;
@@ -2249,7 +2273,14 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
2249
2273
..
2250
2274
} ) => {
2251
2275
self . diagnostic_metadata . current_impl_items = Some ( impl_items) ;
2252
- self . resolve_implementation ( generics, of_trait, & self_ty, item. id , impl_items) ;
2276
+ self . resolve_implementation (
2277
+ & item. attrs ,
2278
+ generics,
2279
+ of_trait,
2280
+ & self_ty,
2281
+ item. id ,
2282
+ impl_items,
2283
+ ) ;
2253
2284
self . diagnostic_metadata . current_impl_items = None ;
2254
2285
}
2255
2286
@@ -2297,7 +2328,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
2297
2328
ItemKind :: Mod ( ..) => {
2298
2329
self . with_scope ( item. id , |this| {
2299
2330
if mod_inner_docs {
2300
- this. resolve_doc_links ( & item. attrs ) ;
2331
+ this. resolve_doc_links ( & item. attrs , MaybeExported :: Ok ( item . id ) ) ;
2301
2332
}
2302
2333
let old_macro_rules = this. parent_scope . macro_rules ;
2303
2334
visit:: walk_item ( this, item) ;
@@ -2583,7 +2614,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
2583
2614
} ;
2584
2615
2585
2616
for item in trait_items {
2586
- self . resolve_doc_links ( & item. attrs ) ;
2617
+ self . resolve_doc_links ( & item. attrs , MaybeExported :: Ok ( item . id ) ) ;
2587
2618
match & item. kind {
2588
2619
AssocItemKind :: Const ( _, ty, default) => {
2589
2620
self . visit_ty ( ty) ;
@@ -2671,6 +2702,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
2671
2702
2672
2703
fn resolve_implementation (
2673
2704
& mut self ,
2705
+ attrs : & [ ast:: Attribute ] ,
2674
2706
generics : & ' ast Generics ,
2675
2707
opt_trait_reference : & ' ast Option < TraitRef > ,
2676
2708
self_type : & ' ast Ty ,
@@ -2701,6 +2733,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
2701
2733
opt_trait_reference. as_ref ( ) ,
2702
2734
self_type,
2703
2735
|this, trait_id| {
2736
+ this. resolve_doc_links ( attrs, MaybeExported :: Impl ( trait_id) ) ;
2737
+
2704
2738
let item_def_id = this. r . local_def_id ( item_id) ;
2705
2739
2706
2740
// Register the trait definitions from here.
@@ -2734,7 +2768,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
2734
2768
debug ! ( "resolve_implementation with_self_rib_ns(ValueNS, ...)" ) ;
2735
2769
let mut seen_trait_items = Default :: default ( ) ;
2736
2770
for item in impl_items {
2737
- this. resolve_impl_item ( & * * item, & mut seen_trait_items) ;
2771
+ this. resolve_impl_item ( & * * item, & mut seen_trait_items, trait_id ) ;
2738
2772
}
2739
2773
} ) ;
2740
2774
} ) ;
@@ -2752,9 +2786,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
2752
2786
& mut self ,
2753
2787
item : & ' ast AssocItem ,
2754
2788
seen_trait_items : & mut FxHashMap < DefId , Span > ,
2789
+ trait_id : Option < DefId > ,
2755
2790
) {
2756
2791
use crate :: ResolutionError :: * ;
2757
- self . resolve_doc_links ( & item. attrs ) ;
2792
+ self . resolve_doc_links ( & item. attrs , MaybeExported :: ImplItem ( trait_id . ok_or ( & item . vis ) ) ) ;
2758
2793
match & item. kind {
2759
2794
AssocItemKind :: Const ( _, ty, default) => {
2760
2795
debug ! ( "resolve_implementation AssocItemKind::Const" ) ;
@@ -4183,7 +4218,23 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
4183
4218
res
4184
4219
}
4185
4220
4186
- fn resolve_doc_links ( & mut self , attrs : & [ Attribute ] ) {
4221
+ fn resolve_doc_links ( & mut self , attrs : & [ Attribute ] , maybe_exported : MaybeExported < ' _ > ) {
4222
+ match self . r . session . opts . resolve_doc_links {
4223
+ ResolveDocLinks :: None => return ,
4224
+ ResolveDocLinks :: ExportedMetadata
4225
+ if !self . r . session . crate_types ( ) . iter ( ) . copied ( ) . any ( CrateType :: has_metadata)
4226
+ || !maybe_exported. eval ( self . r ) =>
4227
+ {
4228
+ return ;
4229
+ }
4230
+ ResolveDocLinks :: Exported if !maybe_exported. eval ( self . r ) => {
4231
+ return ;
4232
+ }
4233
+ ResolveDocLinks :: ExportedMetadata
4234
+ | ResolveDocLinks :: Exported
4235
+ | ResolveDocLinks :: All => { }
4236
+ }
4237
+
4187
4238
if !attrs. iter ( ) . any ( |attr| attr. may_have_doc_links ( ) ) {
4188
4239
return ;
4189
4240
}
@@ -4283,7 +4334,7 @@ impl<'a> Resolver<'a> {
4283
4334
pub ( crate ) fn late_resolve_crate ( & mut self , krate : & Crate ) {
4284
4335
visit:: walk_crate ( & mut LifetimeCountVisitor { r : self } , krate) ;
4285
4336
let mut late_resolution_visitor = LateResolutionVisitor :: new ( self ) ;
4286
- late_resolution_visitor. resolve_doc_links ( & krate. attrs ) ;
4337
+ late_resolution_visitor. resolve_doc_links ( & krate. attrs , MaybeExported :: Ok ( CRATE_NODE_ID ) ) ;
4287
4338
visit:: walk_crate ( & mut late_resolution_visitor, krate) ;
4288
4339
for ( id, span) in late_resolution_visitor. diagnostic_metadata . unused_labels . iter ( ) {
4289
4340
self . lint_buffer . buffer_lint ( lint:: builtin:: UNUSED_LABELS , * id, * span, "unused label" ) ;
0 commit comments