about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-01-05 23:41:43 -0500
committerGitHub <noreply@github.com>2024-01-05 23:41:43 -0500
commit61c776ae0a01b8fd00288ef61a2c3f38d8a98b36 (patch)
tree38551ffad7b7c5668f458703034d84f4ded5a8b0
parenta95a363dbab113bcee3bbe3f8b0f8d854297d0fe (diff)
parent339fa311ad8140cfb98a1c6080ea7e002b9ce3fa (diff)
downloadrust-61c776ae0a01b8fd00288ef61a2c3f38d8a98b36.tar.gz
rust-61c776ae0a01b8fd00288ef61a2c3f38d8a98b36.zip
Rollup merge of #119638 - lukas-code:suggest-constructor-cycle-error, r=cjgillot
fix cyle error when suggesting to use associated function instead of constructor

Fixes https://github.com/rust-lang/rust/issues/119625.

The first commit fixes the infinite recursion and makes the cycle error actually show up. We do this by making the `Display` for `ty::Instance` impl  respect `with_no_queries` so that it can be used in query descriptions.

The second commit fixes the cycle error `resolver_for_lowering` -> `normalize` -> `resolve_instance` (for evaluating const) -> `lang_items` (for `drop_in_place`) -> `resolver_for_lowering` (for collecting lang items). We do this by simply skipping the suggestion when encountering an unnormalized type.
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs12
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs7
-rw-r--r--tests/ui/resolve/auxiliary/suggest-constructor-cycle-error.rs12
-rw-r--r--tests/ui/resolve/suggest-constructor-cycle-error.rs10
-rw-r--r--tests/ui/resolve/suggest-constructor-cycle-error.stderr15
5 files changed, 47 insertions, 9 deletions
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 2ac3cddfa15..dd41cb5a61f 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -293,12 +293,16 @@ impl<'tcx> InstanceDef<'tcx> {
 fn fmt_instance(
     f: &mut fmt::Formatter<'_>,
     instance: &Instance<'_>,
-    type_length: rustc_session::Limit,
+    type_length: Option<rustc_session::Limit>,
 ) -> fmt::Result {
     ty::tls::with(|tcx| {
         let args = tcx.lift(instance.args).expect("could not lift for printing");
 
-        let mut cx = FmtPrinter::new_with_limit(tcx, Namespace::ValueNS, type_length);
+        let mut cx = if let Some(type_length) = type_length {
+            FmtPrinter::new_with_limit(tcx, Namespace::ValueNS, type_length)
+        } else {
+            FmtPrinter::new(tcx, Namespace::ValueNS)
+        };
         cx.print_def_path(instance.def_id(), args)?;
         let s = cx.into_buffer();
         f.write_str(&s)
@@ -324,13 +328,13 @@ pub struct ShortInstance<'a, 'tcx>(pub &'a Instance<'tcx>, pub usize);
 
 impl<'a, 'tcx> fmt::Display for ShortInstance<'a, 'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt_instance(f, self.0, rustc_session::Limit(self.1))
+        fmt_instance(f, self.0, Some(rustc_session::Limit(self.1)))
     }
 }
 
 impl<'tcx> fmt::Display for Instance<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        ty::tls::with(|tcx| fmt_instance(f, self, tcx.type_length_limit()))
+        fmt_instance(f, self, None)
     }
 }
 
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 0fe606cacf5..821aafe2fed 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1755,11 +1755,8 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
             .filter_map(|item| {
                 // Only assoc fns that return `Self`
                 let fn_sig = self.r.tcx.fn_sig(item.def_id).skip_binder();
-                let ret_ty = fn_sig.output();
-                let ret_ty = self
-                    .r
-                    .tcx
-                    .normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), ret_ty);
+                // Don't normalize the return type, because that can cause cycle errors.
+                let ret_ty = fn_sig.output().skip_binder();
                 let ty::Adt(def, _args) = ret_ty.kind() else {
                     return None;
                 };
diff --git a/tests/ui/resolve/auxiliary/suggest-constructor-cycle-error.rs b/tests/ui/resolve/auxiliary/suggest-constructor-cycle-error.rs
new file mode 100644
index 00000000000..8de68c38bc3
--- /dev/null
+++ b/tests/ui/resolve/auxiliary/suggest-constructor-cycle-error.rs
@@ -0,0 +1,12 @@
+mod m {
+    pub struct Uuid(());
+
+    impl Uuid {
+        pub fn encode_buffer() -> [u8; LENGTH] {
+            []
+        }
+    }
+    const LENGTH: usize = 0;
+}
+
+pub use m::Uuid;
diff --git a/tests/ui/resolve/suggest-constructor-cycle-error.rs b/tests/ui/resolve/suggest-constructor-cycle-error.rs
new file mode 100644
index 00000000000..e36fffd97d1
--- /dev/null
+++ b/tests/ui/resolve/suggest-constructor-cycle-error.rs
@@ -0,0 +1,10 @@
+// aux-build:suggest-constructor-cycle-error.rs
+
+// Regression test for https://github.com/rust-lang/rust/issues/119625
+
+extern crate suggest_constructor_cycle_error as a;
+
+const CONST_NAME: a::Uuid = a::Uuid(());
+//~^ ERROR: cannot initialize a tuple struct which contains private fields [E0423]
+
+fn main() {}
diff --git a/tests/ui/resolve/suggest-constructor-cycle-error.stderr b/tests/ui/resolve/suggest-constructor-cycle-error.stderr
new file mode 100644
index 00000000000..c6ec2465a43
--- /dev/null
+++ b/tests/ui/resolve/suggest-constructor-cycle-error.stderr
@@ -0,0 +1,15 @@
+error[E0423]: cannot initialize a tuple struct which contains private fields
+  --> $DIR/suggest-constructor-cycle-error.rs:7:29
+   |
+LL | const CONST_NAME: a::Uuid = a::Uuid(());
+   |                             ^^^^^^^
+   |
+note: constructor is not visible here due to private fields
+  --> $DIR/auxiliary/suggest-constructor-cycle-error.rs:2:21
+   |
+LL |     pub struct Uuid(());
+   |                     ^^ private field
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0423`.