@@ -258,6 +258,8 @@ pub struct Cache {
258
258
parent_stack : Vec < DefId > ,
259
259
parent_is_trait_impl : bool ,
260
260
search_index : Vec < IndexItem > ,
261
+ seen_modules : HashSet < DefId > ,
262
+ seen_mod : bool ,
261
263
stripped_mod : bool ,
262
264
deref_trait_did : Option < DefId > ,
263
265
@@ -520,6 +522,8 @@ pub fn run(mut krate: clean::Crate,
520
522
parent_is_trait_impl : false ,
521
523
extern_locations : HashMap :: new ( ) ,
522
524
primitive_locations : HashMap :: new ( ) ,
525
+ seen_modules : HashSet :: new ( ) ,
526
+ seen_mod : false ,
523
527
stripped_mod : false ,
524
528
access_levels : krate. access_levels . clone ( ) ,
525
529
orphan_methods : Vec :: new ( ) ,
@@ -976,13 +980,20 @@ impl DocFolder for Cache {
976
980
// we don't want it or its children in the search index.
977
981
let orig_stripped_mod = match item. inner {
978
982
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 )
982
984
}
983
985
_ => self . stripped_mod ,
984
986
} ;
985
987
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
+
986
997
// Register any generics to their corresponding string. This is used
987
998
// when pretty-printing types
988
999
match item. inner {
@@ -998,20 +1009,22 @@ impl DocFolder for Cache {
998
1009
_ => { }
999
1010
}
1000
1011
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
+ }
1006
1018
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
+ }
1015
1028
}
1016
1029
}
1017
1030
@@ -1183,7 +1196,6 @@ impl DocFolder for Cache {
1183
1196
} => {
1184
1197
Some ( did)
1185
1198
}
1186
-
1187
1199
ref t => {
1188
1200
t. primitive_type ( ) . and_then ( |t| {
1189
1201
self . primitive_locations . get ( & t) . map ( |n| {
@@ -1193,13 +1205,14 @@ impl DocFolder for Cache {
1193
1205
} )
1194
1206
}
1195
1207
} ;
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
+ }
1203
1216
}
1204
1217
None
1205
1218
} else {
@@ -1209,6 +1222,7 @@ impl DocFolder for Cache {
1209
1222
1210
1223
if pushed { self . stack . pop ( ) . unwrap ( ) ; }
1211
1224
if parent_pushed { self . parent_stack . pop ( ) . unwrap ( ) ; }
1225
+ self . seen_mod = orig_seen_mod;
1212
1226
self . stripped_mod = orig_stripped_mod;
1213
1227
self . parent_is_trait_impl = orig_parent_is_trait_impl;
1214
1228
return ret;
0 commit comments