Skip to content

Commit 4bb6b4a

Browse files
committed
Auto merge of #62503 - pnkfelix:dont-recur-infiitely-from-print-def-path, r=eddyb
Dont recur infinitely from print_def_path Fix #61711
2 parents 97b1128 + 4c58b29 commit 4bb6b4a

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

src/librustc/ty/print/pretty.rs

+25-1
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,27 @@ pub trait PrettyPrinter<'tcx>:
228228
/// from at least one local module and returns true. If the crate defining `def_id` is
229229
/// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
230230
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(
231249
mut self,
232250
def_id: DefId,
251+
callers: &mut Vec<DefId>,
233252
) -> Result<(Self, bool), Self::Error> {
234253
define_scoped_cx!(self);
235254

@@ -302,14 +321,19 @@ pub trait PrettyPrinter<'tcx>:
302321
Some(parent) => parent,
303322
None => return Ok((self, false)),
304323
};
324+
if callers.contains(&visible_parent) {
325+
return Ok((self, false));
326+
}
327+
callers.push(visible_parent);
305328
// HACK(eddyb) this bypasses `path_append`'s prefix printing to avoid
306329
// knowing ahead of time whether the entire path will succeed or not.
307330
// To support printers that do not implement `PrettyPrinter`, a `Vec` or
308331
// 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)? {
310333
(cx, false) => return Ok((cx, false)),
311334
(cx, true) => self = cx,
312335
}
336+
callers.pop();
313337
let actual_parent = self.tcx().parent(def_id);
314338
debug!(
315339
"try_print_visible_def_path: visible_parent={:?} actual_parent={:?}",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// edition:2018
2+
#![crate_type="lib"]
3+
#![crate_name="xcrate_issue_61711_b"]
4+
pub struct Struct;
5+
pub use crate as alias;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Issue 61711: A crate pub re-exporting `crate` was causing an
2+
// infinite loop.
3+
4+
// edition:2018
5+
// aux-build:xcrate-issue-61711-b.rs
6+
// compile-flags:--extern xcrate_issue_61711_b
7+
8+
// run-pass
9+
10+
fn f<F: Fn(xcrate_issue_61711_b::Struct)>(_: F) { }
11+
fn main() { }

0 commit comments

Comments
 (0)