Skip to content

Commit

Permalink
Auto merge of #62503 - pnkfelix:dont-recur-infiitely-from-print-def-p…
Browse files Browse the repository at this point in the history
…ath, r=eddyb

Dont recur infinitely from print_def_path

Fix #61711
  • Loading branch information
bors committed Jul 11, 2019
2 parents 97b1128 + 4c58b29 commit 4bb6b4a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 1 deletion.
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() { }

0 comments on commit 4bb6b4a

Please sign in to comment.