diff options
| author | bors <bors@rust-lang.org> | 2020-09-24 10:29:14 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-09-24 10:29:14 +0000 |
| commit | 3a4da87f58099f08620a9a3e812abd77301cafb2 (patch) | |
| tree | 6159733c14fd9c85f9ba72955c7cdf0768a0c61f /src | |
| parent | 86b4172305bb28612510db9ad3ebf2a4bb86f70f (diff) | |
| parent | 21edd10dc5ae8cde041f84a38fd0c4a44a36965d (diff) | |
| download | rust-3a4da87f58099f08620a9a3e812abd77301cafb2.tar.gz rust-3a4da87f58099f08620a9a3e812abd77301cafb2.zip | |
Auto merge of #77049 - lcnr:const-eval-function-signature, r=oli-obk
const_evaluatable_checked: extend predicate collection
We now walk the hir instead of using `ty` so that we get better spans here, While I am still not completely sure if that's
what we want in the end, it does seem a lot closer to the final goal than the previous version.
We also look into type aliases (and use a `TypeVisitor` here), about which I am not completely sure, but we will see how well this works.
We also look into fn decls, so the following should work now.
```rust
fn test<T>() -> [u8; std::mem::size_of::<T>()] {
[0; std::mem::size_of::<T>()]
}
```
Additionally, we visit the optional trait and self type of impls.
r? `@oli-obk`
Diffstat (limited to 'src')
7 files changed, 84 insertions, 6 deletions
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.rs b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.rs index 22369923329..52b89cfa045 100644 --- a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.rs +++ b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.rs @@ -8,6 +8,7 @@ fn user<T>() { //~^ ERROR constant expression depends //~| ERROR constant expression depends //~| ERROR constant expression depends + //~| ERROR constant expression depends } fn main() {} diff --git a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr index 63abb782b93..4af68118be3 100644 --- a/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr +++ b/src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr @@ -4,10 +4,23 @@ error: constant expression depends on a generic parameter LL | let _ = const_evaluatable_lib::test1::<T>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - ::: $DIR/auxiliary/const_evaluatable_lib.rs:6:41 + ::: $DIR/auxiliary/const_evaluatable_lib.rs:6:10 | LL | [u8; std::mem::size_of::<T>() - 1]: Sized, - | ----- required by this bound in `test1` + | ---------------------------- required by this bound in `test1` + | + = note: this may fail depending on what value the parameter takes + +error: constant expression depends on a generic parameter + --> $DIR/cross_crate_predicate.rs:7:13 + | +LL | let _ = const_evaluatable_lib::test1::<T>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + ::: $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` | = note: this may fail depending on what value the parameter takes @@ -17,10 +30,10 @@ error: constant expression depends on a generic parameter LL | let _ = const_evaluatable_lib::test1::<T>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - ::: $DIR/auxiliary/const_evaluatable_lib.rs:6:41 + ::: $DIR/auxiliary/const_evaluatable_lib.rs:6:10 | LL | [u8; std::mem::size_of::<T>() - 1]: Sized, - | ----- required by this bound in `test1::{{constant}}#1` + | ---------------------------- required by this bound in `test1` | = note: this may fail depending on what value the parameter takes @@ -29,8 +42,13 @@ error: constant expression depends on a generic parameter | LL | let _ = const_evaluatable_lib::test1::<T>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + ::: $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` | = note: this may fail depending on what value the parameter takes -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors diff --git a/src/test/ui/const-generics/const_evaluatable_checked/from-sig-fail.rs b/src/test/ui/const-generics/const_evaluatable_checked/from-sig-fail.rs new file mode 100644 index 00000000000..3da4688702c --- /dev/null +++ b/src/test/ui/const-generics/const_evaluatable_checked/from-sig-fail.rs @@ -0,0 +1,11 @@ +#![feature(const_generics, const_evaluatable_checked)] +#![allow(incomplete_features)] + +fn test<const N: usize>() -> [u8; N - 1] { + //~^ ERROR evaluation of constant + todo!() +} + +fn main() { + test::<0>(); +} diff --git a/src/test/ui/const-generics/const_evaluatable_checked/from-sig-fail.stderr b/src/test/ui/const-generics/const_evaluatable_checked/from-sig-fail.stderr new file mode 100644 index 00000000000..a5acfec34aa --- /dev/null +++ b/src/test/ui/const-generics/const_evaluatable_checked/from-sig-fail.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation of constant value 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`. diff --git a/src/test/ui/const-generics/const_evaluatable_checked/from-sig.rs b/src/test/ui/const-generics/const_evaluatable_checked/from-sig.rs new file mode 100644 index 00000000000..5c05a5acfe9 --- /dev/null +++ b/src/test/ui/const-generics/const_evaluatable_checked/from-sig.rs @@ -0,0 +1,14 @@ +// run-pass +#![feature(const_generics, const_evaluatable_checked)] +#![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>(); +} diff --git a/src/test/ui/const-generics/const_evaluatable_checked/impl-bounds.rs b/src/test/ui/const-generics/const_evaluatable_checked/impl-bounds.rs new file mode 100644 index 00000000000..193a365f9b6 --- /dev/null +++ b/src/test/ui/const-generics/const_evaluatable_checked/impl-bounds.rs @@ -0,0 +1,25 @@ +// check-pass +#![feature(const_generics, const_evaluatable_checked)] +#![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() {} diff --git a/src/test/ui/const-generics/issues/issue-76595.stderr b/src/test/ui/const-generics/issues/issue-76595.stderr index 2e457595393..bbc81693fc0 100644 --- a/src/test/ui/const-generics/issues/issue-76595.stderr +++ b/src/test/ui/const-generics/issues/issue-76595.stderr @@ -8,7 +8,7 @@ error: constant expression depends on a generic parameter --> $DIR/issue-76595.rs:15:5 | LL | fn test<T, const P: usize>() where Bool<{core::mem::size_of::<T>() > 4}>: True { - | ---- required by this bound in `test` + | ------------------------------- required by this bound in `test` ... LL | test::<2>(); | ^^^^^^^^^ |
