Skip to content

Commit 322c7b6

Browse files
Constrain const vars to error if const types are mismatched
1 parent ab9bb3e commit 322c7b6

File tree

5 files changed

+39
-8
lines changed

5 files changed

+39
-8
lines changed

compiler/rustc_infer/src/infer/combine.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,19 @@ impl<'tcx> InferCtxt<'tcx> {
189189
// the expected const's type. Specifically, we don't want const infer vars
190190
// to do any type shapeshifting before and after resolution.
191191
if let Err(guar) = compatible_types {
192-
return Ok(self.tcx.const_error_with_guaranteed(
193-
if relation.a_is_expected() { a.ty() } else { b.ty() },
194-
guar,
195-
));
192+
// HACK: equating both sides with `[const error]` eagerly prevents us
193+
// from leaving unconstrained inference vars during things like impl
194+
// matching in the solver.
195+
let a_error = self.tcx.const_error_with_guaranteed(a.ty(), guar);
196+
if let ty::ConstKind::Infer(InferConst::Var(vid)) = a.kind() {
197+
return self.unify_const_variable(vid, a_error);
198+
}
199+
let b_error = self.tcx.const_error_with_guaranteed(b.ty(), guar);
200+
if let ty::ConstKind::Infer(InferConst::Var(vid)) = b.kind() {
201+
return self.unify_const_variable(vid, b_error);
202+
}
203+
204+
return Ok(if relation.a_is_expected() { a_error } else { b_error });
196205
}
197206

198207
match (a.kind(), b.kind()) {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// incremental
2+
#![crate_type = "lib"]
3+
4+
trait Q {
5+
const ASSOC: usize;
6+
}
7+
8+
impl<const N: u64> Q for [u8; N] {
9+
//~^ ERROR mismatched types
10+
const ASSOC: usize = 1;
11+
}
12+
13+
pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { todo!() }
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/bad-subst-const-kind.rs:8:31
3+
|
4+
LL | impl<const N: u64> Q for [u8; N] {
5+
| ^ expected `usize`, found `u64`
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0308`.

tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
// An impl that has an erroneous const substitution should not specialize one
44
// that is well-formed.
5-
5+
#[derive(Clone)]
66
struct S<const L: usize>;
77

88
impl<const N: i32> Copy for S<N> {}
99
impl<const M: usize> Copy for S<M> {}
10-
//~^ ERROR conflicting implementations of trait `Copy` for type `S<_>`
10+
//~^ ERROR conflicting implementations of trait `Copy` for type `S<[const error]>`
1111

1212
fn main() {}

tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
error[E0119]: conflicting implementations of trait `Copy` for type `S<_>`
1+
error[E0119]: conflicting implementations of trait `Copy` for type `S<[const error]>`
22
--> $DIR/bad-const-wf-doesnt-specialize.rs:9:1
33
|
44
LL | impl<const N: i32> Copy for S<N> {}
55
| -------------------------------- first implementation here
66
LL | impl<const M: usize> Copy for S<M> {}
7-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<_>`
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<[const error]>`
88

99
error: aborting due to previous error
1010

0 commit comments

Comments
 (0)