@@ -228,8 +228,27 @@ pub trait PrettyPrinter<'tcx>:
228
228
/// from at least one local module and returns true. If the crate defining `def_id` is
229
229
/// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
230
230
fn try_print_visible_def_path (
231
+ self ,
232
+ def_id : DefId ,
233
+ ) -> Result < ( Self , bool ) , Self :: Error > {
234
+ let mut callers = Vec :: new ( ) ;
235
+ self . try_print_visible_def_path_recur ( def_id, & mut callers)
236
+ }
237
+
238
+ /// Does the work of `try_print_visible_def_path`, building the
239
+ /// full definition path recursively before attempting to
240
+ /// post-process it into the valid and visible version that
241
+ /// accounts for re-exports.
242
+ ///
243
+ /// This method should only be callled by itself or
244
+ /// `try_print_visible_def_path`.
245
+ ///
246
+ /// `callers` is a chain of visible_parent's leading to `def_id`,
247
+ /// to support cycle detection during recursion.
248
+ fn try_print_visible_def_path_recur (
231
249
mut self ,
232
250
def_id : DefId ,
251
+ callers : & mut Vec < DefId > ,
233
252
) -> Result < ( Self , bool ) , Self :: Error > {
234
253
define_scoped_cx ! ( self ) ;
235
254
@@ -302,14 +321,19 @@ pub trait PrettyPrinter<'tcx>:
302
321
Some ( parent) => parent,
303
322
None => return Ok ( ( self , false ) ) ,
304
323
} ;
324
+ if callers. contains ( & visible_parent) {
325
+ return Ok ( ( self , false ) ) ;
326
+ }
327
+ callers. push ( visible_parent) ;
305
328
// HACK(eddyb) this bypasses `path_append`'s prefix printing to avoid
306
329
// knowing ahead of time whether the entire path will succeed or not.
307
330
// To support printers that do not implement `PrettyPrinter`, a `Vec` or
308
331
// linked list on the stack would need to be built, before any printing.
309
- match self . try_print_visible_def_path ( visible_parent) ? {
332
+ match self . try_print_visible_def_path_recur ( visible_parent, callers ) ? {
310
333
( cx, false ) => return Ok ( ( cx, false ) ) ,
311
334
( cx, true ) => self = cx,
312
335
}
336
+ callers. pop ( ) ;
313
337
let actual_parent = self . tcx ( ) . parent ( def_id) ;
314
338
debug ! (
315
339
"try_print_visible_def_path: visible_parent={:?} actual_parent={:?}" ,
0 commit comments