about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_infer/src/infer/relate/combine.rs34
-rw-r--r--tests/ui/const-generics/bad-subst-const-kind.rs1
-rw-r--r--tests/ui/const-generics/bad-subst-const-kind.stderr16
-rw-r--r--tests/ui/const-generics/generic_const_exprs/type_mismatch.rs3
-rw-r--r--tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr33
-rw-r--r--tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs1
-rw-r--r--tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr23
7 files changed, 80 insertions, 31 deletions
diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs
index 9e1dab12b4d..1c120646f1f 100644
--- a/compiler/rustc_infer/src/infer/relate/combine.rs
+++ b/compiler/rustc_infer/src/infer/relate/combine.rs
@@ -165,9 +165,9 @@ impl<'tcx> InferCtxt<'tcx> {
         //
         // This probe is probably not strictly necessary but it seems better to be safe and not accidentally find
         // ourselves with a check to find bugs being required for code to compile because it made inference progress.
-        let compatible_types = self.probe(|_| {
+        self.probe(|_| {
             if a.ty() == b.ty() {
-                return Ok(());
+                return;
             }
 
             // We don't have access to trait solving machinery in `rustc_infer` so the logic for determining if the
@@ -177,32 +177,18 @@ impl<'tcx> InferCtxt<'tcx> {
                 relation.param_env().and((a.ty(), b.ty())),
                 &mut OriginalQueryValues::default(),
             );
-            self.tcx.check_tys_might_be_eq(canonical).map_err(|_| {
+            self.tcx.check_tys_might_be_eq(canonical).unwrap_or_else(|_| {
+                // The error will only be reported later. If we emit an ErrorGuaranteed
+                // here, then we will never get to the code that actually emits the error.
                 self.tcx.dcx().delayed_bug(format!(
                     "cannot relate consts of different types (a={a:?}, b={b:?})",
-                ))
-            })
+                ));
+                // We treat these constants as if they were of the same type, so that any
+                // such constants being used in impls make these impls match barring other mismatches.
+                // This helps with diagnostics down the road.
+            });
         });
 
-        // If the consts have differing types, just bail with a const error with
-        // the expected const's type. Specifically, we don't want const infer vars
-        // to do any type shapeshifting before and after resolution.
-        if let Err(guar) = compatible_types {
-            // HACK: equating both sides with `[const error]` eagerly prevents us
-            // from leaving unconstrained inference vars during things like impl
-            // matching in the solver.
-            let a_error = ty::Const::new_error(self.tcx, guar, a.ty());
-            if let ty::ConstKind::Infer(InferConst::Var(vid)) = a.kind() {
-                return self.unify_const_variable(vid, a_error, relation.param_env());
-            }
-            let b_error = ty::Const::new_error(self.tcx, guar, b.ty());
-            if let ty::ConstKind::Infer(InferConst::Var(vid)) = b.kind() {
-                return self.unify_const_variable(vid, b_error, relation.param_env());
-            }
-
-            return Ok(if relation.a_is_expected() { a_error } else { b_error });
-        }
-
         match (a.kind(), b.kind()) {
             (
                 ty::ConstKind::Infer(InferConst::Var(a_vid)),
diff --git a/tests/ui/const-generics/bad-subst-const-kind.rs b/tests/ui/const-generics/bad-subst-const-kind.rs
index e13dfbacd24..376b18c15b8 100644
--- a/tests/ui/const-generics/bad-subst-const-kind.rs
+++ b/tests/ui/const-generics/bad-subst-const-kind.rs
@@ -11,3 +11,4 @@ impl<const N: u64> Q for [u8; N] {
 }
 
 pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { todo!() }
+//~^ ERROR: the constant `13` is not of type `u64`
diff --git a/tests/ui/const-generics/bad-subst-const-kind.stderr b/tests/ui/const-generics/bad-subst-const-kind.stderr
index 6f5bc567c37..c04a05573be 100644
--- a/tests/ui/const-generics/bad-subst-const-kind.stderr
+++ b/tests/ui/const-generics/bad-subst-const-kind.stderr
@@ -1,9 +1,23 @@
+error: the constant `13` is not of type `u64`
+  --> $DIR/bad-subst-const-kind.rs:13:24
+   |
+LL | pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { todo!() }
+   |                        ^^^^^^^^ expected `u64`, found `usize`
+   |
+note: required for `[u8; 13]` to implement `Q`
+  --> $DIR/bad-subst-const-kind.rs:8:20
+   |
+LL | impl<const N: u64> Q for [u8; N] {
+   |      ------------  ^     ^^^^^^^
+   |      |
+   |      unsatisfied trait bound introduced here
+
 error[E0308]: mismatched types
   --> $DIR/bad-subst-const-kind.rs:8:31
    |
 LL | impl<const N: u64> Q for [u8; N] {
    |                               ^ expected `usize`, found `u64`
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs b/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs
index 5813f098184..6b0d9e047db 100644
--- a/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs
+++ b/tests/ui/const-generics/generic_const_exprs/type_mismatch.rs
@@ -7,7 +7,10 @@ trait Q {
 
 impl<const N: u64> Q for [u8; N] {}
 //~^ ERROR not all trait items implemented
+//~| ERROR mismatched types
 
 pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
+//~^ ERROR the constant `13` is not of type `u64`
+//~| ERROR mismatched types
 
 pub fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr b/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr
index c73d1022ed3..bb6d650b7ab 100644
--- a/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr
@@ -7,6 +7,35 @@ LL |     const ASSOC: usize;
 LL | impl<const N: u64> Q for [u8; N] {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `ASSOC` in implementation
 
-error: aborting due to 1 previous error
+error: the constant `13` is not of type `u64`
+  --> $DIR/type_mismatch.rs:12:26
+   |
+LL | pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
+   |                          ^^^^^^^^ expected `u64`, found `usize`
+   |
+note: required for `[u8; 13]` to implement `Q`
+  --> $DIR/type_mismatch.rs:8:20
+   |
+LL | impl<const N: u64> Q for [u8; N] {}
+   |      ------------  ^     ^^^^^^^
+   |      |
+   |      unsatisfied trait bound introduced here
+
+error[E0308]: mismatched types
+  --> $DIR/type_mismatch.rs:12:20
+   |
+LL | pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
+   |        ------      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `[u8; <[u8; 13] as Q>::ASSOC]`, found `()`
+   |        |
+   |        implicitly returns `()` as its body has no tail or `return` expression
+
+error[E0308]: mismatched types
+  --> $DIR/type_mismatch.rs:8:31
+   |
+LL | impl<const N: u64> Q for [u8; N] {}
+   |                               ^ expected `usize`, found `u64`
+
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0046`.
+Some errors have detailed explanations: E0046, E0308.
+For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs
index 5fd7c647c25..8ceecd801d3 100644
--- a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs
+++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs
@@ -8,5 +8,6 @@ struct S<const L: usize>;
 impl<const N: i32> Copy for S<N> {}
 //~^ ERROR the constant `N` is not of type `usize`
 impl<const M: usize> Copy for S<M> {}
+//~^ ERROR: conflicting implementations of trait `Copy` for type `S<_>`
 
 fn main() {}
diff --git a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr
index def4a413af1..3268a876733 100644
--- a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr
+++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr
@@ -1,14 +1,29 @@
+error[E0119]: conflicting implementations of trait `Copy` for type `S<_>`
+  --> $DIR/bad-const-wf-doesnt-specialize.rs:10:1
+   |
+LL | impl<const N: i32> Copy for S<N> {}
+   | -------------------------------- first implementation here
+LL |
+LL | impl<const M: usize> Copy for S<M> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<_>`
+
 error: the constant `N` is not of type `usize`
   --> $DIR/bad-const-wf-doesnt-specialize.rs:8:29
    |
 LL | impl<const N: i32> Copy for S<N> {}
    |                             ^^^^ expected `usize`, found `i32`
    |
-note: required by a bound in `S`
-  --> $DIR/bad-const-wf-doesnt-specialize.rs:6:10
+note: required for `S<N>` to implement `Clone`
+  --> $DIR/bad-const-wf-doesnt-specialize.rs:5:10
    |
+LL | #[derive(Clone)]
+   |          ^^^^^
 LL | struct S<const L: usize>;
-   |          ^^^^^^^^^^^^^^ required by this bound in `S`
+   |          ----- unsatisfied trait bound introduced in this `derive` macro
+note: required by a bound in `Copy`
+  --> $SRC_DIR/core/src/marker.rs:LL:COL
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0119`.