Skip to content

Commit

Permalink
Clean up
Browse files Browse the repository at this point in the history
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
  • Loading branch information
JulianKnodt committed Jan 9, 2023
1 parent 7c5cb73 commit 21c5ffe
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 25 deletions.
32 changes: 9 additions & 23 deletions compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,9 @@ fn satisfied_from_param_env<'tcx>(
Some(Ok(o)) if o == c => Some(Ok(c)),
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)
} else {
// FIXME(generic_const_exprs): This doesn't recurse into `<T as Trait<U>>::ASSOC`'s substs.
Expand All @@ -208,35 +209,20 @@ fn satisfied_from_param_env<'tcx>(
match pred.kind().skip_binder() {
ty::PredicateKind::ConstEvaluatable(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);

if let Some(inner) = 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(()))
};
}
single_match = v.single_match;
}
_ => {} // don't care
}
}

if let Some(Ok(c)) = single_match {
let is_ok = 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, ct).is_ok());
if ocx.select_all_or_error().is_empty() { Ok(()) } else { Err(()) }
})
.is_ok();
assert!(is_ok);
let ocx = ObligationCtxt::new(infcx);
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.select_all_or_error().is_empty());
return true;
}

Expand Down
23 changes: 23 additions & 0 deletions src/test/ui/const-generics/fn_with_two_const_inputs.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions src/test/ui/const-generics/fn_with_two_const_inputs.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 22 additions & 0 deletions src/test/ui/const-generics/fn_with_two_same_const_inputs.rs
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ where
[(); (L - 1) + 1 + L]:,
{
foo::<_, L>([(); L + 1 + L]);
//~^ ERROR: unconstrained generic constant
//~| ERROR: mismatched types
//~^ ERROR: mismatched types
//~^^ ERROR: unconstrained generic constant
}

fn main() {}
19 changes: 19 additions & 0 deletions src/test/ui/const-generics/two_matching_preds.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions src/test/ui/const-generics/unify_with_nested_expr.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 22 additions & 0 deletions src/test/ui/const-generics/unify_with_nested_expr.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 21c5ffe

Please sign in to comment.