about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-07-04 17:46:28 +0200
committerGitHub <noreply@github.com>2023-07-04 17:46:28 +0200
commit7996908c4f8fbe2b99ab5225faa794fe02b3158b (patch)
treeba56bb79cc6f8e7d0d26f400da2df3383d8ac629 /compiler/rustc_trait_selection/src
parent494e67c63c9b616b052d4cd9e70ca0b3f7f3cbd1 (diff)
parentabcaf30f9bce3f84f2574184a4bf44d44fd84a7c (diff)
downloadrust-7996908c4f8fbe2b99ab5225faa794fe02b3158b.tar.gz
rust-7996908c4f8fbe2b99ab5225faa794fe02b3158b.zip
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`
Diffstat (limited to 'compiler/rustc_trait_selection/src')
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt.rs11
-rw-r--r--compiler/rustc_trait_selection/src/solve/mod.rs37
2 files changed, 42 insertions, 6 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
index 952a4c24fa6..3e50829ec97 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
@@ -441,12 +441,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")
@@ -456,6 +452,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 8f142a309d7..77809d8d2ba 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -161,6 +161,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,