Fail relating constants of different types

This commit is contained in:
Oli Scherer 2024-05-23 13:37:39 +00:00
parent 7c547894c7
commit 9dc76207ff
13 changed files with 84 additions and 119 deletions

View file

@ -168,7 +168,7 @@ pub fn super_combine_consts<R>(
// ourselves with a check to find bugs being required for code to compile because it made inference progress.
self.probe(|_| {
if a.ty() == b.ty() {
return;
return Ok(());
}
// We don't have access to trait solving machinery in `rustc_infer` so the logic for determining if the
@ -178,18 +178,15 @@ pub fn super_combine_consts<R>(
relation.param_env().and((a.ty(), b.ty())),
&mut OriginalQueryValues::default(),
);
self.tcx.check_tys_might_be_eq(canonical).unwrap_or_else(|_| {
self.tcx.check_tys_might_be_eq(canonical).map_err(|_| {
// 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.
});
});
TypeError::Mismatch
})
})?;
match (a.kind(), b.kind()) {
(
ty::ConstKind::Infer(InferConst::Var(a_vid)),

View file

@ -1,13 +0,0 @@
//@ known-bug: #121585
#![feature(generic_const_exprs)]
trait Trait {}
struct HasCastInTraitImpl<const N: usize, const M: u128>;
impl<const O: f64> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
pub fn use_trait_impl() {
fn assert_impl<T: Trait>() {}
assert_impl::<HasCastInTraitImpl<13, 13>>();
}

View file

@ -1,30 +0,0 @@
//@ known-bug: #121585
//@ check-pass
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
trait Trait {}
pub struct EvaluatableU128<const N: u128>;
struct HasCastInTraitImpl<const N: usize, const M: u128>;
impl<const O: f64> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
pub fn use_trait_impl<const N: usize>() where EvaluatableU128<{N as u128}>:, {
fn assert_impl<T: Trait>() {}
assert_impl::<HasCastInTraitImpl<N, { N as u128 }>>();
assert_impl::<HasCastInTraitImpl<N, { N as _ }>>();
assert_impl::<HasCastInTraitImpl<12, { 12 as u128 }>>();
assert_impl::<HasCastInTraitImpl<13, 13>>();
}
pub fn use_trait_impl_2<const N: usize>() where EvaluatableU128<{N as _}>:, {
fn assert_impl<T: Trait>() {}
assert_impl::<HasCastInTraitImpl<N, { N as u128 }>>();
assert_impl::<HasCastInTraitImpl<N, { N as _ }>>();
assert_impl::<HasCastInTraitImpl<12, { 12 as u128 }>>()const NUM: u8 = xyz();
assert_impl::<HasCastInTraitImpl<13, 13>>();
}
fn main() {}

View file

@ -1,20 +0,0 @@
//@ known-bug: #121858
#![allow(named_arguments_used_positionally)]
#![feature(generic_const_exprs)]
struct Inner<const N: usize, const M: usize>;
impl<const N: usize, const M: usize> Inner<N, M> where [(); N + M]: {
fn i() -> Self {
Self
}
}
struct Outer<const A: i64, const B: usize>(Inner<A, { B * 2 }>) where [(); A + (B * 2)]:;
impl<const A: usize, const B: usize> Outer<A, B> where [(); A + (B * 2)]: {
fn o() -> Union {
Self(Inner::i())
}
}
fn main() {
Outer::<1, 1>::o();
}

View file

@ -1,14 +0,0 @@
//@ known-bug: #124151
#![feature(generic_const_exprs)]
use std::ops::Add;
pub struct Dimension;
pub struct Quantity<S, const D: Dimension>(S);
impl<const D: Dimension, LHS, RHS> Add<LHS, D> for Quantity<LHS, { Dimension }> {}
pub fn add<const U: Dimension>(x: Quantity<f32, U>) -> Quantity<f32, U> {
x + y
}

View file

@ -11,4 +11,4 @@ trait Q {
}
pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { todo!() }
//~^ ERROR: the constant `13` is not of type `u64`
//~^ ERROR: `[u8; 13]: Q` is not satisfied

View file

@ -1,16 +1,10 @@
error: the constant `13` is not of type `u64`
error[E0277]: the trait bound `[u8; 13]: Q` is not satisfied
--> $DIR/bad-subst-const-kind.rs:13:24
|
LL | pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { todo!() }
| ^^^^^^^^ expected `u64`, found `usize`
| ^^^^^^^^ the trait `Q` is not implemented for `[u8; 13]`
|
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
= help: the trait `Q` is implemented for `[u8; N]`
error[E0308]: mismatched types
--> $DIR/bad-subst-const-kind.rs:8:31
@ -20,4 +14,5 @@ LL | impl<const N: u64> Q for [u8; N] {
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.
Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.

View file

@ -10,7 +10,7 @@ trait Q {
//~| ERROR mismatched types
pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
//~^ ERROR the constant `13` is not of type `u64`
//~^ ERROR `[u8; 13]: Q` is not satisfied
//~| ERROR mismatched types
pub fn main() {}

View file

@ -7,19 +7,13 @@ LL | const ASSOC: usize;
LL | impl<const N: u64> Q for [u8; N] {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `ASSOC` in implementation
error: the constant `13` is not of type `u64`
error[E0277]: the trait bound `[u8; 13]: Q` is not satisfied
--> $DIR/type_mismatch.rs:12:26
|
LL | pub fn q_user() -> [u8; <[u8; 13] as Q>::ASSOC] {}
| ^^^^^^^^ expected `u64`, found `usize`
| ^^^^^^^^ the trait `Q` is not implemented for `[u8; 13]`
|
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
= help: the trait `Q` is implemented for `[u8; N]`
error[E0308]: mismatched types
--> $DIR/type_mismatch.rs:12:20
@ -37,5 +31,5 @@ LL | impl<const N: u64> Q for [u8; N] {}
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0046, E0308.
Some errors have detailed explanations: E0046, E0277, E0308.
For more information about an error, try `rustc --explain E0046`.

View file

@ -1,14 +1,17 @@
//@ known-bug: #121858
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
struct Outer<const A: i64, const B: usize>();
impl<const A: usize, const B: usize> Outer<A, B>
//~^ ERROR: `A` is not of type `i64`
//~| ERROR: mismatched types
where
[(); A + (B * 2)]:,
{
fn o() -> Union {}
fn o() {}
}
fn main() {
Outer::<1, 1>::o();
//~^ ERROR: no function or associated item named `o` found
}

View file

@ -0,0 +1,34 @@
error: the constant `A` is not of type `i64`
--> $DIR/eval_type_mismatch.rs:5:38
|
LL | impl<const A: usize, const B: usize> Outer<A, B>
| ^^^^^^^^^^^ expected `i64`, found `usize`
|
note: required by a bound in `Outer`
--> $DIR/eval_type_mismatch.rs:4:14
|
LL | struct Outer<const A: i64, const B: usize>();
| ^^^^^^^^^^^^ required by this bound in `Outer`
error[E0599]: no function or associated item named `o` found for struct `Outer<1, 1>` in the current scope
--> $DIR/eval_type_mismatch.rs:15:20
|
LL | struct Outer<const A: i64, const B: usize>();
| ------------------------------------------ function or associated item `o` not found for this struct
...
LL | Outer::<1, 1>::o();
| ^ function or associated item not found in `Outer<1, 1>`
|
= note: the function or associated item was found for
- `Outer<A, B>`
error[E0308]: mismatched types
--> $DIR/eval_type_mismatch.rs:5:44
|
LL | impl<const A: usize, const B: usize> Outer<A, B>
| ^ expected `i64`, found `usize`
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0308, E0599.
For more information about an error, try `rustc --explain E0308`.

View file

@ -7,7 +7,8 @@
impl<const N: i32> Copy for S<N> {}
//~^ ERROR: mismatched types
//~| ERROR: the trait bound `S<N>: Clone` is not satisfied
//~| 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() {}

View file

@ -1,11 +1,29 @@
error[E0119]: conflicting implementations of trait `Copy` for type `S<_>`
--> $DIR/bad-const-wf-doesnt-specialize.rs:10:1
error[E0277]: the trait bound `S<N>: Clone` is not satisfied
--> $DIR/bad-const-wf-doesnt-specialize.rs:8:29
|
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<_>`
| ^^^^ the trait `Clone` is not implemented for `S<N>`
|
= help: the trait `Clone` is implemented for `S<L>`
note: required by a bound in `Copy`
--> $SRC_DIR/core/src/marker.rs:LL:COL
help: consider annotating `S<N>` with `#[derive(Clone)]`
|
LL + #[derive(Clone)]
LL | struct S<const L: usize>;
|
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
|
LL | struct S<const L: usize>;
| ^^^^^^^^^^^^^^ required by this bound in `S`
error[E0308]: mismatched types
--> $DIR/bad-const-wf-doesnt-specialize.rs:8:31
@ -13,7 +31,7 @@ error[E0308]: mismatched types
LL | impl<const N: i32> Copy for S<N> {}
| ^ expected `usize`, found `i32`
error: aborting due to 2 previous errors
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0119, E0308.
For more information about an error, try `rustc --explain E0119`.
Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.