about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-05-22 16:04:12 +0200
committerGitHub <noreply@github.com>2025-05-22 16:04:12 +0200
commit5cab70ed7fb444775a4ad7e965cd456592e3ffb7 (patch)
tree9b41bd7ca084af708c50548269246f729bc416e8
parent654b2f39f19fac2aaa9a46a89a94048128067300 (diff)
parentbc9cdc960f7ba7a926cea97cf0cec77097ca7851 (diff)
downloadrust-5cab70ed7fb444775a4ad7e965cd456592e3ffb7.tar.gz
rust-5cab70ed7fb444775a4ad7e965cd456592e3ffb7.zip
Rollup merge of #141362 - BoxyUwU:correct_error_term_kind, r=lcnr
Normalize aliases to correct kind of error term

Fixes #140642

When normalizing an alias to an error in the old solver, normalize to the same term kind as the alias being normalized instead of always to a type error.

r? lcnr
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs29
-rw-r--r--tests/crashes/140642.rs8
-rw-r--r--tests/ui/const-generics/mgca/projection-error.rs17
-rw-r--r--tests/ui/const-generics/mgca/projection-error.stderr39
4 files changed, 81 insertions, 12 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index ca58da5ca6d..ed0f34b5aa9 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -378,6 +378,7 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>(
             term: projected_term,
             obligations: mut projected_obligations,
         })) => {
+            debug!("opt_normalize_projection_type: progress");
             // if projection succeeded, then what we get out of this
             // is also non-normalized (consider: it was derived from
             // an impl, where-clause etc) and hence we must
@@ -408,6 +409,7 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>(
             Ok(Some(result.value))
         }
         Ok(Projected::NoProgress(projected_ty)) => {
+            debug!("opt_normalize_projection_type: no progress");
             let result =
                 Normalized { value: projected_ty, obligations: PredicateObligations::new() };
             infcx.inner.borrow_mut().projection_cache().insert_term(cache_key, result.clone());
@@ -621,8 +623,17 @@ struct Progress<'tcx> {
 }
 
 impl<'tcx> Progress<'tcx> {
-    fn error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self {
-        Progress { term: Ty::new_error(tcx, guar).into(), obligations: PredicateObligations::new() }
+    fn error_for_term(
+        tcx: TyCtxt<'tcx>,
+        alias_term: ty::AliasTerm<'tcx>,
+        guar: ErrorGuaranteed,
+    ) -> Self {
+        let err_term = if alias_term.kind(tcx).is_type() {
+            Ty::new_error(tcx, guar).into()
+        } else {
+            ty::Const::new_error(tcx, guar).into()
+        };
+        Progress { term: err_term, obligations: PredicateObligations::new() }
     }
 
     fn with_addl_obligations(mut self, mut obligations: PredicateObligations<'tcx>) -> Self {
@@ -650,7 +661,11 @@ fn project<'cx, 'tcx>(
     }
 
     if let Err(guar) = obligation.predicate.error_reported() {
-        return Ok(Projected::Progress(Progress::error(selcx.tcx(), guar)));
+        return Ok(Projected::Progress(Progress::error_for_term(
+            selcx.tcx(),
+            obligation.predicate,
+            guar,
+        )));
     }
 
     let mut candidates = ProjectionCandidateSet::None;
@@ -1965,7 +1980,13 @@ fn confirm_impl_candidate<'cx, 'tcx>(
     let param_env = obligation.param_env;
     let assoc_term = match specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) {
         Ok(assoc_term) => assoc_term,
-        Err(guar) => return Ok(Projected::Progress(Progress::error(tcx, guar))),
+        Err(guar) => {
+            return Ok(Projected::Progress(Progress::error_for_term(
+                tcx,
+                obligation.predicate,
+                guar,
+            )));
+        }
     };
 
     // This means that the impl is missing a definition for the
diff --git a/tests/crashes/140642.rs b/tests/crashes/140642.rs
deleted file mode 100644
index ff75a6ec2f2..00000000000
--- a/tests/crashes/140642.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ known-bug: #140642
-#![feature(min_generic_const_args)]
-
-pub trait Tr<A> {
-    const SIZE: usize;
-}
-
-fn mk_array(_x: T) -> [(); <T as Tr<bool>>::SIZE] {}
diff --git a/tests/ui/const-generics/mgca/projection-error.rs b/tests/ui/const-generics/mgca/projection-error.rs
new file mode 100644
index 00000000000..d1c4fa8a492
--- /dev/null
+++ b/tests/ui/const-generics/mgca/projection-error.rs
@@ -0,0 +1,17 @@
+#![feature(min_generic_const_args)]
+#![expect(incomplete_features)]
+
+// Regression test for #140642. Test that normalizing const aliases
+// containing erroneous types normalizes to a const error instead of
+// a type error.
+
+
+pub trait Tr<A> {
+    const SIZE: usize;
+}
+
+fn mk_array(_x: T) -> [(); <T as Tr<bool>>::SIZE] {}
+//~^ ERROR: cannot find type `T` in this scope
+//~| ERROR: cannot find type `T` in this scope
+
+fn main() {}
diff --git a/tests/ui/const-generics/mgca/projection-error.stderr b/tests/ui/const-generics/mgca/projection-error.stderr
new file mode 100644
index 00000000000..e6888351da1
--- /dev/null
+++ b/tests/ui/const-generics/mgca/projection-error.stderr
@@ -0,0 +1,39 @@
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/projection-error.rs:13:17
+   |
+LL | pub trait Tr<A> {
+   | --------------- similarly named trait `Tr` defined here
+...
+LL | fn mk_array(_x: T) -> [(); <T as Tr<bool>>::SIZE] {}
+   |                 ^
+   |
+help: a trait with a similar name exists
+   |
+LL | fn mk_array(_x: Tr) -> [(); <T as Tr<bool>>::SIZE] {}
+   |                  +
+help: you might be missing a type parameter
+   |
+LL | fn mk_array<T>(_x: T) -> [(); <T as Tr<bool>>::SIZE] {}
+   |            +++
+
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/projection-error.rs:13:29
+   |
+LL | pub trait Tr<A> {
+   | --------------- similarly named trait `Tr` defined here
+...
+LL | fn mk_array(_x: T) -> [(); <T as Tr<bool>>::SIZE] {}
+   |                             ^
+   |
+help: a trait with a similar name exists
+   |
+LL | fn mk_array(_x: T) -> [(); <Tr as Tr<bool>>::SIZE] {}
+   |                              +
+help: you might be missing a type parameter
+   |
+LL | fn mk_array<T>(_x: T) -> [(); <T as Tr<bool>>::SIZE] {}
+   |            +++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0412`.