@@ -10,6 +10,7 @@ use rustc_hir::{Node, CRATE_HIR_ID};
1010use  rustc_middle:: hir:: nested_filter; 
1111use  rustc_middle:: ty:: TyCtxt ; 
1212use  rustc_span:: def_id:: { CRATE_DEF_ID ,  LOCAL_CRATE } ; 
13+ use  rustc_span:: hygiene:: MacroKind ; 
1314use  rustc_span:: symbol:: { kw,  sym,  Symbol } ; 
1415use  rustc_span:: Span ; 
1516
@@ -87,6 +88,7 @@ pub(crate) struct RustdocVisitor<'a, 'tcx> {
8788     inside_public_path :  bool , 
8889    exact_paths :  DefIdMap < Vec < Symbol > > , 
8990    modules :  Vec < Module < ' tcx > > , 
91+     is_importable_from_parent :  bool , 
9092} 
9193
9294impl < ' a ,  ' tcx >  RustdocVisitor < ' a ,  ' tcx >  { 
@@ -107,6 +109,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
107109            inside_public_path :  true , 
108110            exact_paths :  Default :: default ( ) , 
109111            modules :  vec ! [ om] , 
112+             is_importable_from_parent :  true , 
110113        } 
111114    } 
112115
@@ -319,19 +322,31 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
319322        renamed :  Option < Symbol > , 
320323        parent_id :  Option < LocalDefId > , 
321324    )  { 
322-         self . modules 
323-             . last_mut ( ) 
324-             . unwrap ( ) 
325-             . items 
326-             . insert ( ( item. owner_id . def_id ,  renamed) ,  ( item,  renamed,  parent_id) ) ; 
325+         if  self . is_importable_from_parent 
326+             // If we're inside an item, only impl blocks and `macro_rules!` with the `macro_export` 
327+             // attribute can still be visible. 
328+             || match  item. kind  { 
329+                 hir:: ItemKind :: Impl ( ..)  => true , 
330+                 hir:: ItemKind :: Macro ( _,  MacroKind :: Bang )  => { 
331+                     self . cx . tcx . has_attr ( item. owner_id . def_id ,  sym:: macro_export) 
332+                 } 
333+                 _ => false , 
334+             } 
335+         { 
336+             self . modules 
337+                 . last_mut ( ) 
338+                 . unwrap ( ) 
339+                 . items 
340+                 . insert ( ( item. owner_id . def_id ,  renamed) ,  ( item,  renamed,  parent_id) ) ; 
341+         } 
327342    } 
328343
329344    fn  visit_item_inner ( 
330345        & mut  self , 
331346        item :  & ' tcx  hir:: Item < ' _ > , 
332347        renamed :  Option < Symbol > , 
333348        import_id :  Option < LocalDefId > , 
334-     )  ->  bool   { 
349+     )  { 
335350        debug ! ( "visiting item {:?}" ,  item) ; 
336351        let  name = renamed. unwrap_or ( item. ident . name ) ; 
337352        let  tcx = self . cx . tcx ; 
@@ -448,7 +463,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
448463                } 
449464            } 
450465        } 
451-         true 
452466    } 
453467
454468    fn  visit_foreign_item_inner ( 
@@ -485,9 +499,23 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> {
485499    } 
486500
487501    fn  visit_item ( & mut  self ,  i :  & ' tcx  hir:: Item < ' tcx > )  { 
488-         if  self . visit_item_inner ( i,  None ,  None )  { 
489-             walk_item ( self ,  i) ; 
490-         } 
502+         self . visit_item_inner ( i,  None ,  None ) ; 
503+         let  new_value = if  self . is_importable_from_parent  { 
504+             matches ! ( 
505+                 i. kind, 
506+                 hir:: ItemKind :: Mod ( ..) 
507+                     | hir:: ItemKind :: ForeignMod  {  .. } 
508+                     | hir:: ItemKind :: Impl ( ..) 
509+                     | hir:: ItemKind :: Trait ( ..) 
510+             ) 
511+         }  else  { 
512+             // Whatever the context, if it's an impl block, the items inside it can be used so they 
513+             // should be visible. 
514+             matches ! ( i. kind,  hir:: ItemKind :: Impl ( ..) ) 
515+         } ; 
516+         let  prev = mem:: replace ( & mut  self . is_importable_from_parent ,  new_value) ; 
517+         walk_item ( self ,  i) ; 
518+         self . is_importable_from_parent  = prev; 
491519    } 
492520
493521    fn  visit_mod ( & mut  self ,  _:  & hir:: Mod < ' tcx > ,  _:  Span ,  _:  hir:: HirId )  { 
0 commit comments