@@ -258,6 +258,8 @@ pub struct Cache {
258258 parent_stack : Vec < DefId > ,
259259 parent_is_trait_impl : bool ,
260260 search_index : Vec < IndexItem > ,
261+ seen_modules : HashSet < DefId > ,
262+ seen_mod : bool ,
261263 stripped_mod : bool ,
262264 deref_trait_did : Option < DefId > ,
263265
@@ -520,6 +522,8 @@ pub fn run(mut krate: clean::Crate,
520522 parent_is_trait_impl : false ,
521523 extern_locations : HashMap :: new ( ) ,
522524 primitive_locations : HashMap :: new ( ) ,
525+ seen_modules : HashSet :: new ( ) ,
526+ seen_mod : false ,
523527 stripped_mod : false ,
524528 access_levels : krate. access_levels . clone ( ) ,
525529 orphan_methods : Vec :: new ( ) ,
@@ -976,13 +980,20 @@ impl DocFolder for Cache {
976980 // we don't want it or its children in the search index.
977981 let orig_stripped_mod = match item. inner {
978982 clean:: StrippedItem ( box clean:: ModuleItem ( ..) ) => {
979- let prev = self . stripped_mod ;
980- self . stripped_mod = true ;
981- prev
983+ mem:: replace ( & mut self . stripped_mod , true )
982984 }
983985 _ => self . stripped_mod ,
984986 } ;
985987
988+ // Inlining can cause us to visit the same item multiple times.
989+ // (i.e. relevant for gathering impls and implementors)
990+ let orig_seen_mod = if item. is_mod ( ) {
991+ let seen_this = self . seen_mod || !self . seen_modules . insert ( item. def_id ) ;
992+ mem:: replace ( & mut self . seen_mod , seen_this)
993+ } else {
994+ self . seen_mod
995+ } ;
996+
986997 // Register any generics to their corresponding string. This is used
987998 // when pretty-printing types
988999 match item. inner {
@@ -998,20 +1009,22 @@ impl DocFolder for Cache {
9981009 _ => { }
9991010 }
10001011
1001- // Propagate a trait methods' documentation to all implementors of the
1002- // trait
1003- if let clean:: TraitItem ( ref t) = item. inner {
1004- self . traits . insert ( item. def_id , t. clone ( ) ) ;
1005- }
1012+ if !self . seen_mod {
1013+ // Propagate a trait methods' documentation to all implementors of the
1014+ // trait
1015+ if let clean:: TraitItem ( ref t) = item. inner {
1016+ self . traits . insert ( item. def_id , t. clone ( ) ) ;
1017+ }
10061018
1007- // Collect all the implementors of traits.
1008- if let clean:: ImplItem ( ref i) = item. inner {
1009- if let Some ( did) = i. trait_ . def_id ( ) {
1010- self . implementors . entry ( did) . or_insert ( vec ! [ ] ) . push ( Implementor {
1011- def_id : item. def_id ,
1012- stability : item. stability . clone ( ) ,
1013- impl_ : i. clone ( ) ,
1014- } ) ;
1019+ // Collect all the implementors of traits.
1020+ if let clean:: ImplItem ( ref i) = item. inner {
1021+ if let Some ( did) = i. trait_ . def_id ( ) {
1022+ self . implementors . entry ( did) . or_insert ( vec ! [ ] ) . push ( Implementor {
1023+ def_id : item. def_id ,
1024+ stability : item. stability . clone ( ) ,
1025+ impl_ : i. clone ( ) ,
1026+ } ) ;
1027+ }
10151028 }
10161029 }
10171030
@@ -1183,7 +1196,6 @@ impl DocFolder for Cache {
11831196 } => {
11841197 Some ( did)
11851198 }
1186-
11871199 ref t => {
11881200 t. primitive_type ( ) . and_then ( |t| {
11891201 self . primitive_locations . get ( & t) . map ( |n| {
@@ -1193,13 +1205,14 @@ impl DocFolder for Cache {
11931205 } )
11941206 }
11951207 } ;
1196-
1197- if let Some ( did) = did {
1198- self . impls . entry ( did) . or_insert ( vec ! [ ] ) . push ( Impl {
1199- impl_ : i,
1200- dox : attrs. value ( "doc" ) . map ( |s|s. to_owned ( ) ) ,
1201- stability : item. stability . clone ( ) ,
1202- } ) ;
1208+ if !self . seen_mod {
1209+ if let Some ( did) = did {
1210+ self . impls . entry ( did) . or_insert ( vec ! [ ] ) . push ( Impl {
1211+ impl_ : i,
1212+ dox : attrs. value ( "doc" ) . map ( |s|s. to_owned ( ) ) ,
1213+ stability : item. stability . clone ( ) ,
1214+ } ) ;
1215+ }
12031216 }
12041217 None
12051218 } else {
@@ -1209,6 +1222,7 @@ impl DocFolder for Cache {
12091222
12101223 if pushed { self . stack . pop ( ) . unwrap ( ) ; }
12111224 if parent_pushed { self . parent_stack . pop ( ) . unwrap ( ) ; }
1225+ self . seen_mod = orig_seen_mod;
12121226 self . stripped_mod = orig_stripped_mod;
12131227 self . parent_is_trait_impl = orig_parent_is_trait_impl;
12141228 return ret;
0 commit comments