Skip to content

Commit abcaf30

Browse files
committed
implement ConstEvaluatable goals in new solver
we don't yet handle `generic_const_exprs`, someone else can do that :3
1 parent cd68ead commit abcaf30

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
@@ -425,12 +425,8 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
425425
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
426426
self.compute_well_formed_goal(Goal { param_env, predicate: arg })
427427
}
428-
ty::PredicateKind::Ambiguous => {
429-
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
430-
}
431-
// FIXME: implement this predicate :)
432-
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(_)) => {
433-
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
428+
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(ct)) => {
429+
self.compute_const_evaluatable_goal(Goal { param_env, predicate: ct })
434430
}
435431
ty::PredicateKind::ConstEquate(_, _) => {
436432
bug!("ConstEquate should not be emitted when `-Ztrait-solver=next` is active")
@@ -440,6 +436,9 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
440436
param_env,
441437
predicate: (lhs, rhs, direction),
442438
}),
439+
ty::PredicateKind::Ambiguous => {
440+
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
441+
}
443442
}
444443
} else {
445444
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
@@ -159,6 +159,43 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
159159
}
160160
}
161161

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