@@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
55use rustc_hir as hir;
66use rustc_hir:: def:: { DefKind , Res } ;
77use rustc_hir:: def_id:: { DefId , DefIdMap , LocalDefId , LocalDefIdSet } ;
8- use rustc_hir:: intravisit:: { walk_item, Visitor } ;
8+ use rustc_hir:: intravisit:: { walk_body , walk_item, Visitor } ;
99use rustc_hir:: { Node , CRATE_HIR_ID } ;
1010use rustc_middle:: hir:: nested_filter;
1111use rustc_middle:: ty:: TyCtxt ;
@@ -106,6 +106,7 @@ pub(crate) struct RustdocVisitor<'a, 'tcx> {
106106 exact_paths : DefIdMap < Vec < Symbol > > ,
107107 modules : Vec < Module < ' tcx > > ,
108108 is_importable_from_parent : bool ,
109+ inside_body : bool ,
109110}
110111
111112impl < ' a , ' tcx > RustdocVisitor < ' a , ' tcx > {
@@ -129,6 +130,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
129130 exact_paths : Default :: default ( ) ,
130131 modules : vec ! [ om] ,
131132 is_importable_from_parent : true ,
133+ inside_body : false ,
132134 }
133135 }
134136
@@ -368,6 +370,26 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
368370 import_id : Option < LocalDefId > ,
369371 ) {
370372 debug ! ( "visiting item {:?}" , item) ;
373+ if self . inside_body {
374+ // Only impls can be "seen" outside a body. For example:
375+ //
376+ // ```
377+ // struct Bar;
378+ //
379+ // fn foo() {
380+ // impl Bar { fn bar() {} }
381+ // }
382+ // Bar::bar();
383+ // ```
384+ if let hir:: ItemKind :: Impl ( impl_) = item. kind &&
385+ // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick
386+ // them up regardless of where they're located.
387+ impl_. of_trait . is_none ( )
388+ {
389+ self . add_to_current_mod ( item, None , None ) ;
390+ }
391+ return ;
392+ }
371393 let name = renamed. unwrap_or ( item. ident . name ) ;
372394 let tcx = self . cx . tcx ;
373395
@@ -564,4 +586,10 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> {
564586 fn visit_lifetime ( & mut self , _: & hir:: Lifetime ) {
565587 // Unneeded.
566588 }
589+
590+ fn visit_body ( & mut self , b : & ' tcx hir:: Body < ' tcx > ) {
591+ let prev = mem:: replace ( & mut self . inside_body , true ) ;
592+ walk_body ( self , b) ;
593+ self . inside_body = prev;
594+ }
567595}
0 commit comments