From b84b1da2dbacdfd7e33428540062380b56bfd8de Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 17 Jan 2023 19:29:52 +0000 Subject: [PATCH] Canonicalize trait solver response inside probe --- .../src/solve/assembly.rs | 22 +++++++------------ .../rustc_trait_selection/src/solve/mod.rs | 7 ++++++ .../src/solve/project_goals.rs | 10 ++++----- .../src/solve/trait_goals.rs | 10 ++++----- 4 files changed, 25 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/assembly.rs b/compiler/rustc_trait_selection/src/solve/assembly.rs index cd6e4d2bccd5..c8611294449e 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly.rs @@ -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}; +use super::{CanonicalResponse, EvalCtxt, Goal, QueryResult}; use rustc_hir::def_id::DefId; use rustc_infer::traits::query::NoSolution; use rustc_middle::ty::TypeFoldable; @@ -89,18 +89,18 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, impl_def_id: DefId, - ) -> Result; + ) -> QueryResult<'tcx>; fn consider_builtin_sized_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> Result; + ) -> QueryResult<'tcx>; fn consider_assumption( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, assumption: ty::Predicate<'tcx>, - ) -> Result; + ) -> QueryResult<'tcx>; } impl<'tcx> EvalCtxt<'_, 'tcx> { pub(super) fn assemble_and_evaluate_candidates>( @@ -180,9 +180,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { tcx.for_each_relevant_impl( goal.predicate.trait_def_id(tcx), goal.predicate.self_ty(), - |impl_def_id| match G::consider_impl_candidate(self, goal, impl_def_id) - .and_then(|certainty| self.make_canonical_response(certainty)) - { + |impl_def_id| match G::consider_impl_candidate(self, goal, impl_def_id) { Ok(result) => candidates .push(Candidate { source: CandidateSource::Impl(impl_def_id), result }), Err(NoSolution) => (), @@ -203,7 +201,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { Err(NoSolution) }; - match result.and_then(|certainty| self.make_canonical_response(certainty)) { + match result { Ok(result) => { candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result }) } @@ -217,9 +215,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { candidates: &mut Vec>, ) { for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() { - match G::consider_assumption(self, goal, assumption) - .and_then(|certainty| self.make_canonical_response(certainty)) - { + match G::consider_assumption(self, goal, assumption) { Ok(result) => { candidates.push(Candidate { source: CandidateSource::ParamEnv(i), result }) } @@ -268,9 +264,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { .subst_iter_copied(self.tcx(), alias_ty.substs) .enumerate() { - match G::consider_assumption(self, goal, assumption) - .and_then(|certainty| self.make_canonical_response(certainty)) - { + match G::consider_assumption(self, goal, assumption) { Ok(result) => { candidates.push(Candidate { source: CandidateSource::AliasBound(i), result }) } diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 579cd6a2d59c..32eb84635b53 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -313,6 +313,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } }) } + + fn evaluate_all_and_make_canonical_response( + &mut self, + goals: Vec>>, + ) -> QueryResult<'tcx> { + self.evaluate_all(goals).and_then(|certainty| self.make_canonical_response(certainty)) + } } #[instrument(level = "debug", skip(infcx), ret)] diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 0658836fb9cd..1d85d31705ad 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -191,7 +191,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, ProjectionPredicate<'tcx>>, impl_def_id: DefId, - ) -> Result { + ) -> QueryResult<'tcx> { let tcx = ecx.tcx(); let goal_trait_ref = goal.predicate.projection_ty.trait_ref(tcx); @@ -229,7 +229,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { impl_def_id )? else { let certainty = Certainty::Maybe(MaybeCause::Ambiguity); - return Ok(trait_ref_certainty.unify_and(certainty)); + return ecx.make_canonical_response(trait_ref_certainty.unify_and(certainty)); }; if !assoc_def.item.defaultness(tcx).has_value() { @@ -286,14 +286,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { let rhs_certainty = ecx.evaluate_all(nested_goals).expect("failed to unify with unconstrained term"); - Ok(trait_ref_certainty.unify_and(rhs_certainty)) + ecx.make_canonical_response(trait_ref_certainty.unify_and(rhs_certainty)) }) } fn consider_builtin_sized_candidate( _ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, - ) -> Result { + ) -> QueryResult<'tcx> { bug!("`Sized` does not have an associated type: {:?}", goal); } @@ -301,7 +301,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { _ecx: &mut EvalCtxt<'_, 'tcx>, _goal: Goal<'tcx, Self>, assumption: ty::Predicate<'tcx>, - ) -> Result { + ) -> QueryResult<'tcx> { if let Some(_poly_projection_pred) = assumption.to_opt_poly_projection_pred() { unimplemented!() } else { diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index bbe175d5cc85..111758c77d99 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -4,7 +4,7 @@ use std::iter; use super::assembly::{self, Candidate, CandidateSource}; use super::infcx_ext::InferCtxtExt; -use super::{Certainty, EvalCtxt, Goal, QueryResult}; +use super::{EvalCtxt, Goal, QueryResult}; use rustc_hir::def_id::DefId; use rustc_infer::traits::query::NoSolution; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; @@ -29,7 +29,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, TraitPredicate<'tcx>>, impl_def_id: DefId, - ) -> Result { + ) -> QueryResult<'tcx> { let tcx = ecx.tcx(); let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); @@ -53,14 +53,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { .into_iter() .map(|pred| goal.with(tcx, pred)); nested_goals.extend(where_clause_bounds); - ecx.evaluate_all(nested_goals) + ecx.evaluate_all_and_make_canonical_response(nested_goals) }) } fn consider_builtin_sized_candidate( _ecx: &mut EvalCtxt<'_, 'tcx>, _goal: Goal<'tcx, Self>, - ) -> Result { + ) -> QueryResult<'tcx> { unimplemented!(); } @@ -68,7 +68,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { _ecx: &mut EvalCtxt<'_, 'tcx>, _goal: Goal<'tcx, Self>, assumption: ty::Predicate<'tcx>, - ) -> Result { + ) -> QueryResult<'tcx> { if let Some(_poly_trait_pred) = assumption.to_opt_poly_trait_pred() { unimplemented!() } else {