]> git.lizzy.rs Git - rust.git/commitdiff
Address goal nits
authorMichael Goulet <michael@errs.io>
Fri, 20 Jan 2023 18:38:33 +0000 (18:38 +0000)
committerMichael Goulet <michael@errs.io>
Sat, 21 Jan 2023 17:15:00 +0000 (17:15 +0000)
compiler/rustc_trait_selection/src/solve/assembly.rs
compiler/rustc_trait_selection/src/solve/mod.rs
compiler/rustc_trait_selection/src/solve/project_goals.rs
compiler/rustc_trait_selection/src/solve/trait_goals.rs

index 31c1bc9ecc062c7870242474521939b59e2279ee..cdb72d49834f0101f401660171e102675bfa9e3b 100644 (file)
@@ -1,7 +1,7 @@
 //! Code shared by trait and projection goals for candidate assembly.
 
 use super::infcx_ext::InferCtxtExt;
-use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, MaybeCause, QueryResult};
+use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, QueryResult};
 use rustc_hir::def_id::DefId;
 use rustc_infer::traits::query::NoSolution;
 use rustc_infer::traits::util::elaborate_predicates;
@@ -148,9 +148,7 @@ pub(super) fn assemble_and_evaluate_candidates<G: GoalKind<'tcx>>(
         if goal.predicate.self_ty().is_ty_var() {
             return vec![Candidate {
                 source: CandidateSource::BuiltinImpl,
-                result: self
-                    .make_canonical_response(Certainty::Maybe(MaybeCause::Ambiguity))
-                    .unwrap(),
+                result: self.make_canonical_response(Certainty::AMBIGUOUS).unwrap(),
             }];
         }
 
index e89d3df04db0b819c78c0fbb79786132981f1690..da2a1a19957e128f491b8a1bbc3b3384da637581 100644 (file)
@@ -19,6 +19,7 @@
 
 use std::mem;
 
+use rustc_hir::def_id::DefId;
 use rustc_infer::infer::canonical::{Canonical, CanonicalVarKind, CanonicalVarValues};
 use rustc_infer::infer::canonical::{OriginalQueryValues, QueryRegionConstraints, QueryResponse};
 use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
@@ -27,7 +28,7 @@
 use rustc_middle::infer::canonical::Certainty as OldCertainty;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::ty::{
-    RegionOutlivesPredicate, SubtypePredicate, ToPredicate, TypeOutlivesPredicate,
+    CoercePredicate, RegionOutlivesPredicate, SubtypePredicate, ToPredicate, TypeOutlivesPredicate,
 };
 use rustc_span::DUMMY_SP;
 
@@ -89,6 +90,8 @@ pub enum Certainty {
 }
 
 impl Certainty {
+    pub const AMBIGUOUS: Certainty = Certainty::Maybe(MaybeCause::Ambiguity);
+
     /// When proving multiple goals using **AND**, e.g. nested obligations for an impl,
     /// use this function to unify the certainty of these goals
     pub fn unify_and(self, other: Certainty) -> Certainty {
@@ -248,21 +251,15 @@ fn compute_goal(&mut self, goal: Goal<'tcx, ty::Predicate<'tcx>>) -> QueryResult
                 ty::PredicateKind::Subtype(predicate) => {
                     self.compute_subtype_goal(Goal { param_env, predicate })
                 }
-                ty::PredicateKind::Coerce(predicate) => self.compute_subtype_goal(Goal {
-                    param_env,
-                    predicate: SubtypePredicate {
-                        a_is_expected: true,
-                        a: predicate.a,
-                        b: predicate.b,
-                    },
-                }),
-                ty::PredicateKind::ClosureKind(_, substs, kind) => self.compute_closure_kind_goal(
-                    substs.as_closure().kind_ty().to_opt_closure_kind(),
-                    kind,
-                ),
-                ty::PredicateKind::Ambiguous => {
-                    self.make_canonical_response(Certainty::Maybe(MaybeCause::Ambiguity))
+                ty::PredicateKind::Coerce(predicate) => {
+                    self.compute_coerce_goal(Goal { param_env, predicate })
                 }
+                ty::PredicateKind::ClosureKind(def_id, substs, kind) => self
+                    .compute_closure_kind_goal(Goal {
+                        param_env,
+                        predicate: (def_id, substs, kind),
+                    }),
+                ty::PredicateKind::Ambiguous => self.make_canonical_response(Certainty::AMBIGUOUS),
                 // FIXME: implement these predicates :)
                 ty::PredicateKind::WellFormed(_)
                 | ty::PredicateKind::ObjectSafe(_)
@@ -296,28 +293,50 @@ fn compute_region_outlives_goal(
         self.make_canonical_response(Certainty::Yes)
     }
 
+    fn compute_coerce_goal(
+        &mut self,
+        goal: Goal<'tcx, CoercePredicate<'tcx>>,
+    ) -> QueryResult<'tcx> {
+        self.compute_subtype_goal(Goal {
+            param_env: goal.param_env,
+            predicate: SubtypePredicate {
+                a_is_expected: false,
+                a: goal.predicate.a,
+                b: goal.predicate.b,
+            },
+        })
+    }
+
     fn compute_subtype_goal(
         &mut self,
         goal: Goal<'tcx, SubtypePredicate<'tcx>>,
     ) -> QueryResult<'tcx> {
-        self.infcx.probe(|_| {
-            let InferOk { value: (), obligations } = self
-                .infcx
-                .at(&ObligationCause::dummy(), goal.param_env)
-                .sub(goal.predicate.a, goal.predicate.b)?;
-            self.evaluate_all_and_make_canonical_response(
-                obligations.into_iter().map(|pred| pred.into()).collect(),
-            )
-        })
+        if goal.predicate.a.is_ty_var() && goal.predicate.b.is_ty_var() {
+            // FIXME: Do we want to register a subtype relation between these vars?
+            // That won't actually reflect in the query response, so it seems moot.
+            self.make_canonical_response(Certainty::AMBIGUOUS)
+        } else {
+            self.infcx.probe(|_| {
+                let InferOk { value: (), obligations } = self
+                    .infcx
+                    .at(&ObligationCause::dummy(), goal.param_env)
+                    .sub(goal.predicate.a, goal.predicate.b)?;
+                self.evaluate_all_and_make_canonical_response(
+                    obligations.into_iter().map(|pred| pred.into()).collect(),
+                )
+            })
+        }
     }
 
     fn compute_closure_kind_goal(
         &mut self,
-        found_kind: Option<ty::ClosureKind>,
-        expected_kind: ty::ClosureKind,
+        goal: Goal<'tcx, (DefId, ty::SubstsRef<'tcx>, ty::ClosureKind)>,
     ) -> QueryResult<'tcx> {
+        let (_, substs, expected_kind) = goal.predicate;
+        let found_kind = substs.as_closure().kind_ty().to_opt_closure_kind();
+
         let Some(found_kind) = found_kind else {
-            return self.make_canonical_response(Certainty::Maybe(MaybeCause::Ambiguity));
+            return self.make_canonical_response(Certainty::AMBIGUOUS);
         };
         if found_kind.extends(expected_kind) {
             self.make_canonical_response(Certainty::Yes)
index e39fa05339286ab86d9d18e512eec92ae0448c3c..32e15f03998b3598431b58e417d87938e5cab02d 100644 (file)
@@ -3,7 +3,7 @@
 use super::assembly::{self, Candidate, CandidateSource};
 use super::infcx_ext::InferCtxtExt;
 use super::trait_goals::structural_traits;
-use super::{Certainty, EvalCtxt, Goal, MaybeCause, QueryResult};
+use super::{Certainty, EvalCtxt, Goal, QueryResult};
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
@@ -229,8 +229,7 @@ fn consider_impl_candidate(
                 goal.predicate.def_id(),
                 impl_def_id
             )? else {
-                let certainty = Certainty::Maybe(MaybeCause::Ambiguity);
-                return ecx.make_canonical_response(trait_ref_certainty.unify_and(certainty));
+                return ecx.make_canonical_response(trait_ref_certainty.unify_and(Certainty::AMBIGUOUS));
             };
 
             if !assoc_def.item.defaultness(tcx).has_value() {
@@ -382,7 +381,7 @@ fn consider_builtin_fn_trait_candidates(
                 .to_predicate(ecx.tcx());
             Self::consider_assumption(ecx, goal, pred)
         } else {
-            ecx.make_canonical_response(Certainty::Maybe(MaybeCause::Ambiguity))
+            ecx.make_canonical_response(Certainty::AMBIGUOUS)
         }
     }
 
index 9985d7181bb7dd000edebae5c2a0f695309e3b9d..4b6d673c999c96fd7dab198e99a3aec327ceba70 100644 (file)
@@ -4,7 +4,7 @@
 
 use super::assembly::{self, Candidate, CandidateSource};
 use super::infcx_ext::InferCtxtExt;
-use super::{Certainty, EvalCtxt, Goal, MaybeCause, QueryResult};
+use super::{Certainty, EvalCtxt, Goal, QueryResult};
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::InferCtxt;
 use rustc_infer::traits::query::NoSolution;
@@ -133,7 +133,7 @@ fn consider_builtin_pointer_sized_candidate(
         goal: Goal<'tcx, Self>,
     ) -> QueryResult<'tcx> {
         if goal.predicate.self_ty().has_non_region_infer() {
-            return ecx.make_canonical_response(Certainty::Maybe(MaybeCause::Ambiguity));
+            return ecx.make_canonical_response(Certainty::AMBIGUOUS);
         }
 
         let tcx = ecx.tcx();
@@ -171,7 +171,7 @@ fn consider_builtin_fn_trait_candidates(
                 .to_predicate(ecx.tcx());
             Self::consider_assumption(ecx, goal, pred)
         } else {
-            ecx.make_canonical_response(Certainty::Maybe(MaybeCause::Ambiguity))
+            ecx.make_canonical_response(Certainty::AMBIGUOUS)
         }
     }