From abcaf30f9bce3f84f2574184a4bf44d44fd84a7c Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 4 Jul 2023 15:40:15 +0200 Subject: [PATCH] implement `ConstEvaluatable` goals in new solver we don't yet handle `generic_const_exprs`, someone else can do that :3 --- .../src/solve/eval_ctxt.rs | 11 +++--- .../rustc_trait_selection/src/solve/mod.rs | 37 +++++++++++++++++++ ... => default-param-wf-concrete.next.stderr} | 2 +- .../default-param-wf-concrete.old.stderr | 9 +++++ .../defaults/default-param-wf-concrete.rs | 3 ++ ...-len-underflow-separate-spans.next.stderr} | 4 +- ...st-len-underflow-separate-spans.old.stderr | 15 ++++++++ .../const-len-underflow-separate-spans.rs | 3 ++ 8 files changed, 75 insertions(+), 9 deletions(-) rename tests/ui/const-generics/defaults/{default-param-wf-concrete.stderr => default-param-wf-concrete.next.stderr} (87%) create mode 100644 tests/ui/const-generics/defaults/default-param-wf-concrete.old.stderr rename tests/ui/consts/{const-len-underflow-separate-spans.stderr => const-len-underflow-separate-spans.next.stderr} (78%) create mode 100644 tests/ui/consts/const-len-underflow-separate-spans.old.stderr diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index 6b7be73b6317c..034d68e5459b7 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -425,12 +425,8 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => { self.compute_well_formed_goal(Goal { param_env, predicate: arg }) } - ty::PredicateKind::Ambiguous => { - self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) - } - // FIXME: implement this predicate :) - ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(_)) => { - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(ct)) => { + self.compute_const_evaluatable_goal(Goal { param_env, predicate: ct }) } ty::PredicateKind::ConstEquate(_, _) => { bug!("ConstEquate should not be emitted when `-Ztrait-solver=next` is active") @@ -440,6 +436,9 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { param_env, predicate: (lhs, rhs, direction), }), + ty::PredicateKind::Ambiguous => { + self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) + } } } else { let kind = self.infcx.instantiate_binder_with_placeholders(kind); diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index f3f78cdf09d6e..b987a3a350003 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -159,6 +159,43 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } } + #[instrument(level = "debug", skip(self))] + fn compute_const_evaluatable_goal( + &mut self, + Goal { param_env, predicate: ct }: Goal<'tcx, ty::Const<'tcx>>, + ) -> QueryResult<'tcx> { + match ct.kind() { + ty::ConstKind::Unevaluated(uv) => { + // We never return `NoSolution` here as `try_const_eval_resolve` emits an + // error itself when failing to evaluate, so emitting an additional fulfillment + // error in that case is unnecessary noise. This may change in the future once + // evaluation failures are allowed to impact selection, e.g. generic const + // expressions in impl headers or `where`-clauses. + + // FIXME(generic_const_exprs): Implement handling for generic + // const expressions here. + if let Some(_normalized) = self.try_const_eval_resolve(param_env, uv, ct.ty()) { + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + } else { + self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) + } + } + ty::ConstKind::Infer(_) => { + self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) + } + ty::ConstKind::Placeholder(_) | ty::ConstKind::Value(_) | ty::ConstKind::Error(_) => { + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + } + // We can freely ICE here as: + // - `Param` gets replaced with a placeholder during canonicalization + // - `Bound` cannot exist as we don't have a binder around the self Type + // - `Expr` is part of `feature(generic_const_exprs)` and is not implemented yet + ty::ConstKind::Param(_) | ty::ConstKind::Bound(_, _) | ty::ConstKind::Expr(_) => { + bug!("unexpect const kind: {:?}", ct) + } + } + } + #[instrument(level = "debug", skip(self), ret)] fn compute_const_arg_has_type_goal( &mut self, diff --git a/tests/ui/const-generics/defaults/default-param-wf-concrete.stderr b/tests/ui/const-generics/defaults/default-param-wf-concrete.next.stderr similarity index 87% rename from tests/ui/const-generics/defaults/default-param-wf-concrete.stderr rename to tests/ui/const-generics/defaults/default-param-wf-concrete.next.stderr index e8ebddade5c16..4259ce2b626fe 100644 --- a/tests/ui/const-generics/defaults/default-param-wf-concrete.stderr +++ b/tests/ui/const-generics/defaults/default-param-wf-concrete.next.stderr @@ -1,5 +1,5 @@ error[E0080]: evaluation of constant value failed - --> $DIR/default-param-wf-concrete.rs:1:28 + --> $DIR/default-param-wf-concrete.rs:4:28 | LL | struct Foo; | ^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow diff --git a/tests/ui/const-generics/defaults/default-param-wf-concrete.old.stderr b/tests/ui/const-generics/defaults/default-param-wf-concrete.old.stderr new file mode 100644 index 0000000000000..4259ce2b626fe --- /dev/null +++ b/tests/ui/const-generics/defaults/default-param-wf-concrete.old.stderr @@ -0,0 +1,9 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/default-param-wf-concrete.rs:4:28 + | +LL | struct Foo; + | ^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/const-generics/defaults/default-param-wf-concrete.rs b/tests/ui/const-generics/defaults/default-param-wf-concrete.rs index 41a52c7eb0d83..09a00dd8e701b 100644 --- a/tests/ui/const-generics/defaults/default-param-wf-concrete.rs +++ b/tests/ui/const-generics/defaults/default-param-wf-concrete.rs @@ -1,3 +1,6 @@ +// revisions: old next +//[next] compile-flags: -Ztrait-solver=next + struct Foo; //~^ ERROR evaluation of constant value failed fn main() {} diff --git a/tests/ui/consts/const-len-underflow-separate-spans.stderr b/tests/ui/consts/const-len-underflow-separate-spans.next.stderr similarity index 78% rename from tests/ui/consts/const-len-underflow-separate-spans.stderr rename to tests/ui/consts/const-len-underflow-separate-spans.next.stderr index 269553631cc67..d9208d0706af2 100644 --- a/tests/ui/consts/const-len-underflow-separate-spans.stderr +++ b/tests/ui/consts/const-len-underflow-separate-spans.next.stderr @@ -1,11 +1,11 @@ error[E0080]: evaluation of constant value failed - --> $DIR/const-len-underflow-separate-spans.rs:7:20 + --> $DIR/const-len-underflow-separate-spans.rs:10:20 | LL | const LEN: usize = ONE - TWO; | ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow note: erroneous constant used - --> $DIR/const-len-underflow-separate-spans.rs:11:17 + --> $DIR/const-len-underflow-separate-spans.rs:14:17 | LL | let a: [i8; LEN] = unimplemented!(); | ^^^ diff --git a/tests/ui/consts/const-len-underflow-separate-spans.old.stderr b/tests/ui/consts/const-len-underflow-separate-spans.old.stderr new file mode 100644 index 0000000000000..d9208d0706af2 --- /dev/null +++ b/tests/ui/consts/const-len-underflow-separate-spans.old.stderr @@ -0,0 +1,15 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/const-len-underflow-separate-spans.rs:10:20 + | +LL | const LEN: usize = ONE - TWO; + | ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow + +note: erroneous constant used + --> $DIR/const-len-underflow-separate-spans.rs:14:17 + | +LL | let a: [i8; LEN] = unimplemented!(); + | ^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-len-underflow-separate-spans.rs b/tests/ui/consts/const-len-underflow-separate-spans.rs index 4544c8876ae09..55704b641543b 100644 --- a/tests/ui/consts/const-len-underflow-separate-spans.rs +++ b/tests/ui/consts/const-len-underflow-separate-spans.rs @@ -2,6 +2,9 @@ // spot (where the underflow occurred), while also providing the // overall context for what caused the evaluation. +// revisions: old next +//[next] compile-flags: -Ztrait-solver=next + const ONE: usize = 1; const TWO: usize = 2; const LEN: usize = ONE - TWO;