@@ -74,6 +74,10 @@ fn diff_structure<'a, 'tcx>(changes: &mut ChangeSet,
74
74
let mut visited = HashSet :: new ( ) ;
75
75
let mut children = NameMapping :: default ( ) ;
76
76
let mut mod_queue = VecDeque :: new ( ) ;
77
+ // Removals are processed with a delay to avoid creating multiple path change entries.
78
+ // This is necessary, since the order in which added or removed paths are found wrt each
79
+ // other and their item's definition can't be relied upon.
80
+ let mut removals = Vec :: new ( ) ;
77
81
78
82
mod_queue. push_back ( ( old, new, Public , Public ) ) ;
79
83
@@ -222,10 +226,11 @@ fn diff_structure<'a, 'tcx>(changes: &mut ChangeSet,
222
226
continue ;
223
227
}
224
228
225
- if old_vis == Public && cstore. visibility ( o. def . def_id ( ) ) == Public {
226
- let o_did = o. def . def_id ( ) ;
227
- changes. new_path ( o_did, o. ident . name , tcx. def_span ( o_did) ) ;
228
- changes. add_path_removal ( o_did, o. span ) ;
229
+ let o_did = o. def . def_id ( ) ;
230
+
231
+ if old_vis == Public && cstore. visibility ( o_did) == Public {
232
+ // delay the handling of removals until the id mapping is complete
233
+ removals. push ( o) ;
229
234
}
230
235
}
231
236
( None , Some ( n) ) => {
@@ -234,8 +239,9 @@ fn diff_structure<'a, 'tcx>(changes: &mut ChangeSet,
234
239
continue ;
235
240
}
236
241
237
- if new_vis == Public && cstore. visibility ( n. def . def_id ( ) ) == Public {
238
- let n_did = n. def . def_id ( ) ;
242
+ let n_did = n. def . def_id ( ) ;
243
+
244
+ if new_vis == Public && cstore. visibility ( n_did) == Public {
239
245
changes. new_path ( n_did, n. ident . name , tcx. def_span ( n_did) ) ;
240
246
changes. add_path_addition ( n_did, n. span ) ;
241
247
}
@@ -244,6 +250,21 @@ fn diff_structure<'a, 'tcx>(changes: &mut ChangeSet,
244
250
}
245
251
}
246
252
}
253
+
254
+ // finally, process item removals
255
+ for o in removals. drain ( ..) {
256
+ let o_did = o. def . def_id ( ) ;
257
+
258
+ // reuse an already existing path change entry, if possible
259
+ if id_mapping. contains_id ( o_did) {
260
+ let n_did = id_mapping. get_new_id ( o_did) ;
261
+ changes. new_path ( n_did, o. ident . name , tcx. def_span ( n_did) ) ;
262
+ changes. add_path_removal ( n_did, o. span ) ;
263
+ } else {
264
+ changes. new_path ( o_did, o. ident . name , tcx. def_span ( o_did) ) ;
265
+ changes. add_path_removal ( o_did, o. span ) ;
266
+ }
267
+ }
247
268
}
248
269
249
270
/// Given two fn items, perform structural checks.
0 commit comments