Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dont recur infinitely from print_def_path #62503

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion src/librustc/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,27 @@ pub trait PrettyPrinter<'tcx>:
/// from at least one local module and returns true. If the crate defining `def_id` is
/// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
fn try_print_visible_def_path(
self,
def_id: DefId,
) -> Result<(Self, bool), Self::Error> {
let mut callers = Vec::new();
self.try_print_visible_def_path_recur(def_id, &mut callers)
}

/// Does the work of `try_print_visible_def_path`, building the
/// full definition path recursively before attempting to
/// post-process it into the valid and visible version that
/// accounts for re-exports.
///
/// This method should only be callled by itself or
/// `try_print_visible_def_path`.
///
/// `callers` is a chain of visible_parent's leading to `def_id`,
/// to support cycle detection during recursion.
fn try_print_visible_def_path_recur(
mut self,
def_id: DefId,
callers: &mut Vec<DefId>,
) -> Result<(Self, bool), Self::Error> {
define_scoped_cx!(self);

Expand Down Expand Up @@ -302,14 +321,19 @@ pub trait PrettyPrinter<'tcx>:
Some(parent) => parent,
None => return Ok((self, false)),
};
if callers.contains(&visible_parent) {
return Ok((self, false));
}
callers.push(visible_parent);
// HACK(eddyb) this bypasses `path_append`'s prefix printing to avoid
// knowing ahead of time whether the entire path will succeed or not.
// To support printers that do not implement `PrettyPrinter`, a `Vec` or
// linked list on the stack would need to be built, before any printing.
match self.try_print_visible_def_path(visible_parent)? {
match self.try_print_visible_def_path_recur(visible_parent, callers)? {
(cx, false) => return Ok((cx, false)),
(cx, true) => self = cx,
}
callers.pop();
let actual_parent = self.tcx().parent(def_id);
debug!(
"try_print_visible_def_path: visible_parent={:?} actual_parent={:?}",
Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/issues/auxiliary/xcrate-issue-61711-b.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// edition:2018
#![crate_type="lib"]
#![crate_name="xcrate_issue_61711_b"]
pub struct Struct;
pub use crate as alias;
11 changes: 11 additions & 0 deletions src/test/ui/issues/issue-61711-once-caused-rustc-inf-loop.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Issue 61711: A crate pub re-exporting `crate` was causing an
// infinite loop.

// edition:2018
// aux-build:xcrate-issue-61711-b.rs
// compile-flags:--extern xcrate_issue_61711_b

// run-pass

fn f<F: Fn(xcrate_issue_61711_b::Struct)>(_: F) { }
fn main() { }