1
Fork 0

rename const_evaluatable_checked to generic_const_exprs

This commit is contained in:
Ellen 2021-08-25 10:21:39 +01:00 committed by lcnr
parent dbb0fe9d80
commit fcc2badf9b
146 changed files with 178 additions and 213 deletions

View file

@ -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() {}

View file

@ -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() {}

View file

@ -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

View file

@ -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() {}

View file

@ -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`.

View file

@ -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() {}

View file

@ -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>();
}

View file

@ -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]
}

View file

@ -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() {}

View file

@ -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

View file

@ -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>();
}

View file

@ -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() {}

View file

@ -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

View file

@ -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>();
}

View file

@ -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`.

View 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>();
}

View file

@ -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() {}

View 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() {}

View file

@ -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]);
}

View file

@ -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
}

View file

@ -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`.

View file

@ -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() {}

View file

@ -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

View file

@ -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

View file

@ -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]);
}

View 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>());
}

View file

@ -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>();
}

View file

@ -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`.

View 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>();
}

View file

@ -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() {}

View file

@ -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]);
}

View 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>();
}

View file

@ -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]);
}

View file

@ -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

View file

@ -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``

View file

@ -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

View file

@ -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``

View file

@ -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``

View file

@ -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() {}

View file

@ -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`.

View file

@ -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() {}

View file

@ -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

View file

@ -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
}

View file

@ -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`.

View file

@ -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>(&());
}

View file

@ -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`.

View file

@ -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

View file

@ -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>();
}

View file

@ -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

View file

@ -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>();
}

View 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>();
}

View file

@ -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() {}

View file

@ -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>();
}

View file

@ -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