Rollup merge of #77303 - lcnr:const-evaluatable-TooGeneric, r=oli-obk,varkor

const evaluatable: improve `TooGeneric` handling

Instead of emitting an error in `fulfill`, we now correctly stall on inference variables.

As `const_eval_resolve` returns `ErrorHandled::TooGeneric` when encountering generic parameters on which
we actually do want to error, we check for inference variables and eagerly emit an error if they don't exist, returning `ErrorHandled::Reported` instead.

Also contains a small bugfix for `ConstEquate` where we previously only stalled on type variables. This is probably a leftover from
when we did not yet support stalling on const inference variables.

r? @oli-obk cc @varkor @eddyb
This commit is contained in:
Dylan DPC 2020-10-01 02:13:35 +02:00 committed by GitHub
commit f23559451b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 199 additions and 75 deletions

View file

@ -5,10 +5,10 @@ extern crate const_evaluatable_lib;
fn user<T>() {
let _ = const_evaluatable_lib::test1::<T>();
//~^ ERROR constant expression depends
//~| ERROR constant expression depends
//~| ERROR constant expression depends
//~| ERROR constant expression depends
//~^ ERROR unconstrained generic constant
//~| ERROR unconstrained generic constant
//~| ERROR unconstrained generic constant
//~| ERROR unconstrained generic constant
}
fn main() {}

View file

@ -1,54 +1,50 @@
error: constant expression depends on a generic parameter
error: unconstrained generic constant
--> $DIR/cross_crate_predicate.rs:7:13
|
LL | let _ = const_evaluatable_lib::test1::<T>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
::: $DIR/auxiliary/const_evaluatable_lib.rs:6:10
|
help: consider adding a `where` bound for this expression
--> $DIR/auxiliary/const_evaluatable_lib.rs:6:10
|
LL | [u8; std::mem::size_of::<T>() - 1]: Sized,
| ---------------------------- 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
error: unconstrained generic constant
--> $DIR/cross_crate_predicate.rs:7:13
|
LL | let _ = const_evaluatable_lib::test1::<T>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
::: $DIR/auxiliary/const_evaluatable_lib.rs:4:27
|
help: consider adding a `where` bound for this expression
--> $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: constant expression depends on a generic parameter
error: unconstrained generic constant
--> $DIR/cross_crate_predicate.rs:7:13
|
LL | let _ = const_evaluatable_lib::test1::<T>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
::: $DIR/auxiliary/const_evaluatable_lib.rs:6:10
|
help: consider adding a `where` bound for this expression
--> $DIR/auxiliary/const_evaluatable_lib.rs:6:10
|
LL | [u8; std::mem::size_of::<T>() - 1]: Sized,
| ---------------------------- 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
error: unconstrained generic constant
--> $DIR/cross_crate_predicate.rs:7:13
|
LL | let _ = const_evaluatable_lib::test1::<T>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
::: $DIR/auxiliary/const_evaluatable_lib.rs:4:27
|
help: consider adding a `where` bound for this expression
--> $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 4 previous errors

View file

@ -0,0 +1,24 @@
// run-pass
#![feature(const_generics, const_evaluatable_checked)]
#![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

@ -14,5 +14,4 @@ fn test<T, const P: usize>() where Bool<{core::mem::size_of::<T>() > 4}>: True {
fn main() {
test::<2>();
//~^ ERROR wrong number of type
//~| ERROR constant expression depends
}

View file

@ -4,17 +4,6 @@ error[E0107]: wrong number of type arguments: expected 1, found 0
LL | test::<2>();
| ^^^^^^^^^ expected 1 type argument
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`
...
LL | test::<2>();
| ^^^^^^^^^
|
= note: this may fail depending on what value the parameter takes
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0107`.