Clean up
Simplify match statement Add multiple tests - 1 test for checking `N + 1 + 1` does not unify with `N+1` - 2 tests for checking that a function that uses two parameters only returns the parameter that is actually used. - Check exact repeat predicates
This commit is contained in:
parent
7c5cb73735
commit
21c5ffe008
8 changed files with 133 additions and 25 deletions
|
@ -186,8 +186,9 @@ fn satisfied_from_param_env<'tcx>(
|
||||||
Some(Ok(o)) if o == c => Some(Ok(c)),
|
Some(Ok(o)) if o == c => Some(Ok(c)),
|
||||||
Some(_) => Some(Err(())),
|
Some(_) => Some(Err(())),
|
||||||
};
|
};
|
||||||
ControlFlow::CONTINUE
|
}
|
||||||
} else if let ty::ConstKind::Expr(e) = c.kind() {
|
|
||||||
|
if let ty::ConstKind::Expr(e) = c.kind() {
|
||||||
e.visit_with(self)
|
e.visit_with(self)
|
||||||
} else {
|
} else {
|
||||||
// FIXME(generic_const_exprs): This doesn't recurse into `<T as Trait<U>>::ASSOC`'s substs.
|
// FIXME(generic_const_exprs): This doesn't recurse into `<T as Trait<U>>::ASSOC`'s substs.
|
||||||
|
@ -208,35 +209,20 @@ fn satisfied_from_param_env<'tcx>(
|
||||||
match pred.kind().skip_binder() {
|
match pred.kind().skip_binder() {
|
||||||
ty::PredicateKind::ConstEvaluatable(ce) => {
|
ty::PredicateKind::ConstEvaluatable(ce) => {
|
||||||
let b_ct = tcx.expand_abstract_consts(ce);
|
let b_ct = tcx.expand_abstract_consts(ce);
|
||||||
let mut v = Visitor { ct, infcx, param_env, single_match: None };
|
let mut v = Visitor { ct, infcx, param_env, single_match };
|
||||||
let _ = b_ct.visit_with(&mut v);
|
let _ = b_ct.visit_with(&mut v);
|
||||||
|
|
||||||
if let Some(inner) = v.single_match {
|
single_match = v.single_match;
|
||||||
single_match = if let Ok(inner) = inner {
|
|
||||||
match single_match {
|
|
||||||
None => Some(Ok(inner)),
|
|
||||||
Some(Ok(prev)) if prev == inner => Some(Ok(prev)),
|
|
||||||
Some(_) => Some(Err(())),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Some(Err(()))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {} // don't care
|
_ => {} // don't care
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(Ok(c)) = single_match {
|
if let Some(Ok(c)) = single_match {
|
||||||
let is_ok = infcx
|
let ocx = ObligationCtxt::new(infcx);
|
||||||
.commit_if_ok(|_| {
|
|
||||||
let ocx = ObligationCtxt::new_in_snapshot(infcx);
|
|
||||||
assert!(ocx.eq(&ObligationCause::dummy(), param_env, c.ty(), ct.ty()).is_ok());
|
assert!(ocx.eq(&ObligationCause::dummy(), param_env, c.ty(), ct.ty()).is_ok());
|
||||||
assert!(ocx.eq(&ObligationCause::dummy(), param_env, c, ct).is_ok());
|
assert!(ocx.eq(&ObligationCause::dummy(), param_env, c, ct).is_ok());
|
||||||
if ocx.select_all_or_error().is_empty() { Ok(()) } else { Err(()) }
|
assert!(ocx.select_all_or_error().is_empty());
|
||||||
})
|
|
||||||
.is_ok();
|
|
||||||
assert!(is_ok);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
src/test/ui/const-generics/fn_with_two_const_inputs.rs
Normal file
23
src/test/ui/const-generics/fn_with_two_const_inputs.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#![feature(generic_const_exprs)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
const fn both(_: usize, b: usize) -> usize {
|
||||||
|
b
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo<const N: usize, const M: usize>() -> [(); N + 2]
|
||||||
|
where
|
||||||
|
[(); both(N + 1, M + 1)]:,
|
||||||
|
{
|
||||||
|
bar()
|
||||||
|
//~^ ERROR: unconstrained generic constant
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar<const N: usize>() -> [(); N]
|
||||||
|
where
|
||||||
|
[(); N + 1]:,
|
||||||
|
{
|
||||||
|
[(); N]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
18
src/test/ui/const-generics/fn_with_two_const_inputs.stderr
Normal file
18
src/test/ui/const-generics/fn_with_two_const_inputs.stderr
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
error: unconstrained generic constant
|
||||||
|
--> $DIR/fn_with_two_const_inputs.rs:12:5
|
||||||
|
|
|
||||||
|
LL | bar()
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
= help: try adding a `where` bound using this expression: `where [(); N + 1]:`
|
||||||
|
note: required by a bound in `bar`
|
||||||
|
--> $DIR/fn_with_two_const_inputs.rs:18:10
|
||||||
|
|
|
||||||
|
LL | fn bar<const N: usize>() -> [(); N]
|
||||||
|
| --- required by a bound in this
|
||||||
|
LL | where
|
||||||
|
LL | [(); N + 1]:,
|
||||||
|
| ^^^^^ required by this bound in `bar`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
22
src/test/ui/const-generics/fn_with_two_same_const_inputs.rs
Normal file
22
src/test/ui/const-generics/fn_with_two_same_const_inputs.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// check-pass
|
||||||
|
#![feature(generic_const_exprs)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
const fn both(_: usize, b: usize) -> usize {
|
||||||
|
b
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo<const N: usize>()
|
||||||
|
where
|
||||||
|
[(); both(N + 1, N + 1)]:,
|
||||||
|
{
|
||||||
|
bar::<N>();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar<const N: usize>()
|
||||||
|
where
|
||||||
|
[(); N + 1]:,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -15,8 +15,8 @@ where
|
||||||
[(); (L - 1) + 1 + L]:,
|
[(); (L - 1) + 1 + L]:,
|
||||||
{
|
{
|
||||||
foo::<_, L>([(); L + 1 + L]);
|
foo::<_, L>([(); L + 1 + L]);
|
||||||
//~^ ERROR: unconstrained generic constant
|
//~^ ERROR: mismatched types
|
||||||
//~| ERROR: mismatched types
|
//~^^ ERROR: unconstrained generic constant
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
19
src/test/ui/const-generics/two_matching_preds.rs
Normal file
19
src/test/ui/const-generics/two_matching_preds.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// check-pass
|
||||||
|
#![feature(generic_const_exprs)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
fn foo<const N: usize>()
|
||||||
|
where
|
||||||
|
[(); N + 1]:,
|
||||||
|
[(); N + 1]:,
|
||||||
|
{
|
||||||
|
bar::<N>();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar<const N: usize>()
|
||||||
|
where
|
||||||
|
[(); N + 1]:,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
18
src/test/ui/const-generics/unify_with_nested_expr.rs
Normal file
18
src/test/ui/const-generics/unify_with_nested_expr.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#![feature(generic_const_exprs)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
fn foo<const N: usize>()
|
||||||
|
where
|
||||||
|
[(); N + 1 + 1]:,
|
||||||
|
{
|
||||||
|
bar();
|
||||||
|
//~^ ERROR: type annotations
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar<const N: usize>()
|
||||||
|
where
|
||||||
|
[(); N + 1]:,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
22
src/test/ui/const-generics/unify_with_nested_expr.stderr
Normal file
22
src/test/ui/const-generics/unify_with_nested_expr.stderr
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
error[E0284]: type annotations needed
|
||||||
|
--> $DIR/unify_with_nested_expr.rs:8:5
|
||||||
|
|
|
||||||
|
LL | bar();
|
||||||
|
| ^^^ cannot infer the value of the const parameter `N` declared on the function `bar`
|
||||||
|
|
|
||||||
|
note: required by a bound in `bar`
|
||||||
|
--> $DIR/unify_with_nested_expr.rs:14:10
|
||||||
|
|
|
||||||
|
LL | fn bar<const N: usize>()
|
||||||
|
| --- required by a bound in this
|
||||||
|
LL | where
|
||||||
|
LL | [(); N + 1]:,
|
||||||
|
| ^^^^^ required by this bound in `bar`
|
||||||
|
help: consider specifying the generic argument
|
||||||
|
|
|
||||||
|
LL | bar::<N>();
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0284`.
|
Loading…
Add table
Add a link
Reference in a new issue