Skip to content

Commit 4c5bbbb

Browse files
committed
Impossible preds tests
1 parent b79cb46 commit 4c5bbbb

6 files changed

+214
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Check that we emit the `CONST_EVALUATABLE_UNCHECKED` FCW when a repeat expr
2+
// count depends on in-scope where clauses to prove an impossible bound but does
3+
// not otherwise depend on any in-scope generic parameters.
4+
5+
pub trait Unimplemented<'a> {}
6+
7+
trait Trait<T>
8+
where
9+
for<'a> T: Unimplemented<'a>,
10+
{
11+
const ASSOC: usize;
12+
}
13+
14+
impl<T> Trait<T> for u8
15+
where
16+
for<'a> T: Unimplemented<'a>,
17+
{
18+
const ASSOC: usize = 1;
19+
}
20+
21+
pub fn impossible_preds_repeat_expr_count()
22+
where
23+
for<'a> (): Unimplemented<'a>,
24+
{
25+
let _a: [(); 1] = [(); <u8 as Trait<()>>::ASSOC];
26+
}
27+
28+
struct Foo<const N: usize>;
29+
30+
pub fn impossible_preds_normal_arg()
31+
where
32+
for<'a> (): Unimplemented<'a>,
33+
{
34+
let _a: Foo<1> = Foo::<{ <u8 as Trait<()>>::ASSOC }>;
35+
//~^ ERROR: the trait bound `for<'a> (): Unimplemented<'a>`
36+
//~| ERROR: the trait bound `for<'a> (): Unimplemented<'a>`
37+
}
38+
39+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
error[E0277]: the trait bound `for<'a> (): Unimplemented<'a>` is not satisfied
2+
--> $DIR/impossible_preds_repeat_expr_hack.rs:34:43
3+
|
4+
LL | let _a: Foo<1> = Foo::<{ <u8 as Trait<()>>::ASSOC }>;
5+
| ^^ the trait `for<'a> Unimplemented<'a>` is not implemented for `()`
6+
|
7+
help: this trait has no implementations, consider adding one
8+
--> $DIR/impossible_preds_repeat_expr_hack.rs:5:1
9+
|
10+
LL | pub trait Unimplemented<'a> {}
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
note: required by a bound in `Trait::ASSOC`
13+
--> $DIR/impossible_preds_repeat_expr_hack.rs:9:16
14+
|
15+
LL | for<'a> T: Unimplemented<'a>,
16+
| ^^^^^^^^^^^^^^^^^ required by this bound in `Trait::ASSOC`
17+
LL | {
18+
LL | const ASSOC: usize;
19+
| ----- required by a bound in this associated constant
20+
21+
error[E0277]: the trait bound `for<'a> (): Unimplemented<'a>` is not satisfied
22+
--> $DIR/impossible_preds_repeat_expr_hack.rs:34:31
23+
|
24+
LL | let _a: Foo<1> = Foo::<{ <u8 as Trait<()>>::ASSOC }>;
25+
| ^^ the trait `for<'a> Unimplemented<'a>` is not implemented for `()`
26+
|
27+
help: this trait has no implementations, consider adding one
28+
--> $DIR/impossible_preds_repeat_expr_hack.rs:5:1
29+
|
30+
LL | pub trait Unimplemented<'a> {}
31+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
32+
note: required for `u8` to implement `Trait<()>`
33+
--> $DIR/impossible_preds_repeat_expr_hack.rs:14:9
34+
|
35+
LL | impl<T> Trait<T> for u8
36+
| ^^^^^^^^ ^^
37+
LL | where
38+
LL | for<'a> T: Unimplemented<'a>,
39+
| ----------------- unsatisfied trait bound introduced here
40+
41+
error: aborting due to 2 previous errors
42+
43+
For more information about this error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#![feature(generic_const_items, min_generic_const_args)]
2+
#![expect(incomplete_features)]
3+
4+
// Tests behaviour of attempting to evaluate const arguments whose wellformedness
5+
// depends on impossible to satisfy predicates, that are satisfied from another
6+
// trivially false clause in the environment.
7+
//
8+
// Additionally tests how (or if) this behaviour differs depending on whether the
9+
// constants where trivially false where clause is global or not.
10+
11+
trait Unimplemented<'a> {}
12+
13+
trait Trait {
14+
const NON_GLOBAL<T>: usize
15+
where
16+
for<'a> T: Unimplemented<'a>;
17+
18+
const GLOBAL: usize
19+
where
20+
for<'a> (): Unimplemented<'a>;
21+
}
22+
23+
impl Trait for u8 {
24+
const NON_GLOBAL<T>: usize = 1
25+
where
26+
for<'a> T: Unimplemented<'a>;
27+
28+
const GLOBAL: usize = 1
29+
//~^ ERROR: evaluation of constant value failed
30+
where
31+
for<'a> (): Unimplemented<'a>;
32+
}
33+
34+
struct Foo<const N: usize>;
35+
36+
fn non_global()
37+
where
38+
for<'a> (): Unimplemented<'a>,
39+
{
40+
let _: Foo<1> = Foo::<{ <u8 as Trait>::NON_GLOBAL::<()> }>;
41+
}
42+
43+
fn global()
44+
where
45+
for<'a> (): Unimplemented<'a>,
46+
{
47+
let _: Foo<1> = Foo::<{ <u8 as Trait>::GLOBAL }>;
48+
}
49+
50+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0080]: evaluation of constant value failed
2+
--> $DIR/impossible_preds_on_anon_const.rs:28:5
3+
|
4+
LL | / const GLOBAL: usize = 1
5+
LL | |
6+
LL | | where
7+
LL | | for<'a> (): Unimplemented<'a>;
8+
| |______________________________________^ entering unreachable code
9+
10+
error: aborting due to 1 previous error
11+
12+
For more information about this error, try `rustc --explain E0080`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#![feature(generic_const_items)]
2+
#![expect(incomplete_features)]
3+
4+
trait Unimplemented<'a> {}
5+
6+
trait Trait<T>
7+
where
8+
for<'a> T: Unimplemented<'a>,
9+
{
10+
const ASSOC: usize;
11+
}
12+
13+
impl<T> Trait<T> for ()
14+
where
15+
for<'a> T: Unimplemented<'a>,
16+
{
17+
const ASSOC: usize = 0;
18+
}
19+
20+
trait Global {
21+
const ASSOC: usize
22+
where
23+
for<'a> (): Unimplemented<'a>;
24+
}
25+
26+
impl Global for () {
27+
const ASSOC: usize = 0
28+
//~^ ERROR: evaluation of constant value failed
29+
where
30+
for<'a> (): Unimplemented<'a>;
31+
}
32+
33+
fn works(x: usize)
34+
where
35+
for<'a> (): Unimplemented<'a>,
36+
{
37+
// In order for match exhaustiveness to determine this match is OK, CTFE must
38+
// be able to evalaute `<() as Trait>::ASSOC` which depends on a trivially
39+
// false bound for well formedness.
40+
match x {
41+
<() as Trait<()>>::ASSOC => todo!(),
42+
1.. => todo!(),
43+
}
44+
}
45+
46+
fn errors(x: usize)
47+
where
48+
for<'a> (): Unimplemented<'a>,
49+
{
50+
// This errors due to the MIR for `ASSOC` being empty due to the
51+
// globally false bound.
52+
match x {
53+
<() as Global>::ASSOC => todo!(),
54+
1.. => todo!(),
55+
}
56+
}
57+
58+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0080]: evaluation of constant value failed
2+
--> $DIR/impossible_preds_const_pattern.rs:27:5
3+
|
4+
LL | / const ASSOC: usize = 0
5+
LL | |
6+
LL | | where
7+
LL | | for<'a> (): Unimplemented<'a>;
8+
| |______________________________________^ entering unreachable code
9+
10+
error: aborting due to 1 previous error
11+
12+
For more information about this error, try `rustc --explain E0080`.

0 commit comments

Comments
 (0)