]> git.lizzy.rs Git - rust.git/commitdiff
add `eq` to `InferCtxtExt`
authorlcnr <rust@lcnr.de>
Tue, 17 Jan 2023 11:26:28 +0000 (12:26 +0100)
committerlcnr <rust@lcnr.de>
Wed, 18 Jan 2023 07:11:15 +0000 (08:11 +0100)
compiler/rustc_trait_selection/src/solve/infcx_ext.rs
compiler/rustc_trait_selection/src/solve/project_goals.rs
compiler/rustc_trait_selection/src/solve/trait_goals.rs

index 8a8c3091d549fd61aee174c6e3c5b3221dfc4c63..f92d64631340a732839b5a487f959eeb78d6c8f3 100644 (file)
@@ -1,11 +1,28 @@
+use rustc_infer::infer::at::ToTrace;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
-use rustc_infer::infer::InferCtxt;
-use rustc_middle::ty::Ty;
+use rustc_infer::infer::{InferCtxt, InferOk};
+use rustc_infer::traits::query::NoSolution;
+use rustc_infer::traits::ObligationCause;
+use rustc_middle::ty::{self, Ty};
 use rustc_span::DUMMY_SP;
 
+use super::Goal;
+
 /// Methods used inside of the canonical queries of the solver.
+///
+/// Most notably these do not care about diagnostics information.
+/// If you find this while looking for methods to use outside of the
+/// solver, you may look at the implementation of these method for
+/// help.
 pub(super) trait InferCtxtExt<'tcx> {
     fn next_ty_infer(&self) -> Ty<'tcx>;
+
+    fn eq<T: ToTrace<'tcx>>(
+        &self,
+        param_env: ty::ParamEnv<'tcx>,
+        lhs: T,
+        rhs: T,
+    ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution>;
 }
 
 impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
@@ -15,4 +32,23 @@ fn next_ty_infer(&self) -> Ty<'tcx> {
             span: DUMMY_SP,
         })
     }
+
+    #[instrument(level = "debug", skip(self, param_env), ret)]
+    fn eq<T: ToTrace<'tcx>>(
+        &self,
+        param_env: ty::ParamEnv<'tcx>,
+        lhs: T,
+        rhs: T,
+    ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
+        self.at(&ObligationCause::dummy(), param_env)
+            .define_opaque_types(false)
+            .eq(lhs, rhs)
+            .map(|InferOk { value: (), obligations }| {
+                obligations.into_iter().map(|o| o.into()).collect()
+            })
+            .map_err(|e| {
+                debug!(?e, "failed to equate");
+                NoSolution
+            })
+    }
 }
index 92c5d4e53f5302be1408bad440e1b3745b9979d7..cf07926f85a2755183d90b01e091f5d81d96c20a 100644 (file)
@@ -1,14 +1,15 @@
 use crate::traits::{specialization_graph, translate_substs};
 
 use super::assembly::{self, Candidate, CandidateSource};
+use super::infcx_ext::InferCtxtExt;
 use super::{Certainty, EvalCtxt, Goal, QueryResult};
 use rustc_errors::ErrorGuaranteed;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
-use rustc_infer::infer::{InferCtxt, InferOk};
+use rustc_infer::infer::InferCtxt;
 use rustc_infer::traits::query::NoSolution;
 use rustc_infer::traits::specialization_graph::LeafDef;
-use rustc_infer::traits::{ObligationCause, Reveal};
+use rustc_infer::traits::Reveal;
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
 use rustc_middle::ty::ProjectionPredicate;
 use rustc_middle::ty::TypeVisitable;
@@ -112,14 +113,7 @@ fn consider_impl_candidate(
             let impl_substs = ecx.infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
             let impl_trait_ref = impl_trait_ref.subst(tcx, impl_substs);
 
-            let Ok(InferOk { obligations, .. }) = ecx.infcx
-                .at(&ObligationCause::dummy(), goal.param_env)
-                .define_opaque_types(false)
-                .eq(goal_trait_ref, impl_trait_ref)
-                .map_err(|e| debug!("failed to equate trait refs: {e:?}"))
-            else {
-                return Err(NoSolution)
-            };
+            let mut nested_goals = ecx.infcx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;
             let where_clause_bounds = tcx
                 .predicates_of(impl_def_id)
                 .instantiate(tcx, impl_substs)
@@ -127,8 +121,7 @@ fn consider_impl_candidate(
                 .into_iter()
                 .map(|pred| goal.with(tcx, pred));
 
-            let nested_goals =
-                obligations.into_iter().map(|o| o.into()).chain(where_clause_bounds).collect();
+            nested_goals.extend(where_clause_bounds);
             let trait_ref_certainty = ecx.evaluate_all(nested_goals)?;
 
             let Some(assoc_def) = fetch_eligible_assoc_item_def(
@@ -185,16 +178,8 @@ fn consider_impl_candidate(
                 ty.map_bound(|ty| ty.into())
             };
 
-            let Ok(InferOk { obligations, .. }) = ecx.infcx
-                .at(&ObligationCause::dummy(), goal.param_env)
-                .define_opaque_types(false)
-                .eq(goal.predicate.term,  term.subst(tcx, substs))
-                .map_err(|e| debug!("failed to equate trait refs: {e:?}"))
-            else {
-                return Err(NoSolution);
-            };
-
-            let nested_goals = obligations.into_iter().map(|o| o.into()).collect();
+            let nested_goals =
+                ecx.infcx.eq(goal.param_env, goal.predicate.term, term.subst(tcx, substs))?;
             let rhs_certainty = ecx.evaluate_all(nested_goals)?;
 
             Ok(trait_ref_certainty.unify_and(rhs_certainty))
index 3c8314aa565ee12616eac0a00ff070847394bfe7..bbe175d5cc8536ce72792b2a14592d2bc4ec6827 100644 (file)
@@ -3,11 +3,10 @@
 use std::iter;
 
 use super::assembly::{self, Candidate, CandidateSource};
+use super::infcx_ext::InferCtxtExt;
 use super::{Certainty, EvalCtxt, Goal, QueryResult};
 use rustc_hir::def_id::DefId;
-use rustc_infer::infer::InferOk;
 use rustc_infer::traits::query::NoSolution;
-use rustc_infer::traits::ObligationCause;
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
 use rustc_middle::ty::TraitPredicate;
 use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -45,24 +44,15 @@ fn consider_impl_candidate(
             let impl_substs = ecx.infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
             let impl_trait_ref = impl_trait_ref.subst(tcx, impl_substs);
 
-            let Ok(InferOk { obligations, .. }) = ecx.infcx
-                .at(&ObligationCause::dummy(), goal.param_env)
-                .define_opaque_types(false)
-                .eq(goal.predicate.trait_ref, impl_trait_ref)
-                .map_err(|e| debug!("failed to equate trait refs: {e:?}"))
-            else {
-                return Err(NoSolution);
-            };
+            let mut nested_goals =
+                ecx.infcx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?;
             let where_clause_bounds = tcx
                 .predicates_of(impl_def_id)
                 .instantiate(tcx, impl_substs)
                 .predicates
                 .into_iter()
                 .map(|pred| goal.with(tcx, pred));
-
-            let nested_goals =
-                obligations.into_iter().map(|o| o.into()).chain(where_clause_bounds).collect();
-
+            nested_goals.extend(where_clause_bounds);
             ecx.evaluate_all(nested_goals)
         })
     }