Change:
I have three crates: (library), (library), and (binary). has no dependencies, and its is just: has the following dependency and : has the following dependency and : The following error happens running or in crate : Try as I may, I can't manage to make the error happen without putting in every one of those lines and dependencies. EDIT: the bug only requires , not
pre-triage: P-high, removing nomination tag. assigning to self for initial investigation.
(seems to me like the line is not necessary to reproduce the bug?) ((but the nonetheless does remain necessary for reproduction....))
Here is a shell script to compile the files using itself (so we get out of the way) and run the compile of under :
and the backtrace from gives us a pretty good hint as to where we might be infinite-looping: (and so on, for at least 15,000 stack frames...)
(prior to rust 1.35.0, it seems like we might have infinite looped here with no stack overflow. Not 100% sure of that yet; and this test case currently relies on 2018 edition, so its not easy to go back to earlier than 1.31.0)
Also, you can inline the contents of crate a into crate b and preserve the erroneous behavior:
Okay I think I have a solution for this. Hope to post PR today or tomorrow.

Discussion:
/// 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( <ins> 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( </ins> mut self, def_id: DefId, <ins> callers: &mut Vec<DefId>, </ins> ) -> Result<(Self, bool), Self::Error> { define_scoped_cx!(self);

Some(parent) => parent, None => return Ok((self, false)), }; <ins> if callers.contains(&visible_parent) { return Ok((self, false)); } callers.push(visible_parent); </ins> // 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. <del> match self.try_print_visible_def_path(visible_parent)? { </del> <ins> match self.try_print_visible_def_path_recur(visible_parent, callers)? { </ins> (cx, false) => return Ok((cx, false)), (cx, true) => self = cx, } <ins> callers.pop(); </ins> let actual_parent = self.tcx().parent(def_id); debug!( "try_print_visible_def_path: visible_parent={:?} actual_parent={:?}",

<ins> // edition:2018 #![crate_type="lib"] #![crate_name="xcrate_issue_61711_b"] pub struct Struct; pub use crate as alias; </ins>

<ins> // 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() { } </ins>