Skip to content

Commit f14e8dd

Browse files
committed
ty::pretty: prevent infinite recursion for extern crate paths.
1 parent 152e403 commit f14e8dd

File tree

6 files changed

+74
-1
lines changed

6 files changed

+74
-1
lines changed

compiler/rustc_middle/src/ty/print/pretty.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,14 @@ pub trait PrettyPrinter<'tcx>:
360360
return Ok((self.path_crate(cnum)?, true));
361361
}
362362

363-
return Ok((self.print_def_path(def_id, &[])?, true));
363+
// Disable `try_print_trimmed_def_path` behavior within
364+
// the `print_def_path` call, to avoid infinite recursion
365+
// in cases where the `extern crate foo` has non-trivial
366+
// parents, e.g. it's nested in `impl foo::Trait for Bar`
367+
// (see also issues #55779 and #87932).
368+
self = with_no_visible_paths(|| self.print_def_path(def_id, &[]))?;
369+
370+
return Ok((self, true));
364371
}
365372
(ExternCrateSource::Path, LOCAL_CRATE) => {
366373
return Ok((self.path_crate(cnum)?, true));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub trait Trait { fn no_op(&self); }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub trait Deserialize {
2+
fn deserialize();
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// run-pass
2+
// edition:2018
3+
// aux-crate:issue_55779_extern_trait=issue-55779-extern-trait.rs
4+
5+
use issue_55779_extern_trait::Trait;
6+
7+
struct Local;
8+
struct Helper;
9+
10+
impl Trait for Local {
11+
fn no_op(&self)
12+
{
13+
// (Unused) extern crate declaration necessary to reproduce bug
14+
extern crate issue_55779_extern_trait;
15+
16+
// This one works
17+
// impl Trait for Helper { fn no_op(&self) { } }
18+
19+
// This one infinite-loops
20+
const _IMPL_SERIALIZE_FOR_HELPER: () = {
21+
// (extern crate can also appear here to reproduce bug,
22+
// as in originating example from serde)
23+
impl Trait for Helper { fn no_op(&self) { } }
24+
};
25+
26+
}
27+
}
28+
29+
fn main() { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// edition:2018
2+
// aux-crate:issue_87932_a=issue-87932-a.rs
3+
4+
pub struct A {}
5+
6+
impl issue_87932_a::Deserialize for A {
7+
fn deserialize() {
8+
extern crate issue_87932_a as _a;
9+
}
10+
}
11+
12+
fn main() {
13+
A::deserialize();
14+
//~^ ERROR no function or associated item named `deserialize` found for struct `A`
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0599]: no function or associated item named `deserialize` found for struct `A` in the current scope
2+
--> $DIR/issue-87932.rs:13:8
3+
|
4+
LL | pub struct A {}
5+
| ------------ function or associated item `deserialize` not found for this
6+
...
7+
LL | A::deserialize();
8+
| ^^^^^^^^^^^ function or associated item not found in `A`
9+
|
10+
= help: items from traits can only be used if the trait is in scope
11+
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
12+
|
13+
LL | use <crate::A as issue_87932_a::Deserialize>::deserialize::_a::Deserialize;
14+
|
15+
16+
error: aborting due to previous error
17+
18+
For more information about this error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)