about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-09-24 10:29:14 +0000
committerbors <bors@rust-lang.org>2020-09-24 10:29:14 +0000
commit3a4da87f58099f08620a9a3e812abd77301cafb2 (patch)
tree6159733c14fd9c85f9ba72955c7cdf0768a0c61f /src
parent86b4172305bb28612510db9ad3ebf2a4bb86f70f (diff)
parent21edd10dc5ae8cde041f84a38fd0c4a44a36965d (diff)
downloadrust-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')
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.rs1
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/cross_crate_predicate.stderr28
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/from-sig-fail.rs11
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/from-sig-fail.stderr9
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/from-sig.rs14
-rw-r--r--src/test/ui/const-generics/const_evaluatable_checked/impl-bounds.rs25
-rw-r--r--src/test/ui/const-generics/issues/issue-76595.stderr2
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>();
    |     ^^^^^^^^^