1
Fork 0

Auto merge of #122802 - estebank:unconstrained-generic-const, r=Nadrieril

Provide structured suggestion for unconstrained generic constant

```
error: unconstrained generic constant
  --> $DIR/const-argument-if-length.rs:18:10
   |
LL |     pad: [u8; is_zst::<T>()],
   |          ^^^^^^^^^^^^^^^^^^^
   |
help: try adding a `where` bound
   |
LL | pub struct AtLeastByte<T: ?Sized> where [(); is_zst::<T>()]: {
   |                                   ++++++++++++++++++++++++++
```

Detect when the constant expression isn't `usize` and suggest casting:

```
error: unconstrained generic constant
 --> f300.rs:6:10
  |
6 |     bb::<{!N}>();
  |          ^^^^
-Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs:3539:36
  |
help: try adding a `where` bound
  |
5 | fn b<const N: bool>() where [(); {!N} as usize]: {
  |                       ++++++++++++++++++++++++++
```

Fix #122395.
This commit is contained in:
bors 2024-03-25 09:59:37 +00:00
commit dda2372cf3
41 changed files with 351 additions and 111 deletions

View file

@ -0,0 +1,21 @@
//@ run-rustfix
#![feature(generic_const_exprs)]
#![allow(incomplete_features, dead_code)]
struct Evaluatable<const N: u128> {}
struct Foo<const N: u8>([u8; N as usize])
//~^ ERROR unconstrained generic constant
where
Evaluatable<{N as u128}>:, [(); N as usize]:;
//~^ HELP try adding a `where` bound
struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:, [(); {N as u128} as usize]:;
//~^ ERROR unconstrained generic constant
//~| HELP try adding a `where` bound
struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:, [(); (N + 2) as usize]:;
//~^ ERROR unconstrained generic constant
//~| HELP try adding a `where` bound
fn main() {}

View file

@ -1,20 +1,21 @@
//@ run-rustfix
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
#![allow(incomplete_features, dead_code)]
struct Evaluatable<const N: u128> {}
struct Foo<const N: u8>([u8; N as usize])
//~^ Error: unconstrained generic constant
//~| help: try adding a `where` bound using this expression: `where [(); N as usize]:`
//~^ ERROR unconstrained generic constant
where
Evaluatable<{N as u128}>:;
//~^ HELP try adding a `where` bound
struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:;
//~^ Error: unconstrained generic constant
//~| help: try adding a `where` bound using this expression: `where [(); {N as u128}]:`
//~^ ERROR unconstrained generic constant
//~| HELP try adding a `where` bound
struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:;
//~^ Error: unconstrained generic constant
//~| help: try adding a `where` bound using this expression: `where [(); (N + 2) as usize]:`
//~^ ERROR unconstrained generic constant
//~| HELP try adding a `where` bound
fn main() {}

View file

@ -1,26 +1,35 @@
error: unconstrained generic constant
--> $DIR/abstract-const-as-cast-2.rs:6:25
--> $DIR/abstract-const-as-cast-2.rs:7:25
|
LL | struct Foo<const N: u8>([u8; N as usize])
| ^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); N as usize]:`
help: try adding a `where` bound
|
LL | Evaluatable<{N as u128}>:, [(); N as usize]:;
| +++++++++++++++++++
error: unconstrained generic constant
--> $DIR/abstract-const-as-cast-2.rs:12:26
--> $DIR/abstract-const-as-cast-2.rs:13:26
|
LL | struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); {N as u128}]:`
help: try adding a `where` bound
|
LL | struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:, [(); {N as u128} as usize]:;
| +++++++++++++++++++++++++++++
error: unconstrained generic constant
--> $DIR/abstract-const-as-cast-2.rs:16:25
--> $DIR/abstract-const-as-cast-2.rs:17:25
|
LL | struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:;
| ^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); (N + 2) as usize]:`
help: try adding a `where` bound
|
LL | struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:, [(); (N + 2) as usize]:;
| +++++++++++++++++++++++++
error: aborting due to 3 previous errors

View file

@ -4,7 +4,6 @@ error: unconstrained generic constant
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait`
--> $DIR/abstract-const-as-cast-3.rs:8:22
|
@ -15,6 +14,10 @@ note: required by a bound in `use_trait_impl::assert_impl`
|
LL | fn assert_impl<T: Trait>() {}
| ^^^^^ required by this bound in `assert_impl`
help: try adding a `where` bound
|
LL | EvaluatableU128<{N as u128}>:, [(); { O as u128 } as usize]: {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0308]: mismatched types
--> $DIR/abstract-const-as-cast-3.rs:17:5
@ -36,7 +39,6 @@ error: unconstrained generic constant
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait`
--> $DIR/abstract-const-as-cast-3.rs:8:22
|
@ -47,6 +49,10 @@ note: required by a bound in `use_trait_impl::assert_impl`
|
LL | fn assert_impl<T: Trait>() {}
| ^^^^^ required by this bound in `assert_impl`
help: try adding a `where` bound
|
LL | EvaluatableU128<{N as u128}>:, [(); { O as u128 } as usize]: {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0308]: mismatched types
--> $DIR/abstract-const-as-cast-3.rs:20:5
@ -96,7 +102,6 @@ error: unconstrained generic constant
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait`
--> $DIR/abstract-const-as-cast-3.rs:8:22
|
@ -107,6 +112,10 @@ note: required by a bound in `use_trait_impl_2::assert_impl`
|
LL | fn assert_impl<T: Trait>() {}
| ^^^^^ required by this bound in `assert_impl`
help: try adding a `where` bound
|
LL | EvaluatableU128<{N as _}>:, [(); { O as u128 } as usize]: {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0308]: mismatched types
--> $DIR/abstract-const-as-cast-3.rs:35:5
@ -128,7 +137,6 @@ error: unconstrained generic constant
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait`
--> $DIR/abstract-const-as-cast-3.rs:8:22
|
@ -139,6 +147,10 @@ note: required by a bound in `use_trait_impl_2::assert_impl`
|
LL | fn assert_impl<T: Trait>() {}
| ^^^^^ required by this bound in `assert_impl`
help: try adding a `where` bound
|
LL | EvaluatableU128<{N as _}>:, [(); { O as u128 } as usize]: {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0308]: mismatched types
--> $DIR/abstract-const-as-cast-3.rs:38:5

View file

@ -4,7 +4,10 @@ error: unconstrained generic constant
LL | bar::<{ N as usize as usize }>();
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); { N as usize as usize }]:`
help: try adding a `where` bound
|
LL | fn foo<const N: u8>(a: [(); N as usize]) where [(); { N as usize as usize }]: {
| ++++++++++++++++++++++++++++++++++++
error: aborting due to 1 previous error

View file

@ -4,7 +4,10 @@ error: unconstrained generic constant
LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
| ^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); 0 + N]:`
help: try adding a `where` bound
|
LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]) where [(); 0 + N]:;
| ++++++++++++++++++
error: overly complex generic constant
--> $DIR/array-size-in-generic-struct-param.rs:23:15

View file

@ -4,7 +4,10 @@ error: unconstrained generic constant
LL | bar::<{ T::ASSOC }>();
| ^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); { T::ASSOC }]:`
help: try adding a `where` bound
|
LL | fn foo<T: Trait, U: Trait>() where [(); U::ASSOC]:, [(); { T::ASSOC }]: {
| ~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 1 previous error

View file

@ -24,7 +24,10 @@ error: unconstrained generic constant
LL | foo::<_, L>([(); L + 1 + L]);
| ^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); L + 1 + L]:`
help: try adding a `where` bound
|
LL | [(); (L - 1) + 1 + L]:, [(); L + 1 + L]:
| ~~~~~~~~~~~~~~~~~~
error: unconstrained generic constant
--> $DIR/issue_114151.rs:17:17
@ -34,11 +37,6 @@ LL | foo::<_, L>([(); L + 1 + L]);
| |
| required by a bound introduced by this call
|
= help: try adding a `where` bound using this expression: `where [(); {
{
N
}
}]:`
note: required by a bound in `foo`
--> $DIR/issue_114151.rs:5:13
|
@ -51,6 +49,14 @@ LL | | N
LL | | }
LL | | }],
| |_____^ required by this bound in `foo`
help: try adding a `where` bound
|
LL ~ [(); (L - 1) + 1 + L]:, [(); {
LL + {
LL + N
LL + }
LL + }]:
|
error: unconstrained generic constant `L + 1 + L`
--> $DIR/issue_114151.rs:17:5

View file

@ -13,7 +13,10 @@ error: unconstrained generic constant
LL | Bar::<{ make_generic(N, 1_u8 == 0_u8) }>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); { make_generic(N, 1_u8 == 0_u8) }]:`
help: try adding a `where` bound
|
LL | fn foo<const N: usize>() -> Bar<{ make_generic(N, true == false) }> where [(); { make_generic(N, 1_u8 == 0_u8) } as usize]: {
| +++++++++++++++++++++++++++++++++++++++++++++++++++++++
error: aborting due to 2 previous errors

View file

@ -13,7 +13,10 @@ error: unconstrained generic constant
LL | [(); (1_u8 as usize) + N]
| ^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); (1_u8 as usize) + N]:`
help: try adding a `where` bound
|
LL | fn foo<const N: usize>() -> [(); (true as usize) + N] where [(); (1_u8 as usize) + N]: {
| ++++++++++++++++++++++++++++++++
error: aborting due to 2 previous errors

View file

@ -13,7 +13,10 @@ error: unconstrained generic constant
LL | foo::<_, L>([(); L + 1 + L]);
| ^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); L + 1 + L]:`
help: try adding a `where` bound
|
LL | [(); (L - 1) + 1 + L]:, [(); L + 1 + L]:
| ~~~~~~~~~~~~~~~~~~
error: aborting due to 2 previous errors

View file

@ -4,7 +4,6 @@ error: unconstrained generic constant
LL | let _ = const_evaluatable_lib::test1::<T>();
| ^
|
= help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
note: required by a bound in `test1`
--> $DIR/auxiliary/const_evaluatable_lib.rs:5:10
|
@ -13,6 +12,10 @@ LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
LL | where
LL | [u8; std::mem::size_of::<T>() - 1]: Sized,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
help: try adding a `where` bound
|
LL | fn user<T>() where [(); std::mem::size_of::<T>() - 1]: {
| +++++++++++++++++++++++++++++++++++++++++
error: unconstrained generic constant
--> $DIR/cross_crate_predicate.rs:7:44
@ -20,12 +23,15 @@ error: unconstrained generic constant
LL | let _ = const_evaluatable_lib::test1::<T>();
| ^
|
= help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
note: required by a bound in `test1`
--> $DIR/auxiliary/const_evaluatable_lib.rs:3:27
|
LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
help: try adding a `where` bound
|
LL | fn user<T>() where [(); std::mem::size_of::<T>() - 1]: {
| +++++++++++++++++++++++++++++++++++++++++
error: unconstrained generic constant
--> $DIR/cross_crate_predicate.rs:7:13
@ -33,7 +39,6 @@ error: unconstrained generic constant
LL | let _ = const_evaluatable_lib::test1::<T>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
note: required by a bound in `test1`
--> $DIR/auxiliary/const_evaluatable_lib.rs:5:10
|
@ -42,6 +47,10 @@ LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
LL | where
LL | [u8; std::mem::size_of::<T>() - 1]: Sized,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
help: try adding a `where` bound
|
LL | fn user<T>() where [(); std::mem::size_of::<T>() - 1]: {
| +++++++++++++++++++++++++++++++++++++++++
error: unconstrained generic constant
--> $DIR/cross_crate_predicate.rs:7:13
@ -49,12 +58,15 @@ error: unconstrained generic constant
LL | let _ = const_evaluatable_lib::test1::<T>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
note: required by a bound in `test1`
--> $DIR/auxiliary/const_evaluatable_lib.rs:3:27
|
LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
help: try adding a `where` bound
|
LL | fn user<T>() where [(); std::mem::size_of::<T>() - 1]: {
| +++++++++++++++++++++++++++++++++++++++++
error: aborting due to 4 previous errors

View file

@ -20,7 +20,10 @@ error: unconstrained generic constant
LL | let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); size_of::<*mut T>()]:`
help: try adding a `where` bound
|
LL | fn foo<T>() where [(); size_of::<*mut T>()]: {
| ++++++++++++++++++++++++++++++++
error: unconstrained generic constant
--> $DIR/dependence_lint.rs:10:9
@ -28,7 +31,10 @@ error: unconstrained generic constant
LL | [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
| ^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); size_of::<*mut T>()]:`
help: try adding a `where` bound
|
LL | fn foo<T>() where [(); size_of::<*mut T>()]: {
| ++++++++++++++++++++++++++++++++
error: aborting due to 4 previous errors

View file

@ -13,7 +13,10 @@ error: unconstrained generic constant
LL | [0; size_of::<Foo<T>>()]
| ^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); size_of::<Foo<T>>()]:`
help: try adding a `where` bound
|
LL | fn test<T>() -> [u8; size_of::<T>()] where [(); size_of::<Foo<T>>()]: {
| ++++++++++++++++++++++++++++++++
error: aborting due to 2 previous errors

View file

@ -13,7 +13,10 @@ error: unconstrained generic constant
LL | ArrayHolder([0; Self::SIZE])
| ^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); Self::SIZE]:`
help: try adding a `where` bound
|
LL | pub const fn new() -> Self where [(); Self::SIZE]: {
| +++++++++++++++++++++++
error[E0282]: type annotations needed for `ArrayHolder<X>`
--> $DIR/issue-62504.rs:26:9

View file

@ -13,12 +13,15 @@ error: unconstrained generic constant
LL | self.reference.size()
| ^^^^
|
= help: try adding a `where` bound using this expression: `where [(); Self::DIM]:`
note: required by a bound in `TensorSize::size`
--> $DIR/issue-83765.rs:9:31
|
LL | fn size(&self) -> [usize; Self::DIM];
| ^^^^^^^^^ required by this bound in `TensorSize::size`
help: try adding a `where` bound
|
LL | fn size(&self) -> [usize; DIM] where [(); Self::DIM]: {
| ++++++++++++++++++++++
error[E0308]: mismatched types
--> $DIR/issue-83765.rs:32:9

View file

@ -35,7 +35,6 @@ LL | writes_to_specific_path(&cap);
| |
| required by a bound introduced by this call
|
= help: try adding a `where` bound using this expression: `where [(); { contains::<T, U>() }]:`
note: required for `&C` to implement `Contains<(), true>`
--> $DIR/issue-85848.rs:21:12
|
@ -53,6 +52,10 @@ note: required by a bound in `writes_to_specific_path`
|
LL | fn writes_to_specific_path<C: Delegates<()>>(cap: &C) {}
| ^^^^^^^^^^^^^ required by this bound in `writes_to_specific_path`
help: try adding a `where` bound
|
LL | fn writes_to_path<C>(cap: &C) where [(); { contains::<T, U>() } as usize]: {
| ++++++++++++++++++++++++++++++++++++++++++++
error[E0308]: mismatched types
--> $DIR/issue-85848.rs:24:5

View file

@ -4,7 +4,10 @@ error: unconstrained generic constant
LL | b: [f32; complex_maths::<T>(N)],
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); complex_maths::<T>(N)]:`
help: try adding a `where` bound
|
LL | struct Example<T, const N: usize> where [(); complex_maths::<T>(N)]: {
| ++++++++++++++++++++++++++++++++++
error: aborting due to 1 previous error

View file

@ -4,7 +4,10 @@ error: unconstrained generic constant
LL | b: [f32; complex_maths(N)],
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); complex_maths(N)]:`
help: try adding a `where` bound
|
LL | pub struct Example<const N: usize> where [(); complex_maths(N)]: {
| +++++++++++++++++++++++++++++
error: unconstrained generic constant
--> $DIR/no_where_clause.rs:18:15
@ -12,7 +15,10 @@ error: unconstrained generic constant
LL | b: [0.; complex_maths(N)],
| ^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); complex_maths(N)]:`
help: try adding a `where` bound
|
LL | pub fn new() -> Self where [(); complex_maths(N)]: {
| +++++++++++++++++++++++++++++
error: aborting due to 2 previous errors

View file

@ -40,7 +40,10 @@ error: unconstrained generic constant
LL | bar2::<{ std::ops::Add::add(N, N) }>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); { std::ops::Add::add(N, N) }]:`
help: try adding a `where` bound
|
LL | fn foo2<const N: usize>(a: Evaluatable2<{ N + N }>) where [(); { std::ops::Add::add(N, N) }]: {
| +++++++++++++++++++++++++++++++++++++++++
error[E0015]: cannot call non-const operator in constants
--> $DIR/unify-op-with-fn-call.rs:20:39