Rollup merge of #89738 - eddyb:extern-crate-recursion, r=nagisa
ty::pretty: prevent infinite recursion for `extern crate` paths. Fixes #55779, fixes #87932. This fix is based on `@estebank's` idea in https://github.com/rust-lang/rust/issues/55779#issuecomment-614758510 - but instead of trying to get `try_print_visible_def_path_recur`'s cycle detection to work in this case, this PR "just" disables the "visible path" feature when printing the path to an `extern crate`, so that the old recursion chain of `try_print_visible_def_path -> print_def_path -> try_print_visible_def_path`, is now impossible. Both tests have been confirmed to crash `rustc` because of a stack overflow, without the fix.
This commit is contained in:
commit
59dc2187ad
6 changed files with 84 additions and 10 deletions
|
@ -350,18 +350,26 @@ pub trait PrettyPrinter<'tcx>:
|
|||
match self.tcx().extern_crate(def_id) {
|
||||
Some(&ExternCrate { src, dependency_of, span, .. }) => match (src, dependency_of) {
|
||||
(ExternCrateSource::Extern(def_id), LOCAL_CRATE) => {
|
||||
debug!("try_print_visible_def_path: def_id={:?}", def_id);
|
||||
return Ok((
|
||||
if !span.is_dummy() {
|
||||
self.print_def_path(def_id, &[])?
|
||||
} else {
|
||||
self.path_crate(cnum)?
|
||||
},
|
||||
true,
|
||||
));
|
||||
// NOTE(eddyb) the only reason `span` might be dummy,
|
||||
// that we're aware of, is that it's the `std`/`core`
|
||||
// `extern crate` injected by default.
|
||||
// FIXME(eddyb) find something better to key this on,
|
||||
// or avoid ending up with `ExternCrateSource::Extern`,
|
||||
// for the injected `std`/`core`.
|
||||
if span.is_dummy() {
|
||||
return Ok((self.path_crate(cnum)?, true));
|
||||
}
|
||||
|
||||
// Disable `try_print_trimmed_def_path` behavior within
|
||||
// the `print_def_path` call, to avoid infinite recursion
|
||||
// in cases where the `extern crate foo` has non-trivial
|
||||
// parents, e.g. it's nested in `impl foo::Trait for Bar`
|
||||
// (see also issues #55779 and #87932).
|
||||
self = with_no_visible_paths(|| self.print_def_path(def_id, &[]))?;
|
||||
|
||||
return Ok((self, true));
|
||||
}
|
||||
(ExternCrateSource::Path, LOCAL_CRATE) => {
|
||||
debug!("try_print_visible_def_path: def_id={:?}", def_id);
|
||||
return Ok((self.path_crate(cnum)?, true));
|
||||
}
|
||||
_ => {}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue