@@ -24,13 +24,13 @@ use rustc_hir::{BindingAnnotation, PrimTy, TraitCandidate};
2424use rustc_middle:: middle:: resolve_lifetime:: Set1 ;
2525use rustc_middle:: ty:: DefIdTree ;
2626use rustc_middle:: { bug, span_bug} ;
27- use rustc_session:: config:: CrateType ;
27+ use rustc_session:: config:: { CrateType , ResolveDocLinks } ;
2828use rustc_session:: lint;
29+ use rustc_span:: source_map:: { respan, Spanned } ;
2930use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
3031use rustc_span:: { BytePos , Span , SyntaxContext } ;
3132use smallvec:: { smallvec, SmallVec } ;
3233
33- use rustc_span:: source_map:: { respan, Spanned } ;
3434use std:: assert_matches:: debug_assert_matches;
3535use std:: borrow:: Cow ;
3636use std:: collections:: { hash_map:: Entry , BTreeSet } ;
@@ -494,6 +494,30 @@ impl<'a> PathSource<'a> {
494494 }
495495}
496496
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+
497521#[ derive( Default ) ]
498522struct DiagnosticMetadata < ' ast > {
499523 /// 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> {
774798 ) ;
775799 }
776800 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 ) ) ;
778802 match foreign_item. kind {
779803 ForeignItemKind :: TyAlias ( box TyAlias { ref generics, .. } ) => {
780804 self . with_generic_param_rib (
@@ -1165,12 +1189,12 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
11651189 }
11661190
11671191 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 ) ) ;
11691193 visit:: walk_variant ( self , v)
11701194 }
11711195
11721196 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 ) ) ;
11741198 visit:: walk_field_def ( self , f)
11751199 }
11761200}
@@ -2201,8 +2225,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
22012225 fn resolve_item ( & mut self , item : & ' ast Item ) {
22022226 let mod_inner_docs =
22032227 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 ) ) ;
22062230 }
22072231
22082232 let name = item. ident . name ;
@@ -2249,7 +2273,14 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
22492273 ..
22502274 } ) => {
22512275 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+ ) ;
22532284 self . diagnostic_metadata . current_impl_items = None ;
22542285 }
22552286
@@ -2297,7 +2328,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
22972328 ItemKind :: Mod ( ..) => {
22982329 self . with_scope ( item. id , |this| {
22992330 if mod_inner_docs {
2300- this. resolve_doc_links ( & item. attrs ) ;
2331+ this. resolve_doc_links ( & item. attrs , MaybeExported :: Ok ( item . id ) ) ;
23012332 }
23022333 let old_macro_rules = this. parent_scope . macro_rules ;
23032334 visit:: walk_item ( this, item) ;
@@ -2583,7 +2614,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
25832614 } ;
25842615
25852616 for item in trait_items {
2586- self . resolve_doc_links ( & item. attrs ) ;
2617+ self . resolve_doc_links ( & item. attrs , MaybeExported :: Ok ( item . id ) ) ;
25872618 match & item. kind {
25882619 AssocItemKind :: Const ( _, ty, default) => {
25892620 self . visit_ty ( ty) ;
@@ -2671,6 +2702,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
26712702
26722703 fn resolve_implementation (
26732704 & mut self ,
2705+ attrs : & [ ast:: Attribute ] ,
26742706 generics : & ' ast Generics ,
26752707 opt_trait_reference : & ' ast Option < TraitRef > ,
26762708 self_type : & ' ast Ty ,
@@ -2701,6 +2733,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
27012733 opt_trait_reference. as_ref ( ) ,
27022734 self_type,
27032735 |this, trait_id| {
2736+ this. resolve_doc_links ( attrs, MaybeExported :: Impl ( trait_id) ) ;
2737+
27042738 let item_def_id = this. r . local_def_id ( item_id) ;
27052739
27062740 // Register the trait definitions from here.
@@ -2734,7 +2768,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
27342768 debug ! ( "resolve_implementation with_self_rib_ns(ValueNS, ...)" ) ;
27352769 let mut seen_trait_items = Default :: default ( ) ;
27362770 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 ) ;
27382772 }
27392773 } ) ;
27402774 } ) ;
@@ -2752,9 +2786,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
27522786 & mut self ,
27532787 item : & ' ast AssocItem ,
27542788 seen_trait_items : & mut FxHashMap < DefId , Span > ,
2789+ trait_id : Option < DefId > ,
27552790 ) {
27562791 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 ) ) ) ;
27582793 match & item. kind {
27592794 AssocItemKind :: Const ( _, ty, default) => {
27602795 debug ! ( "resolve_implementation AssocItemKind::Const" ) ;
@@ -4183,7 +4218,23 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
41834218 res
41844219 }
41854220
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+
41874238 if !attrs. iter ( ) . any ( |attr| attr. may_have_doc_links ( ) ) {
41884239 return ;
41894240 }
@@ -4283,7 +4334,7 @@ impl<'a> Resolver<'a> {
42834334 pub ( crate ) fn late_resolve_crate ( & mut self , krate : & Crate ) {
42844335 visit:: walk_crate ( & mut LifetimeCountVisitor { r : self } , krate) ;
42854336 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 ) ) ;
42874338 visit:: walk_crate ( & mut late_resolution_visitor, krate) ;
42884339 for ( id, span) in late_resolution_visitor. diagnostic_metadata . unused_labels . iter ( ) {
42894340 self . lint_buffer . buffer_lint ( lint:: builtin:: UNUSED_LABELS , * id, * span, "unused label" ) ;
0 commit comments