about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <eddyb@lyken.rs>2021-10-10 18:50:44 +0300
committerEduard-Mihai Burtescu <eddyb@lyken.rs>2021-10-10 18:58:28 +0300
commitf14e8dd4e719bd29c6f559ffffa9a17317f4af1e (patch)
tree68d7ba3721f268baff0f3742929bfa999064bb79
parent152e40377aefe966486515c392d741f851510a8a (diff)
downloadrust-f14e8dd4e719bd29c6f559ffffa9a17317f4af1e.tar.gz
rust-f14e8dd4e719bd29c6f559ffffa9a17317f4af1e.zip
ty::pretty: prevent infinite recursion for `extern crate` paths.
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs9
-rw-r--r--src/test/ui/rust-2018/uniform-paths/auxiliary/issue-55779-extern-trait.rs1
-rw-r--r--src/test/ui/rust-2018/uniform-paths/auxiliary/issue-87932-a.rs3
-rw-r--r--src/test/ui/rust-2018/uniform-paths/issue-55779.rs29
-rw-r--r--src/test/ui/rust-2018/uniform-paths/issue-87932.rs15
-rw-r--r--src/test/ui/rust-2018/uniform-paths/issue-87932.stderr18
6 files changed, 74 insertions, 1 deletions
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index ae0cc97c704..b11a54d5dcb 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -360,7 +360,14 @@ pub trait PrettyPrinter<'tcx>:
                             return Ok((self.path_crate(cnum)?, true));
                         }
 
-                        return Ok((self.print_def_path(def_id, &[])?, 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) => {
                         return Ok((self.path_crate(cnum)?, true));
diff --git a/src/test/ui/rust-2018/uniform-paths/auxiliary/issue-55779-extern-trait.rs b/src/test/ui/rust-2018/uniform-paths/auxiliary/issue-55779-extern-trait.rs
new file mode 100644
index 00000000000..1ce9841c1a8
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/auxiliary/issue-55779-extern-trait.rs
@@ -0,0 +1 @@
+pub trait Trait { fn no_op(&self); }
diff --git a/src/test/ui/rust-2018/uniform-paths/auxiliary/issue-87932-a.rs b/src/test/ui/rust-2018/uniform-paths/auxiliary/issue-87932-a.rs
new file mode 100644
index 00000000000..8fd2d77be39
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/auxiliary/issue-87932-a.rs
@@ -0,0 +1,3 @@
+pub trait Deserialize {
+    fn deserialize();
+}
diff --git a/src/test/ui/rust-2018/uniform-paths/issue-55779.rs b/src/test/ui/rust-2018/uniform-paths/issue-55779.rs
new file mode 100644
index 00000000000..0af17a89b17
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/issue-55779.rs
@@ -0,0 +1,29 @@
+// run-pass
+// edition:2018
+// aux-crate:issue_55779_extern_trait=issue-55779-extern-trait.rs
+
+use issue_55779_extern_trait::Trait;
+
+struct Local;
+struct Helper;
+
+impl Trait for Local {
+    fn no_op(&self)
+    {
+        // (Unused) extern crate declaration necessary to reproduce bug
+        extern crate issue_55779_extern_trait;
+
+        // This one works
+        // impl Trait for Helper { fn no_op(&self) { } }
+
+        // This one infinite-loops
+        const _IMPL_SERIALIZE_FOR_HELPER: () = {
+            // (extern crate can also appear here to reproduce bug,
+            // as in originating example from serde)
+            impl Trait for Helper { fn no_op(&self) { } }
+        };
+
+    }
+}
+
+fn main() { }
diff --git a/src/test/ui/rust-2018/uniform-paths/issue-87932.rs b/src/test/ui/rust-2018/uniform-paths/issue-87932.rs
new file mode 100644
index 00000000000..70a641d8a47
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/issue-87932.rs
@@ -0,0 +1,15 @@
+// edition:2018
+// aux-crate:issue_87932_a=issue-87932-a.rs
+
+pub struct A {}
+
+impl issue_87932_a::Deserialize for A {
+    fn deserialize() {
+        extern crate issue_87932_a as _a;
+    }
+}
+
+fn main() {
+    A::deserialize();
+    //~^ ERROR no function or associated item named `deserialize` found for struct `A`
+}
diff --git a/src/test/ui/rust-2018/uniform-paths/issue-87932.stderr b/src/test/ui/rust-2018/uniform-paths/issue-87932.stderr
new file mode 100644
index 00000000000..53272abccbb
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/issue-87932.stderr
@@ -0,0 +1,18 @@
+error[E0599]: no function or associated item named `deserialize` found for struct `A` in the current scope
+  --> $DIR/issue-87932.rs:13:8
+   |
+LL | pub struct A {}
+   | ------------ function or associated item `deserialize` not found for this
+...
+LL |     A::deserialize();
+   |        ^^^^^^^^^^^ function or associated item not found in `A`
+   |
+   = help: items from traits can only be used if the trait is in scope
+help: the following trait is implemented but not in scope; perhaps add a `use` for it:
+   |
+LL | use <crate::A as issue_87932_a::Deserialize>::deserialize::_a::Deserialize;
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.