rename const_evaluatable_checked to generic_const_exprs
✨
This commit is contained in:
parent
dbb0fe9d80
commit
fcc2badf9b
146 changed files with 178 additions and 213 deletions
|
@ -0,0 +1,18 @@
|
|||
// check-pass
|
||||
#![feature(generic_const_exprs, const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct Foo<const N: u8>([u8; N as usize])
|
||||
where
|
||||
[(); N as usize]:;
|
||||
|
||||
struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 2) as usize]:;
|
||||
|
||||
// unifying with subtrees
|
||||
struct Evaluatable<const N: u16>;
|
||||
fn foo<const N: u8>() where Evaluatable<{N as usize as u16 }>: {
|
||||
let _ = Foo::<N>([1; N as usize]);
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,20 @@
|
|||
#![feature(generic_const_exprs, const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
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]:`
|
||||
where
|
||||
Evaluatable<{N as u128}>:;
|
||||
|
||||
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}]:`
|
||||
|
||||
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]:`
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,26 @@
|
|||
error: unconstrained generic constant
|
||||
--> $DIR/abstract-const-as-cast-2.rs:6:25
|
||||
|
|
||||
LL | struct Foo<const N: u8>([u8; N as usize])
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); N as usize]:`
|
||||
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/abstract-const-as-cast-2.rs:12: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}]:`
|
||||
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/abstract-const-as-cast-2.rs:16: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]:`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
#![feature(const_generics, 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: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
|
||||
|
||||
pub fn use_trait_impl<const N: usize>()
|
||||
where
|
||||
[(); { N + 1}]:,
|
||||
EvaluatableU128<{N as u128}>:, {
|
||||
fn assert_impl<T: Trait>() {}
|
||||
|
||||
// errors are bad but seems to be pre-existing issue #86198
|
||||
assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
|
||||
//~^ Error: mismatched types
|
||||
//~^^ Error: unconstrained generic constant
|
||||
assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
|
||||
//~^ Error: mismatched types
|
||||
//~^^ Error: unconstrained generic constant
|
||||
assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
|
||||
//~^ Error: mismatched types
|
||||
assert_impl::<HasCastInTraitImpl<14, 13>>();
|
||||
//~^ Error: mismatched types
|
||||
}
|
||||
pub fn use_trait_impl_2<const N: usize>()
|
||||
where
|
||||
[(); { N + 1}]:,
|
||||
EvaluatableU128<{N as _}>:, {
|
||||
fn assert_impl<T: Trait>() {}
|
||||
|
||||
// errors are bad but seems to be pre-existing issue #86198
|
||||
assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
|
||||
//~^ Error: mismatched types
|
||||
//~^^ Error: unconstrained generic constant
|
||||
assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
|
||||
//~^ Error: mismatched types
|
||||
//~^^ Error: unconstrained generic constant
|
||||
assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
|
||||
//~^ Error: mismatched types
|
||||
assert_impl::<HasCastInTraitImpl<14, 13>>();
|
||||
//~^ Error: mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,147 @@
|
|||
error: unconstrained generic constant
|
||||
--> $DIR/abstract-const-as-cast-3.rs:17:5
|
||||
|
|
||||
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
|
||||
note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>`
|
||||
--> $DIR/abstract-const-as-cast-3.rs:8:22
|
||||
|
|
||||
LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
|
||||
| ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: required by a bound in `use_trait_impl::assert_impl`
|
||||
--> $DIR/abstract-const-as-cast-3.rs:14:23
|
||||
|
|
||||
LL | fn assert_impl<T: Trait>() {}
|
||||
| ^^^^^ required by this bound in `use_trait_impl::assert_impl`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/abstract-const-as-cast-3.rs:17:5
|
||||
|
|
||||
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }`
|
||||
|
|
||||
= note: expected type `{ N as u128 }`
|
||||
found type `{ O as u128 }`
|
||||
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/abstract-const-as-cast-3.rs:20:5
|
||||
|
|
||||
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
|
||||
note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>`
|
||||
--> $DIR/abstract-const-as-cast-3.rs:8:22
|
||||
|
|
||||
LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
|
||||
| ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: required by a bound in `use_trait_impl::assert_impl`
|
||||
--> $DIR/abstract-const-as-cast-3.rs:14:23
|
||||
|
|
||||
LL | fn assert_impl<T: Trait>() {}
|
||||
| ^^^^^ required by this bound in `use_trait_impl::assert_impl`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/abstract-const-as-cast-3.rs:20:5
|
||||
|
|
||||
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }`
|
||||
|
|
||||
= note: expected type `{ N as _ }`
|
||||
found type `{ O as u128 }`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/abstract-const-as-cast-3.rs:23:5
|
||||
|
|
||||
LL | assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12_u128`, found `13_u128`
|
||||
|
|
||||
= note: expected type `12_u128`
|
||||
found type `13_u128`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/abstract-const-as-cast-3.rs:25:5
|
||||
|
|
||||
LL | assert_impl::<HasCastInTraitImpl<14, 13>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13_u128`, found `14_u128`
|
||||
|
|
||||
= note: expected type `13_u128`
|
||||
found type `14_u128`
|
||||
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/abstract-const-as-cast-3.rs:35:5
|
||||
|
|
||||
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
|
||||
note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>`
|
||||
--> $DIR/abstract-const-as-cast-3.rs:8:22
|
||||
|
|
||||
LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
|
||||
| ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: required by a bound in `use_trait_impl_2::assert_impl`
|
||||
--> $DIR/abstract-const-as-cast-3.rs:32:23
|
||||
|
|
||||
LL | fn assert_impl<T: Trait>() {}
|
||||
| ^^^^^ required by this bound in `use_trait_impl_2::assert_impl`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/abstract-const-as-cast-3.rs:35:5
|
||||
|
|
||||
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as u128 }`, found `{ O as u128 }`
|
||||
|
|
||||
= note: expected type `{ N as u128 }`
|
||||
found type `{ O as u128 }`
|
||||
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/abstract-const-as-cast-3.rs:38:5
|
||||
|
|
||||
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
|
||||
note: required because of the requirements on the impl of `Trait` for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>`
|
||||
--> $DIR/abstract-const-as-cast-3.rs:8:22
|
||||
|
|
||||
LL | impl<const O: usize> Trait for HasCastInTraitImpl<O, { O as u128 }> {}
|
||||
| ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: required by a bound in `use_trait_impl_2::assert_impl`
|
||||
--> $DIR/abstract-const-as-cast-3.rs:32:23
|
||||
|
|
||||
LL | fn assert_impl<T: Trait>() {}
|
||||
| ^^^^^ required by this bound in `use_trait_impl_2::assert_impl`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/abstract-const-as-cast-3.rs:38:5
|
||||
|
|
||||
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `{ N as _ }`, found `{ O as u128 }`
|
||||
|
|
||||
= note: expected type `{ N as _ }`
|
||||
found type `{ O as u128 }`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/abstract-const-as-cast-3.rs:41:5
|
||||
|
|
||||
LL | assert_impl::<HasCastInTraitImpl<13, { 12 as u128 }>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12_u128`, found `13_u128`
|
||||
|
|
||||
= note: expected type `12_u128`
|
||||
found type `13_u128`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/abstract-const-as-cast-3.rs:43:5
|
||||
|
|
||||
LL | assert_impl::<HasCastInTraitImpl<14, 13>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13_u128`, found `14_u128`
|
||||
|
|
||||
= note: expected type `13_u128`
|
||||
found type `14_u128`
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
|
@ -0,0 +1,29 @@
|
|||
// check-pass
|
||||
#![feature(generic_const_exprs, const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait Trait {}
|
||||
pub struct EvaluatableU128<const N: u128>;
|
||||
|
||||
struct HasCastInTraitImpl<const N: usize, const M: u128>;
|
||||
impl<const O: usize> 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 }>>();
|
||||
assert_impl::<HasCastInTraitImpl<13, 13>>();
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,31 @@
|
|||
// run-pass
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
pub trait BlockCipher {
|
||||
const BLOCK_SIZE: usize;
|
||||
}
|
||||
|
||||
struct FooCipher;
|
||||
impl BlockCipher for FooCipher {
|
||||
const BLOCK_SIZE: usize = 64;
|
||||
}
|
||||
|
||||
struct BarCipher;
|
||||
impl BlockCipher for BarCipher {
|
||||
const BLOCK_SIZE: usize = 32;
|
||||
}
|
||||
|
||||
pub struct Block<C>(C);
|
||||
|
||||
pub fn test<C: BlockCipher, const M: usize>()
|
||||
where
|
||||
[u8; M - C::BLOCK_SIZE]: Sized,
|
||||
{
|
||||
let _ = [0; M - C::BLOCK_SIZE];
|
||||
}
|
||||
|
||||
fn main() {
|
||||
test::<FooCipher, 128>();
|
||||
test::<BarCipher, 64>();
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
|
||||
where
|
||||
[u8; std::mem::size_of::<T>() - 1]: Sized,
|
||||
{
|
||||
[0; std::mem::size_of::<T>() - 1]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
fn test<const N: usize>() -> [u8; N + (|| 42)()] {}
|
||||
//~^ ERROR overly complex generic constant
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,12 @@
|
|||
error: overly complex generic constant
|
||||
--> $DIR/closures.rs:3:35
|
||||
|
|
||||
LL | fn test<const N: usize>() -> [u8; N + (|| 42)()] {}
|
||||
| ^^^^-------^^
|
||||
| |
|
||||
| unsupported rvalue
|
||||
|
|
||||
= help: consider moving this anonymous constant into a `const` function
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// aux-build:const_evaluatable_lib.rs
|
||||
// run-pass
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
extern crate const_evaluatable_lib;
|
||||
|
||||
fn user<T>() where [u8; std::mem::size_of::<T>() - 1]: Sized {
|
||||
assert_eq!(const_evaluatable_lib::test1::<T>(), [0; std::mem::size_of::<T>() - 1]);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(const_evaluatable_lib::test1::<u32>(), [0; 3]);
|
||||
user::<u32>();
|
||||
user::<u64>();
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
// aux-build:const_evaluatable_lib.rs
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
extern crate const_evaluatable_lib;
|
||||
|
||||
fn user<T>() {
|
||||
let _ = const_evaluatable_lib::test1::<T>();
|
||||
//~^ ERROR unconstrained generic constant
|
||||
//~| ERROR unconstrained generic constant
|
||||
//~| ERROR unconstrained generic constant
|
||||
//~| ERROR unconstrained generic constant
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,54 @@
|
|||
error: unconstrained generic constant
|
||||
--> $DIR/cross_crate_predicate.rs:7:13
|
||||
|
|
||||
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:6:10
|
||||
|
|
||||
LL | [u8; std::mem::size_of::<T>() - 1]: Sized,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
|
||||
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/cross_crate_predicate.rs:7:13
|
||||
|
|
||||
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:4:27
|
||||
|
|
||||
LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
|
||||
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/cross_crate_predicate.rs:7:13
|
||||
|
|
||||
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:6:10
|
||||
|
|
||||
LL | [u8; std::mem::size_of::<T>() - 1]: Sized,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
|
||||
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/cross_crate_predicate.rs:7:13
|
||||
|
|
||||
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:4:27
|
||||
|
|
||||
LL | pub fn test1<T>() -> [u8; std::mem::size_of::<T>() - 1]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::mem::size_of;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
struct Foo<T>(PhantomData<T>);
|
||||
|
||||
fn test<T>() -> [u8; size_of::<T>()] {
|
||||
[0; size_of::<Foo<T>>()]
|
||||
//~^ ERROR unconstrained generic constant
|
||||
//~| ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {
|
||||
test::<u32>();
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/different-fn.rs:10:5
|
||||
|
|
||||
LL | [0; size_of::<Foo<T>>()]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected `size_of::<T>()`, found `size_of::<Foo<T>>()`
|
||||
|
|
||||
= note: expected type `size_of::<T>()`
|
||||
found type `size_of::<Foo<T>>()`
|
||||
|
||||
error: unconstrained generic constant
|
||||
--> $DIR/different-fn.rs:10:9
|
||||
|
|
||||
LL | [0; size_of::<Foo<T>>()]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: try adding a `where` bound using this expression: `where [(); size_of::<Foo<T>>()]:`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
11
src/test/ui/const-generics/generic_const_exprs/division.rs
Normal file
11
src/test/ui/const-generics/generic_const_exprs/division.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// run-pass
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
fn with_bound<const N: usize>() where [u8; N / 2]: Sized {
|
||||
let _: [u8; N / 2] = [0; N / 2];
|
||||
}
|
||||
|
||||
fn main() {
|
||||
with_bound::<4>();
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
// run-pass
|
||||
#![feature(const_generics)]
|
||||
#![feature(generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
// This test is a repro for #82279. It checks that we don't error
|
||||
// when calling is_const_evaluatable on `std::mem::size_of::<T>()`
|
||||
// when looking for candidates that may prove `T: Foo` in `foo`
|
||||
|
||||
trait Foo {}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn foo<T: Foo>() {}
|
||||
|
||||
impl<T> Foo for T where [(); std::mem::size_of::<T>()]: {}
|
||||
|
||||
fn main() {}
|
16
src/test/ui/const-generics/generic_const_exprs/drop_impl.rs
Normal file
16
src/test/ui/const-generics/generic_const_exprs/drop_impl.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
//check-pass
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct Foo<const N: usize>
|
||||
where
|
||||
[(); N + 1]: ;
|
||||
|
||||
impl<const N: usize> Drop for Foo<N>
|
||||
where
|
||||
[(); N + 1]: ,
|
||||
{
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,24 @@
|
|||
// run-pass
|
||||
// Test that we use the elaborated predicates from traits
|
||||
// to satisfy const evaluatable predicates.
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
use std::mem::size_of;
|
||||
|
||||
trait Foo: Sized
|
||||
where
|
||||
[(); size_of::<Self>()]: Sized,
|
||||
{
|
||||
}
|
||||
|
||||
impl Foo for u64 {}
|
||||
impl Foo for u32 {}
|
||||
|
||||
fn foo<T: Foo>() -> [u8; size_of::<T>()] {
|
||||
[0; size_of::<T>()]
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(foo::<u32>(), [0; 4]);
|
||||
assert_eq!(foo::<u64>(), [0; 8]);
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
pub struct Const<const U: u8>;
|
||||
|
||||
pub trait Trait {
|
||||
type AssocTy;
|
||||
fn assoc_fn() -> Self::AssocTy;
|
||||
}
|
||||
|
||||
impl<const U: u8> Trait for Const<U>
|
||||
//~^ WARN private type
|
||||
//~| WARN this was previously
|
||||
//~| WARN private type
|
||||
//~| WARN this was previously
|
||||
|
||||
where
|
||||
Const<{ my_const_fn(U) }>: ,
|
||||
{
|
||||
type AssocTy = Const<{ my_const_fn(U) }>;
|
||||
//~^ ERROR private type
|
||||
fn assoc_fn() -> Self::AssocTy {
|
||||
Const
|
||||
}
|
||||
}
|
||||
|
||||
const fn my_const_fn(val: u8) -> u8 {
|
||||
// body of this function doesn't matter
|
||||
val
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
warning: private type `fn(u8) -> u8 {my_const_fn}` in public interface (error E0446)
|
||||
--> $DIR/eval-privacy.rs:12:1
|
||||
|
|
||||
LL | / impl<const U: u8> Trait for Const<U>
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
= note: `#[warn(private_in_public)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
||||
|
||||
warning: private type `fn(u8) -> u8 {my_const_fn}` in public interface (error E0446)
|
||||
--> $DIR/eval-privacy.rs:12:1
|
||||
|
|
||||
LL | / impl<const U: u8> Trait for Const<U>
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
||||
|
||||
error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
|
||||
--> $DIR/eval-privacy.rs:21:5
|
||||
|
|
||||
LL | type AssocTy = Const<{ my_const_fn(U) }>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
|
||||
...
|
||||
LL | const fn my_const_fn(val: u8) -> u8 {
|
||||
| ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
|
||||
|
||||
error: aborting due to previous error; 2 warnings emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0446`.
|
|
@ -0,0 +1,22 @@
|
|||
// check-pass
|
||||
|
||||
// We previously always returned ambiguity when equating generic consts, even if they
|
||||
// only contain generic parameters. This is incorrect as trying to unify `N > 1` with `M > 1`
|
||||
// should fail.
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
|
||||
enum Assert<const COND: bool> {}
|
||||
trait IsTrue {}
|
||||
impl IsTrue for Assert<true> {}
|
||||
|
||||
struct Foo<const N: usize, const M: usize>;
|
||||
trait Bar<const N: usize, const M: usize> {}
|
||||
impl<const N: usize, const M: usize> Bar<N, M> for Foo<N, M>
|
||||
where
|
||||
Assert<{ N > 1 }>: IsTrue,
|
||||
Assert<{ M > 1 }>: IsTrue,
|
||||
{
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,10 @@
|
|||
error: constant expression depends on a generic parameter
|
||||
--> $DIR/feature-gate-generic_const_exprs.rs:8:30
|
||||
|
|
||||
LL | fn test<const N: usize>() -> Arr<N> where Arr<N>: Default {
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: this may fail depending on what value the parameter takes
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/feature-gate-generic_const_exprs.rs:5:33
|
||||
|
|
||||
LL | type Arr<const N: usize> = [u8; N - 1];
|
||||
| ^ cannot perform const operation using `N`
|
||||
|
|
||||
= help: const parameters may only be used as standalone arguments, i.e. `N`
|
||||
= help: use `#![feature(const_generics)]` and `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// revisions: full min
|
||||
#![cfg_attr(full, feature(const_generics))]
|
||||
#![cfg_attr(full, allow(incomplete_features))]
|
||||
|
||||
type Arr<const N: usize> = [u8; N - 1];
|
||||
//[min]~^ ERROR generic parameters may not be used in const operations
|
||||
|
||||
fn test<const N: usize>() -> Arr<N> where Arr<N>: Default {
|
||||
//[full]~^ ERROR constant expression depends
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = test::<33>();
|
||||
assert_eq!(x, [0; 32]);
|
||||
}
|
30
src/test/ui/const-generics/generic_const_exprs/fn_call.rs
Normal file
30
src/test/ui/const-generics/generic_const_exprs/fn_call.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
// run-pass
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
const fn test_me<T>(a: usize, b: usize) -> usize {
|
||||
if a < b {
|
||||
std::mem::size_of::<T>()
|
||||
} else {
|
||||
usize::MAX
|
||||
}
|
||||
}
|
||||
|
||||
fn test_simple<T>() -> [u8; std::mem::size_of::<T>()]
|
||||
where
|
||||
[u8; std::mem::size_of::<T>()]: Sized,
|
||||
{
|
||||
[0; std::mem::size_of::<T>()]
|
||||
}
|
||||
|
||||
fn test_with_args<T, const N: usize>() -> [u8; test_me::<T>(N, N + 1) + N]
|
||||
where
|
||||
[u8; test_me::<T>(N, N + 1) + N]: Sized,
|
||||
{
|
||||
[0; test_me::<T>(N, N + 1) + N]
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!([0; 8], test_simple::<u64>());
|
||||
assert_eq!([0; 12], test_with_args::<u64, 4>());
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
fn test<const N: usize>() -> [u8; N - 1] {
|
||||
//~^ ERROR evaluation of `test::<0_usize>::{constant#0}` failed
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
test::<0>();
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
error[E0080]: evaluation of `test::<0_usize>::{constant#0}` failed
|
||||
--> $DIR/from-sig-fail.rs:4:35
|
||||
|
|
||||
LL | fn test<const N: usize>() -> [u8; N - 1] {
|
||||
| ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
14
src/test/ui/const-generics/generic_const_exprs/from-sig.rs
Normal file
14
src/test/ui/const-generics/generic_const_exprs/from-sig.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
// run-pass
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct Foo<const B: bool>;
|
||||
|
||||
fn test<const N: usize>() -> Foo<{ N > 10 }> {
|
||||
Foo
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _: Foo<true> = test::<12>();
|
||||
let _: Foo<false> = test::<9>();
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
// check-pass
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::mem::size_of;
|
||||
|
||||
struct Foo<T, const N: usize>(T);
|
||||
|
||||
impl<T> Foo<T, { size_of::<T>() }> {
|
||||
fn test() {
|
||||
let _: [u8; std::mem::size_of::<T>()];
|
||||
}
|
||||
}
|
||||
|
||||
trait Bar<const N: usize> {
|
||||
fn test_me();
|
||||
}
|
||||
|
||||
impl<T> Bar<{ size_of::<T>() }> for Foo<T, 3> {
|
||||
fn test_me() {
|
||||
let _: [u8; std::mem::size_of::<T>()];
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,24 @@
|
|||
// run-pass
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::{mem, ptr};
|
||||
|
||||
fn split_first<T, const N: usize>(arr: [T; N]) -> (T, [T; N - 1])
|
||||
where
|
||||
[T; N - 1]: Sized,
|
||||
{
|
||||
let arr = mem::ManuallyDrop::new(arr);
|
||||
unsafe {
|
||||
let head = ptr::read(&arr[0]);
|
||||
let tail = ptr::read(&arr[1..] as *const [T] as *const [T; N - 1]);
|
||||
(head, tail)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let arr = [0, 1, 2, 3, 4];
|
||||
let (head, tail) = split_first(arr);
|
||||
assert_eq!(head, 0);
|
||||
assert_eq!(tail, [1, 2, 3, 4]);
|
||||
}
|
14
src/test/ui/const-generics/generic_const_exprs/less_than.rs
Normal file
14
src/test/ui/const-generics/generic_const_exprs/less_than.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
// run-pass
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct Foo<const B: bool>;
|
||||
|
||||
fn test<const N: usize>() -> Foo<{ N > 10 }> where Foo<{ N > 10 }>: Sized {
|
||||
Foo
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _: Foo<true> = test::<12>();
|
||||
let _: Foo<false> = test::<9>();
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
// We do not yet want to support let-bindings in abstract consts,
|
||||
// so this test should keep failing for now.
|
||||
fn test<const N: usize>() -> [u8; { let x = N; N + 1 }] where [u8; { let x = N; N + 1 }]: Default {
|
||||
//~^ ERROR overly complex generic constant
|
||||
//~| ERROR overly complex generic constant
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = test::<31>();
|
||||
assert_eq!(x, [0; 32]);
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
error: overly complex generic constant
|
||||
--> $DIR/let-bindings.rs:6:68
|
||||
|
|
||||
LL | fn test<const N: usize>() -> [u8; { let x = N; N + 1 }] where [u8; { let x = N; N + 1 }]: Default {
|
||||
| ^^^^^^-^^^^^^^^^^^^^
|
||||
| |
|
||||
| unsupported statement
|
||||
|
|
||||
= help: consider moving this anonymous constant into a `const` function
|
||||
|
||||
error: overly complex generic constant
|
||||
--> $DIR/let-bindings.rs:6:35
|
||||
|
|
||||
LL | fn test<const N: usize>() -> [u8; { let x = N; N + 1 }] where [u8; { let x = N; N + 1 }]: Default {
|
||||
| ^^^^^^-^^^^^^^^^^^^^
|
||||
| |
|
||||
| unsupported statement
|
||||
|
|
||||
= help: consider moving this anonymous constant into a `const` function
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// run-pass
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
fn callee<const M2: usize>() -> usize
|
||||
where
|
||||
[u8; M2 + 1]: Sized,
|
||||
{
|
||||
M2
|
||||
}
|
||||
|
||||
fn caller<const N1: usize>() -> usize
|
||||
where
|
||||
[u8; N1 + 1]: Sized,
|
||||
[u8; (N1 + 1) + 1]: Sized,
|
||||
{
|
||||
callee::<{ N1 + 1 }>()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(caller::<4>(), 5);
|
||||
}
|
||||
|
||||
// Test that the ``(N1 + 1) + 1`` bound on ``caller`` satisfies the ``M2 + 1`` bound on ``callee``
|
|
@ -0,0 +1,35 @@
|
|||
// run-pass
|
||||
#![feature(generic_const_exprs, const_generics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct Generic<const K: u64>;
|
||||
|
||||
struct ConstU64<const K: u64>;
|
||||
|
||||
impl<const K: u64> Generic<K>
|
||||
where
|
||||
ConstU64<{ K - 1 }>: ,
|
||||
{
|
||||
fn foo(self) -> u64 {
|
||||
K
|
||||
}
|
||||
}
|
||||
|
||||
impl<const K: u64> Generic<K>
|
||||
where
|
||||
ConstU64<{ K - 1 }>: ,
|
||||
ConstU64<{ K + 1 }>: ,
|
||||
ConstU64<{ K + 1 - 1 }>: ,
|
||||
{
|
||||
fn bar(self) -> u64 {
|
||||
let x: Generic<{ K + 1 }> = Generic;
|
||||
x.foo()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!((Generic::<10>).bar(), 11);
|
||||
}
|
||||
|
||||
// Test that the ``ConstU64<{ K + 1 - 1}>`` bound on ``bar``'s impl block satisfies the
|
||||
// ``ConstU64<{K - 1}>`` bound on ``foo``'s impl block
|
|
@ -0,0 +1,34 @@
|
|||
// run-pass
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
fn zero_init<const N: usize>() -> Substs1<N>
|
||||
where
|
||||
[u8; N + 1]: ,
|
||||
{
|
||||
Substs1([0; N + 1])
|
||||
}
|
||||
struct Substs1<const N: usize>([u8; N + 1])
|
||||
where
|
||||
[(); N + 1]: ;
|
||||
|
||||
fn substs2<const M: usize>() -> Substs1<{ M * 2 }>
|
||||
where
|
||||
[(); { M * 2 } + 1]: ,
|
||||
{
|
||||
zero_init::<{ M * 2 }>()
|
||||
}
|
||||
|
||||
fn substs3<const L: usize>() -> Substs1<{ (L - 1) * 2 }>
|
||||
where
|
||||
[(); (L - 1) * 2 + 1]: ,
|
||||
{
|
||||
substs2::<{ L - 1 }>()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(substs3::<2>().0, [0; 3]);
|
||||
}
|
||||
|
||||
// Test that the ``{ (L - 1) * 2 + 1 }`` bound on ``substs3`` satisfies the
|
||||
// ``{ N + 1 }`` bound on ``Substs1``
|
|
@ -0,0 +1,29 @@
|
|||
// run-pass
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features, unused_parens, unused_braces)]
|
||||
|
||||
fn zero_init<const N: usize>() -> Substs1<{ (N) }>
|
||||
where
|
||||
[u8; { (N) }]: ,
|
||||
{
|
||||
Substs1([0; { (N) }])
|
||||
}
|
||||
|
||||
struct Substs1<const N: usize>([u8; { (N) }])
|
||||
where
|
||||
[(); { (N) }]: ;
|
||||
|
||||
fn substs2<const M: usize>() -> Substs1<{ (M) }> {
|
||||
zero_init::<{ (M) }>()
|
||||
}
|
||||
|
||||
fn substs3<const L: usize>() -> Substs1<{ (L) }> {
|
||||
substs2::<{ (L) }>()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(substs3::<2>().0, [0; 2]);
|
||||
}
|
||||
|
||||
// Test that the implicit ``{ (L) }`` bound on ``substs3`` satisfies the
|
||||
// ``{ (N) }`` bound on ``Substs1``
|
|
@ -0,0 +1,21 @@
|
|||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
|
||||
const fn bar<T: ?Sized>() -> usize { 7 }
|
||||
|
||||
trait Foo {
|
||||
fn test(&self) -> [u8; bar::<Self>()];
|
||||
}
|
||||
|
||||
impl Foo for () {
|
||||
fn test(&self) -> [u8; bar::<Self>()] {
|
||||
[0; bar::<Self>()]
|
||||
}
|
||||
}
|
||||
|
||||
fn use_dyn(v: &dyn Foo) { //~ERROR the trait `Foo` cannot be made into an object
|
||||
v.test();
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,18 @@
|
|||
error[E0038]: the trait `Foo` cannot be made into an object
|
||||
--> $DIR/object-safety-err-ret.rs:17:16
|
||||
|
|
||||
LL | fn use_dyn(v: &dyn Foo) {
|
||||
| ^^^^^^^ `Foo` cannot be made into an object
|
||||
|
|
||||
= help: consider moving `test` to another trait
|
||||
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $DIR/object-safety-err-ret.rs:8:23
|
||||
|
|
||||
LL | trait Foo {
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | fn test(&self) -> [u8; bar::<Self>()];
|
||||
| ^^^^^^^^^^^^^^^^^^^ ...because method `test` references the `Self` type in its return type
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
|
@ -0,0 +1,22 @@
|
|||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
#![deny(where_clauses_object_safety)]
|
||||
|
||||
|
||||
const fn bar<T: ?Sized>() -> usize { 7 }
|
||||
|
||||
trait Foo {
|
||||
fn test(&self) where [u8; bar::<Self>()]: Sized;
|
||||
//~^ ERROR the trait `Foo` cannot be made into an object
|
||||
//~| WARN this was previously accepted by the compiler but is being phased out
|
||||
}
|
||||
|
||||
impl Foo for () {
|
||||
fn test(&self) where [u8; bar::<Self>()]: Sized {}
|
||||
}
|
||||
|
||||
fn use_dyn(v: &dyn Foo) {
|
||||
v.test();
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,24 @@
|
|||
error: the trait `Foo` cannot be made into an object
|
||||
--> $DIR/object-safety-err-where-bounds.rs:9:8
|
||||
|
|
||||
LL | fn test(&self) where [u8; bar::<Self>()]: Sized;
|
||||
| ^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/object-safety-err-where-bounds.rs:3:9
|
||||
|
|
||||
LL | #![deny(where_clauses_object_safety)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #51443 <https://github.com/rust-lang/rust/issues/51443>
|
||||
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $DIR/object-safety-err-where-bounds.rs:9:8
|
||||
|
|
||||
LL | trait Foo {
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | fn test(&self) where [u8; bar::<Self>()]: Sized;
|
||||
| ^^^^ ...because method `test` references the `Self` type in its `where` clause
|
||||
= help: consider moving `test` to another trait
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait Foo<const N: usize> {
|
||||
fn test(&self) -> [u8; N + 1];
|
||||
}
|
||||
|
||||
impl<const N: usize> Foo<N> for () {
|
||||
fn test(&self) -> [u8; N + 1] {
|
||||
[0; N + 1]
|
||||
}
|
||||
}
|
||||
|
||||
fn use_dyn<const N: usize>(v: &dyn Foo<N>) where [u8; N + 1]: Sized {
|
||||
assert_eq!(v.test(), [0; N + 1]);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// FIXME(generic_const_exprs): Improve the error message here.
|
||||
use_dyn(&());
|
||||
//~^ ERROR type annotations needed
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
error[E0284]: type annotations needed: cannot satisfy `the constant `use_dyn::<{_: usize}>::{constant#0}` can be evaluated`
|
||||
--> $DIR/object-safety-ok-infer-err.rs:20:5
|
||||
|
|
||||
LL | use_dyn(&());
|
||||
| ^^^^^^^ cannot satisfy `the constant `use_dyn::<{_: usize}>::{constant#0}` can be evaluated`
|
||||
|
|
||||
note: required by a bound in `use_dyn`
|
||||
--> $DIR/object-safety-ok-infer-err.rs:14:55
|
||||
|
|
||||
LL | fn use_dyn<const N: usize>(v: &dyn Foo<N>) where [u8; N + 1]: Sized {
|
||||
| ^^^^^ required by this bound in `use_dyn`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0284`.
|
|
@ -0,0 +1,21 @@
|
|||
// run-pass
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait Foo<const N: usize> {
|
||||
fn test(&self) -> [u8; N + 1];
|
||||
}
|
||||
|
||||
impl<const N: usize> Foo<N> for () {
|
||||
fn test(&self) -> [u8; N + 1] {
|
||||
[0; N + 1]
|
||||
}
|
||||
}
|
||||
|
||||
fn use_dyn<const N: usize>(v: &dyn Foo<N>) where [u8; N + 1]: Sized {
|
||||
assert_eq!(v.test(), [0; N + 1]);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
use_dyn::<3>(&());
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
error[E0080]: evaluation of `test::<0_usize>::{constant#0}` failed
|
||||
--> $DIR/simple_fail.rs:10:48
|
||||
|
|
||||
LL | fn test<const N: usize>() -> Arr<N> where [u8; N - 1]: Sized {
|
||||
| ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow
|
||||
|
||||
error[E0080]: evaluation of `Arr::<0_usize>::{constant#0}` failed
|
||||
--> $DIR/simple_fail.rs:6:33
|
||||
|
|
||||
LL | type Arr<const N: usize> = [u8; N - 1];
|
||||
| ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
|
@ -0,0 +1,20 @@
|
|||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/simple_fail.rs:6:33
|
||||
|
|
||||
LL | type Arr<const N: usize> = [u8; N - 1];
|
||||
| ^ cannot perform const operation using `N`
|
||||
|
|
||||
= help: const parameters may only be used as standalone arguments, i.e. `N`
|
||||
= help: use `#![feature(const_generics)]` and `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/simple_fail.rs:10:48
|
||||
|
|
||||
LL | fn test<const N: usize>() -> Arr<N> where [u8; N - 1]: Sized {
|
||||
| ^ cannot perform const operation using `N`
|
||||
|
|
||||
= help: const parameters may only be used as standalone arguments, i.e. `N`
|
||||
= help: use `#![feature(const_generics)]` and `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
// revisions: full min
|
||||
#![cfg_attr(full, feature(const_generics))]
|
||||
#![cfg_attr(full, feature(generic_const_exprs))]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
type Arr<const N: usize> = [u8; N - 1];
|
||||
//[min]~^ ERROR generic parameters may not be used in const operations
|
||||
//[full]~^^ ERROR evaluation of `Arr::<0_usize>::{constant#0}` failed
|
||||
|
||||
fn test<const N: usize>() -> Arr<N> where [u8; N - 1]: Sized {
|
||||
//[min]~^ ERROR generic parameters may not be used in const operations
|
||||
//[full]~^^ ERROR evaluation of `test::<0_usize>::{constant#0}` failed
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
test::<0>();
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
// run-pass
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
fn make_array<const M: usize>() -> [(); M + 1] {
|
||||
[(); M + 1]
|
||||
}
|
||||
|
||||
fn foo<const N: usize>() -> [(); (N * 2) + 1] {
|
||||
make_array::<{ N * 2 }>()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(foo::<10>(), [(); 10 * 2 + 1])
|
||||
}
|
||||
|
||||
// Tests that N * 2 is considered const_evalutable by appearing as part of the (N * 2) + 1 const
|
|
@ -0,0 +1,14 @@
|
|||
// check-pass
|
||||
// Test that we correctly substitute generic arguments for type aliases.
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
type Alias<T, const N: usize> = [T; N + 1];
|
||||
|
||||
fn foo<const M: usize>() -> Alias<u32, M> where [u8; M + 1]: Sized {
|
||||
[0; M + 1]
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo::<0>();
|
||||
}
|
14
src/test/ui/const-generics/generic_const_exprs/unop.rs
Normal file
14
src/test/ui/const-generics/generic_const_exprs/unop.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
// run-pass
|
||||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct Foo<const B: bool>;
|
||||
|
||||
fn test<const N: usize>() -> Foo<{ !(N > 10) }> where Foo<{ !(N > 10) }>: Sized {
|
||||
Foo
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _: Foo<false> = test::<12>();
|
||||
let _: Foo<true> = test::<9>();
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
// check-pass
|
||||
#![feature(const_generics, generic_const_exprs, const_generics_defaults)]
|
||||
#![allow(incomplete_features)]
|
||||
struct Foo<const N: usize, const M: usize = { N + 1 }>;
|
||||
struct Bar<const N: usize>(Foo<N, 3>);
|
||||
fn main() {}
|
|
@ -0,0 +1,25 @@
|
|||
#![feature(const_generics, generic_const_exprs)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
fn add<const N: usize>() -> [u8; { N + 1; 5 }] {
|
||||
//~^ ERROR overly complex generic constant
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn div<const N: usize>() -> [u8; { N / 1; 5 }] {
|
||||
//~^ ERROR overly complex generic constant
|
||||
todo!()
|
||||
}
|
||||
|
||||
const fn foo(n: usize) {}
|
||||
|
||||
fn fn_call<const N: usize>() -> [u8; { foo(N); 5 }] {
|
||||
//~^ ERROR overly complex generic constant
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
add::<12>();
|
||||
div::<9>();
|
||||
fn_call::<14>();
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
error: overly complex generic constant
|
||||
--> $DIR/unused_expr.rs:4:34
|
||||
|
|
||||
LL | fn add<const N: usize>() -> [u8; { N + 1; 5 }] {
|
||||
| ^^-----^^^^^
|
||||
| |
|
||||
| dead code
|
||||
|
|
||||
= help: consider moving this anonymous constant into a `const` function
|
||||
|
||||
error: overly complex generic constant
|
||||
--> $DIR/unused_expr.rs:9:34
|
||||
|
|
||||
LL | fn div<const N: usize>() -> [u8; { N / 1; 5 }] {
|
||||
| ^^-----^^^^^
|
||||
| |
|
||||
| dead code
|
||||
|
|
||||
= help: consider moving this anonymous constant into a `const` function
|
||||
|
||||
error: overly complex generic constant
|
||||
--> $DIR/unused_expr.rs:16:38
|
||||
|
|
||||
LL | fn fn_call<const N: usize>() -> [u8; { foo(N); 5 }] {
|
||||
| ^^------^^^^^
|
||||
| |
|
||||
| dead code
|
||||
|
|
||||
= help: consider moving this anonymous constant into a `const` function
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue