Skip to content

Commit 7996908

Browse files
authored
Rollup merge of #113324 - lcnr:const-evaluatable-goal, r=BoxyUwU
implement `ConstEvaluatable` goals in new solver this only supports stable const generics. `feature(generic_const_exprs)` needs to extend that function is non-trivial ways. Leaving this for someone else or some later date. r? `@BoxyUwU`
2 parents 494e67c + abcaf30 commit 7996908

8 files changed

+75
-9
lines changed

compiler/rustc_trait_selection/src/solve/eval_ctxt.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -441,12 +441,8 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
441441
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
442442
self.compute_well_formed_goal(Goal { param_env, predicate: arg })
443443
}
444-
ty::PredicateKind::Ambiguous => {
445-
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
446-
}
447-
// FIXME: implement this predicate :)
448-
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(_)) => {
449-
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
444+
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(ct)) => {
445+
self.compute_const_evaluatable_goal(Goal { param_env, predicate: ct })
450446
}
451447
ty::PredicateKind::ConstEquate(_, _) => {
452448
bug!("ConstEquate should not be emitted when `-Ztrait-solver=next` is active")
@@ -456,6 +452,9 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
456452
param_env,
457453
predicate: (lhs, rhs, direction),
458454
}),
455+
ty::PredicateKind::Ambiguous => {
456+
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
457+
}
459458
}
460459
} else {
461460
let kind = self.infcx.instantiate_binder_with_placeholders(kind);

compiler/rustc_trait_selection/src/solve/mod.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,43 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
161161
}
162162
}
163163

164+
#[instrument(level = "debug", skip(self))]
165+
fn compute_const_evaluatable_goal(
166+
&mut self,
167+
Goal { param_env, predicate: ct }: Goal<'tcx, ty::Const<'tcx>>,
168+
) -> QueryResult<'tcx> {
169+
match ct.kind() {
170+
ty::ConstKind::Unevaluated(uv) => {
171+
// We never return `NoSolution` here as `try_const_eval_resolve` emits an
172+
// error itself when failing to evaluate, so emitting an additional fulfillment
173+
// error in that case is unnecessary noise. This may change in the future once
174+
// evaluation failures are allowed to impact selection, e.g. generic const
175+
// expressions in impl headers or `where`-clauses.
176+
177+
// FIXME(generic_const_exprs): Implement handling for generic
178+
// const expressions here.
179+
if let Some(_normalized) = self.try_const_eval_resolve(param_env, uv, ct.ty()) {
180+
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
181+
} else {
182+
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
183+
}
184+
}
185+
ty::ConstKind::Infer(_) => {
186+
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
187+
}
188+
ty::ConstKind::Placeholder(_) | ty::ConstKind::Value(_) | ty::ConstKind::Error(_) => {
189+
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
190+
}
191+
// We can freely ICE here as:
192+
// - `Param` gets replaced with a placeholder during canonicalization
193+
// - `Bound` cannot exist as we don't have a binder around the self Type
194+
// - `Expr` is part of `feature(generic_const_exprs)` and is not implemented yet
195+
ty::ConstKind::Param(_) | ty::ConstKind::Bound(_, _) | ty::ConstKind::Expr(_) => {
196+
bug!("unexpect const kind: {:?}", ct)
197+
}
198+
}
199+
}
200+
164201
#[instrument(level = "debug", skip(self), ret)]
165202
fn compute_const_arg_has_type_goal(
166203
&mut self,

tests/ui/const-generics/defaults/default-param-wf-concrete.stderr renamed to tests/ui/const-generics/defaults/default-param-wf-concrete.next.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0080]: evaluation of constant value failed
2-
--> $DIR/default-param-wf-concrete.rs:1:28
2+
--> $DIR/default-param-wf-concrete.rs:4:28
33
|
44
LL | struct Foo<const N: u8 = { 255 + 1 }>;
55
| ^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0080]: evaluation of constant value failed
2+
--> $DIR/default-param-wf-concrete.rs:4:28
3+
|
4+
LL | struct Foo<const N: u8 = { 255 + 1 }>;
5+
| ^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0080`.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// revisions: old next
2+
//[next] compile-flags: -Ztrait-solver=next
3+
14
struct Foo<const N: u8 = { 255 + 1 }>;
25
//~^ ERROR evaluation of constant value failed
36
fn main() {}

tests/ui/consts/const-len-underflow-separate-spans.stderr renamed to tests/ui/consts/const-len-underflow-separate-spans.next.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0080]: evaluation of constant value failed
2-
--> $DIR/const-len-underflow-separate-spans.rs:7:20
2+
--> $DIR/const-len-underflow-separate-spans.rs:10:20
33
|
44
LL | const LEN: usize = ONE - TWO;
55
| ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow
66

77
note: erroneous constant used
8-
--> $DIR/const-len-underflow-separate-spans.rs:11:17
8+
--> $DIR/const-len-underflow-separate-spans.rs:14:17
99
|
1010
LL | let a: [i8; LEN] = unimplemented!();
1111
| ^^^
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0080]: evaluation of constant value failed
2+
--> $DIR/const-len-underflow-separate-spans.rs:10:20
3+
|
4+
LL | const LEN: usize = ONE - TWO;
5+
| ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow
6+
7+
note: erroneous constant used
8+
--> $DIR/const-len-underflow-separate-spans.rs:14:17
9+
|
10+
LL | let a: [i8; LEN] = unimplemented!();
11+
| ^^^
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0080`.

tests/ui/consts/const-len-underflow-separate-spans.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// spot (where the underflow occurred), while also providing the
33
// overall context for what caused the evaluation.
44

5+
// revisions: old next
6+
//[next] compile-flags: -Ztrait-solver=next
7+
58
const ONE: usize = 1;
69
const TWO: usize = 2;
710
const LEN: usize = ONE - TWO;

0 commit comments

Comments
 (0)