diff options
Diffstat (limited to 'compiler/rustc_trait_selection/src')
6 files changed, 310 insertions, 77 deletions
diff --git a/compiler/rustc_trait_selection/src/solve.rs b/compiler/rustc_trait_selection/src/solve.rs new file mode 100644 index 00000000000..a7c8cc5a32b --- /dev/null +++ b/compiler/rustc_trait_selection/src/solve.rs @@ -0,0 +1,12 @@ +pub use rustc_next_trait_solver::solve::*; + +mod fulfill; +mod infcx; +pub mod inspect; +mod normalize; +mod select; + +pub use fulfill::{FulfillmentCtxt, NextSolverError}; +pub(crate) use normalize::deeply_normalize_for_diagnostics; +pub use normalize::{deeply_normalize, deeply_normalize_with_skipped_universes}; +pub use select::InferCtxtSelectExt; diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 3c01d1a65f5..8937ed467a1 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -12,13 +12,14 @@ use rustc_infer::traits::{ use rustc_middle::bug; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{self, TyCtxt}; +use rustc_next_trait_solver::solve::{GenerateProofTree, SolverDelegateEvalExt as _}; use rustc_span::symbol::sym; use crate::traits::{FulfillmentError, FulfillmentErrorCode, ScrubbedTraitError}; -use super::eval_ctxt::GenerateProofTree; +use super::infcx::SolverDelegate; use super::inspect::{self, ProofTreeInferCtxtExt, ProofTreeVisitor}; -use super::{Certainty, InferCtxtEvalExt}; +use super::Certainty; /// A trait engine using the new trait solver. /// @@ -83,7 +84,9 @@ impl<'tcx> ObligationStorage<'tcx> { // change. self.overflowed.extend(self.pending.extract_if(|o| { let goal = o.clone().into(); - let result = infcx.evaluate_root_goal(goal, GenerateProofTree::No).0; + let result = <&SolverDelegate<'tcx>>::from(infcx) + .evaluate_root_goal(goal, GenerateProofTree::No) + .0; match result { Ok((has_changed, _)) => has_changed, _ => false, @@ -165,7 +168,9 @@ where let mut has_changed = false; for obligation in self.obligations.unstalled_for_select() { let goal = obligation.clone().into(); - let result = infcx.evaluate_root_goal(goal, GenerateProofTree::No).0; + let result = <&SolverDelegate<'tcx>>::from(infcx) + .evaluate_root_goal(goal, GenerateProofTree::No) + .0; self.inspect_evaluated_obligation(infcx, &obligation, &result); let (changed, certainty) = match result { Ok(result) => result, @@ -288,7 +293,10 @@ fn fulfillment_error_for_stalled<'tcx>( root_obligation: PredicateObligation<'tcx>, ) -> FulfillmentError<'tcx> { let (code, refine_obligation) = infcx.probe(|_| { - match infcx.evaluate_root_goal(root_obligation.clone().into(), GenerateProofTree::No).0 { + match <&SolverDelegate<'tcx>>::from(infcx) + .evaluate_root_goal(root_obligation.clone().into(), GenerateProofTree::No) + .0 + { Ok((_, Certainty::Maybe(MaybeCause::Ambiguity))) => { (FulfillmentErrorCode::Ambiguity { overflow: None }, true) } diff --git a/compiler/rustc_trait_selection/src/solve/infcx.rs b/compiler/rustc_trait_selection/src/solve/infcx.rs index c73c49aa9b8..2a5aaa26f3f 100644 --- a/compiler/rustc_trait_selection/src/solve/infcx.rs +++ b/compiler/rustc_trait_selection/src/solve/infcx.rs @@ -1,14 +1,25 @@ use std::ops::Deref; +use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_infer::infer::{BoundRegionConversionTime, InferCtxt}; +use rustc_infer::infer::canonical::query_response::make_query_region_constraints; +use rustc_infer::infer::canonical::{ + Canonical, CanonicalExt as _, CanonicalVarInfo, CanonicalVarValues, +}; +use rustc_infer::infer::{ + BoundRegionConversionTime, InferCtxt, RegionVariableOrigin, SubregionOrigin, TyCtxtInferExt, +}; use rustc_infer::traits::solve::Goal; -use rustc_infer::traits::ObligationCause; +use rustc_infer::traits::util::supertraits; +use rustc_infer::traits::{ObligationCause, Reveal}; use rustc_middle::ty::fold::TypeFoldable; -use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_span::DUMMY_SP; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt as _}; +use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP}; use rustc_type_ir::relate::Relate; -use rustc_type_ir::solve::NoSolution; +use rustc_type_ir::solve::{NoSolution, SolverMode}; + +use crate::traits::coherence::trait_ref_is_knowable; +use crate::traits::specialization_graph; #[repr(transparent)] pub struct SolverDelegate<'tcx>(InferCtxt<'tcx>); @@ -32,7 +43,43 @@ impl<'tcx> rustc_next_trait_solver::infcx::SolverDelegate for SolverDelegate<'tc type Interner = TyCtxt<'tcx>; fn interner(&self) -> TyCtxt<'tcx> { - (**self).tcx + self.0.tcx + } + + type Span = Span; + + fn solver_mode(&self) -> ty::solve::SolverMode { + match self.intercrate { + true => SolverMode::Coherence, + false => SolverMode::Normal, + } + } + + fn build_with_canonical<V>( + interner: TyCtxt<'tcx>, + solver_mode: SolverMode, + canonical: &Canonical<'tcx, V>, + ) -> (Self, V, CanonicalVarValues<'tcx>) + where + V: TypeFoldable<TyCtxt<'tcx>>, + { + let (infcx, value, vars) = interner + .infer_ctxt() + .with_next_trait_solver(true) + .intercrate(match solver_mode { + SolverMode::Normal => false, + SolverMode::Coherence => true, + }) + .build_with_canonical(DUMMY_SP, canonical); + (SolverDelegate(infcx), value, vars) + } + + fn universe(&self) -> ty::UniverseIndex { + self.0.universe() + } + + fn create_next_universe(&self) -> ty::UniverseIndex { + self.0.create_next_universe() } fn universe_of_ty(&self, vid: ty::TyVid) -> Option<ty::UniverseIndex> { @@ -40,14 +87,14 @@ impl<'tcx> rustc_next_trait_solver::infcx::SolverDelegate for SolverDelegate<'tc // ty infers will give you the universe of the var it resolved to not the universe // it actually had. It also means that if you have a `?0.1` and infer it to `u8` then // try to print out `?0.1` it will just print `?0`. - match (**self).probe_ty_var(vid) { + match self.0.probe_ty_var(vid) { Err(universe) => Some(universe), Ok(_) => None, } } fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex> { - match (**self).inner.borrow_mut().unwrap_region_constraints().probe_value(lt) { + match self.0.inner.borrow_mut().unwrap_region_constraints().probe_value(lt) { Err(universe) => Some(universe), Ok(_) => None, } @@ -55,81 +102,95 @@ impl<'tcx> rustc_next_trait_solver::infcx::SolverDelegate for SolverDelegate<'tc fn universe_of_ct(&self, ct: ty::ConstVid) -> Option<ty::UniverseIndex> { // Same issue as with `universe_of_ty` - match (**self).probe_const_var(ct) { + match self.0.probe_const_var(ct) { Err(universe) => Some(universe), Ok(_) => None, } } fn root_ty_var(&self, var: ty::TyVid) -> ty::TyVid { - (**self).root_var(var) + self.0.root_var(var) } fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid { - (**self).root_const_var(var) + self.0.root_const_var(var) } fn opportunistic_resolve_ty_var(&self, vid: ty::TyVid) -> Ty<'tcx> { - match (**self).probe_ty_var(vid) { + match self.0.probe_ty_var(vid) { Ok(ty) => ty, - Err(_) => Ty::new_var((**self).tcx, (**self).root_var(vid)), + Err(_) => Ty::new_var(self.0.tcx, self.0.root_var(vid)), } } fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> { - (**self).opportunistic_resolve_int_var(vid) + self.0.opportunistic_resolve_int_var(vid) } fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> { - (**self).opportunistic_resolve_float_var(vid) + self.0.opportunistic_resolve_float_var(vid) } fn opportunistic_resolve_ct_var(&self, vid: ty::ConstVid) -> ty::Const<'tcx> { - match (**self).probe_const_var(vid) { + match self.0.probe_const_var(vid) { Ok(ct) => ct, - Err(_) => ty::Const::new_var((**self).tcx, (**self).root_const_var(vid)), + Err(_) => ty::Const::new_var(self.0.tcx, self.0.root_const_var(vid)), } } fn opportunistic_resolve_effect_var(&self, vid: ty::EffectVid) -> ty::Const<'tcx> { - match (**self).probe_effect_var(vid) { + match self.0.probe_effect_var(vid) { Some(ct) => ct, None => ty::Const::new_infer( - (**self).tcx, - ty::InferConst::EffectVar((**self).root_effect_var(vid)), + self.0.tcx, + ty::InferConst::EffectVar(self.0.root_effect_var(vid)), ), } } fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> { - (**self) + self.0 .inner .borrow_mut() .unwrap_region_constraints() - .opportunistic_resolve_var((**self).tcx, vid) + .opportunistic_resolve_var(self.0.tcx, vid) } fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> { - (**self).defining_opaque_types() + self.0.defining_opaque_types() } fn next_ty_infer(&self) -> Ty<'tcx> { - (**self).next_ty_var(DUMMY_SP) + self.0.next_ty_var(DUMMY_SP) } fn next_const_infer(&self) -> ty::Const<'tcx> { - (**self).next_const_var(DUMMY_SP) + self.0.next_const_var(DUMMY_SP) } fn fresh_args_for_item(&self, def_id: DefId) -> ty::GenericArgsRef<'tcx> { - (**self).fresh_args_for_item(DUMMY_SP, def_id) + self.0.fresh_args_for_item(DUMMY_SP, def_id) } - fn instantiate_binder_with_infer<T: TypeFoldable<Self::Interner> + Copy>( + fn fresh_var_for_kind_with_span( + &self, + arg: ty::GenericArg<'tcx>, + span: Span, + ) -> ty::GenericArg<'tcx> { + match arg.unpack() { + ty::GenericArgKind::Lifetime(_) => { + self.next_region_var(RegionVariableOrigin::MiscVariable(span)).into() + } + ty::GenericArgKind::Type(_) => self.next_ty_var(span).into(), + ty::GenericArgKind::Const(_) => self.next_const_var(span).into(), + } + } + + fn instantiate_binder_with_infer<T: TypeFoldable<TyCtxt<'tcx>> + Copy>( &self, value: ty::Binder<'tcx, T>, ) -> T { - (**self).instantiate_binder_with_fresh_vars( + self.0.instantiate_binder_with_fresh_vars( DUMMY_SP, BoundRegionConversionTime::HigherRankedType, value, @@ -141,7 +202,7 @@ impl<'tcx> rustc_next_trait_solver::infcx::SolverDelegate for SolverDelegate<'tc value: ty::Binder<'tcx, T>, f: impl FnOnce(T) -> U, ) -> U { - (**self).enter_forall(value, f) + self.0.enter_forall(value, f) } fn relate<T: Relate<TyCtxt<'tcx>>>( @@ -151,7 +212,7 @@ impl<'tcx> rustc_next_trait_solver::infcx::SolverDelegate for SolverDelegate<'tc variance: ty::Variance, rhs: T, ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> { - (**self).at(&ObligationCause::dummy(), param_env).relate_no_trace(lhs, variance, rhs) + self.0.at(&ObligationCause::dummy(), param_env).relate_no_trace(lhs, variance, rhs) } fn eq_structurally_relating_aliases<T: Relate<TyCtxt<'tcx>>>( @@ -160,7 +221,7 @@ impl<'tcx> rustc_next_trait_solver::infcx::SolverDelegate for SolverDelegate<'tc lhs: T, rhs: T, ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> { - (**self) + self.0 .at(&ObligationCause::dummy(), param_env) .eq_structurally_relating_aliases_no_trace(lhs, rhs) } @@ -169,10 +230,180 @@ impl<'tcx> rustc_next_trait_solver::infcx::SolverDelegate for SolverDelegate<'tc where T: TypeFoldable<TyCtxt<'tcx>>, { - (**self).resolve_vars_if_possible(value) + self.0.resolve_vars_if_possible(value) } fn probe<T>(&self, probe: impl FnOnce() -> T) -> T { - (**self).probe(|_| probe()) + self.0.probe(|_| probe()) + } + + fn leak_check(&self, max_input_universe: ty::UniverseIndex) -> Result<(), NoSolution> { + self.0.leak_check(max_input_universe, None).map_err(|_| NoSolution) + } + + fn elaborate_supertraits( + interner: TyCtxt<'tcx>, + trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, + ) -> impl Iterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>> { + supertraits(interner, trait_ref) + } + + fn try_const_eval_resolve( + &self, + param_env: ty::ParamEnv<'tcx>, + unevaluated: ty::UnevaluatedConst<'tcx>, + ) -> Option<ty::Const<'tcx>> { + use rustc_middle::mir::interpret::ErrorHandled; + match self.const_eval_resolve(param_env, unevaluated, DUMMY_SP) { + Ok(Some(val)) => Some(ty::Const::new_value( + self.tcx, + val, + self.tcx.type_of(unevaluated.def).instantiate(self.tcx, unevaluated.args), + )), + Ok(None) | Err(ErrorHandled::TooGeneric(_)) => None, + Err(ErrorHandled::Reported(e, _)) => Some(ty::Const::new_error(self.tcx, e.into())), + } + } + + fn sub_regions(&self, sub: ty::Region<'tcx>, sup: ty::Region<'tcx>) { + self.0.sub_regions(SubregionOrigin::RelateRegionParamBound(DUMMY_SP), sub, sup) + } + + fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>) { + self.0.register_region_obligation_with_cause(ty, r, &ObligationCause::dummy()); + } + + fn well_formed_goals( + &self, + param_env: ty::ParamEnv<'tcx>, + arg: ty::GenericArg<'tcx>, + ) -> Option<Vec<Goal<'tcx, ty::Predicate<'tcx>>>> { + crate::traits::wf::unnormalized_obligations(&self.0, param_env, arg).map(|obligations| { + obligations.into_iter().map(|obligation| obligation.into()).collect() + }) + } + + fn clone_opaque_types_for_query_response(&self) -> Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)> { + self.0.clone_opaque_types_for_query_response() + } + + fn make_deduplicated_outlives_constraints( + &self, + ) -> Vec<ty::OutlivesPredicate<'tcx, ty::GenericArg<'tcx>>> { + // Cannot use `take_registered_region_obligations` as we may compute the response + // inside of a `probe` whenever we have multiple choices inside of the solver. + let region_obligations = self.0.inner.borrow().region_obligations().to_owned(); + let region_constraints = self.0.with_region_constraints(|region_constraints| { + make_query_region_constraints( + self.tcx, + region_obligations + .iter() + .map(|r_o| (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())), + region_constraints, + ) + }); + + assert_eq!(region_constraints.member_constraints, vec![]); + + let mut seen = FxHashSet::default(); + region_constraints + .outlives + .into_iter() + .filter(|&(outlives, _)| seen.insert(outlives)) + .map(|(outlives, _)| outlives) + .collect() + } + + fn instantiate_canonical<V>( + &self, + canonical: Canonical<'tcx, V>, + values: CanonicalVarValues<'tcx>, + ) -> V + where + V: TypeFoldable<TyCtxt<'tcx>>, + { + canonical.instantiate(self.tcx, &values) + } + + fn instantiate_canonical_var_with_infer( + &self, + cv_info: CanonicalVarInfo<'tcx>, + universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex, + ) -> ty::GenericArg<'tcx> { + self.0.instantiate_canonical_var(DUMMY_SP, cv_info, universe_map) + } + + fn insert_hidden_type( + &self, + opaque_type_key: ty::OpaqueTypeKey<'tcx>, + param_env: ty::ParamEnv<'tcx>, + hidden_ty: Ty<'tcx>, + goals: &mut Vec<Goal<'tcx, ty::Predicate<'tcx>>>, + ) -> Result<(), NoSolution> { + self.0 + .insert_hidden_type(opaque_type_key, DUMMY_SP, param_env, hidden_ty, goals) + .map_err(|_| NoSolution) + } + + fn add_item_bounds_for_hidden_type( + &self, + def_id: DefId, + args: ty::GenericArgsRef<'tcx>, + param_env: ty::ParamEnv<'tcx>, + hidden_ty: Ty<'tcx>, + goals: &mut Vec<Goal<'tcx, ty::Predicate<'tcx>>>, + ) { + self.0.add_item_bounds_for_hidden_type(def_id, args, param_env, hidden_ty, goals); + } + + fn inject_new_hidden_type_unchecked(&self, key: ty::OpaqueTypeKey<'tcx>, hidden_ty: Ty<'tcx>) { + self.0.inject_new_hidden_type_unchecked( + key, + ty::OpaqueHiddenType { ty: hidden_ty, span: DUMMY_SP }, + ) + } + + fn reset_opaque_types(&self) { + let _ = self.take_opaque_types(); + } + + fn trait_ref_is_knowable<E: std::fmt::Debug>( + &self, + trait_ref: ty::TraitRef<'tcx>, + lazily_normalize_ty: impl FnMut(Ty<'tcx>) -> Result<Ty<'tcx>, E>, + ) -> Result<bool, E> { + trait_ref_is_knowable(&self.0, trait_ref, lazily_normalize_ty) + .map(|is_knowable| is_knowable.is_ok()) + } + + fn fetch_eligible_assoc_item( + &self, + param_env: ty::ParamEnv<'tcx>, + goal_trait_ref: ty::TraitRef<'tcx>, + trait_assoc_def_id: DefId, + impl_def_id: DefId, + ) -> Result<Option<DefId>, NoSolution> { + let node_item = specialization_graph::assoc_def(self.tcx, impl_def_id, trait_assoc_def_id) + .map_err(|ErrorGuaranteed { .. }| NoSolution)?; + + let eligible = if node_item.is_final() { + // Non-specializable items are always projectable. + true + } else { + // Only reveal a specializable default if we're past type-checking + // and the obligation is monomorphic, otherwise passes such as + // transmute checking and polymorphic MIR optimizations could + // get a result which isn't correct for all monomorphizations. + if param_env.reveal() == Reveal::All { + let poly_trait_ref = self.resolve_vars_if_possible(goal_trait_ref); + !poly_trait_ref.still_further_specializable() + } else { + trace!(?node_item.item.def_id, "not eligible due to default"); + false + } + }; + + // FIXME: Check for defaultness here may cause diagnostics problems. + if eligible { Ok(Some(node_item.item.def_id)) } else { Ok(None) } } } diff --git a/compiler/rustc_trait_selection/src/solve/inspect.rs b/compiler/rustc_trait_selection/src/solve/inspect.rs new file mode 100644 index 00000000000..f100a8c2ff0 --- /dev/null +++ b/compiler/rustc_trait_selection/src/solve/inspect.rs @@ -0,0 +1,4 @@ +pub use rustc_next_trait_solver::solve::inspect::*; + +mod analyse; +pub use analyse::*; diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index db8f15118e1..cb621487125 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -13,19 +13,16 @@ use rustc_ast_ir::try_visit; use rustc_ast_ir::visit::VisitorResult; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk}; use rustc_macros::extension; -use rustc_middle::traits::query::NoSolution; -use rustc_middle::traits::solve::{inspect, QueryResult}; -use rustc_middle::traits::solve::{Certainty, Goal, MaybeCause}; +use rustc_middle::traits::solve::{Certainty, Goal, GoalSource, NoSolution, QueryResult}; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{TyCtxt, TypeFoldable}; use rustc_middle::{bug, ty}; use rustc_next_trait_solver::resolve::EagerResolver; +use rustc_next_trait_solver::solve::inspect::{self, instantiate_canonical_state}; +use rustc_next_trait_solver::solve::{GenerateProofTree, MaybeCause, SolverDelegateEvalExt as _}; use rustc_span::{Span, DUMMY_SP}; -use crate::solve::eval_ctxt::canonical; use crate::solve::infcx::SolverDelegate; -use crate::solve::{EvalCtxt, GoalEvaluationKind, GoalSource}; -use crate::solve::{GenerateProofTree, InferCtxtEvalExt}; use crate::traits::ObligationCtxt; pub struct InspectConfig { @@ -33,7 +30,7 @@ pub struct InspectConfig { } pub struct InspectGoal<'a, 'tcx> { - infcx: &'a InferCtxt<'tcx>, + infcx: &'a SolverDelegate<'tcx>, depth: usize, orig_values: Vec<ty::GenericArg<'tcx>>, goal: Goal<'tcx, ty::Predicate<'tcx>>, @@ -163,16 +160,10 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { match **step { inspect::ProbeStep::AddGoal(source, goal) => instantiated_goals.push(( source, - canonical::instantiate_canonical_state( - infcx, - span, - param_env, - &mut orig_values, - goal, - ), + instantiate_canonical_state(infcx, span, param_env, &mut orig_values, goal), )), inspect::ProbeStep::RecordImplArgs { impl_args } => { - opt_impl_args = Some(canonical::instantiate_canonical_state( + opt_impl_args = Some(instantiate_canonical_state( infcx, span, param_env, @@ -185,13 +176,8 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { } } - let () = canonical::instantiate_canonical_state( - infcx, - span, - param_env, - &mut orig_values, - self.final_state, - ); + let () = + instantiate_canonical_state(infcx, span, param_env, &mut orig_values, self.final_state); if let Some(term_hack) = self.goal.normalizes_to_term_hack { // FIXME: We ignore the expected term of `NormalizesTo` goals @@ -200,9 +186,8 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { let _ = term_hack.constrain(infcx, span, param_env); } - let opt_impl_args = opt_impl_args.map(|impl_args| { - impl_args.fold_with(&mut EagerResolver::new(<&SolverDelegate<'tcx>>::from(infcx))) - }); + let opt_impl_args = + opt_impl_args.map(|impl_args| impl_args.fold_with(&mut EagerResolver::new(infcx))); let goals = instantiated_goals .into_iter() @@ -221,16 +206,7 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> { // instantiating the candidate it is already constrained to the result of another // candidate. let proof_tree = infcx - .probe(|_| { - EvalCtxt::enter_root(infcx, GenerateProofTree::Yes, |ecx| { - ecx.evaluate_goal_raw( - GoalEvaluationKind::Root, - GoalSource::Misc, - goal, - ) - }) - }) - .1; + .probe(|_| infcx.evaluate_root_goal_raw(goal, GenerateProofTree::Yes).1); InspectGoal::new( infcx, self.goal.depth + 1, @@ -390,6 +366,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { normalizes_to_term_hack: Option<NormalizesToTermHack<'tcx>>, source: GoalSource, ) -> Self { + let infcx = <&SolverDelegate<'tcx>>::from(infcx); + let inspect::GoalEvaluation { uncanonicalized_goal, orig_values, evaluation } = root; let result = evaluation.result.and_then(|ok| { if let Some(term_hack) = normalizes_to_term_hack { @@ -405,8 +383,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> { infcx, depth, orig_values, - goal: uncanonicalized_goal - .fold_with(&mut EagerResolver::new(<&SolverDelegate<'tcx>>::from(infcx))), + goal: uncanonicalized_goal.fold_with(&mut EagerResolver::new(infcx)), result, evaluation_kind: evaluation.kind, normalizes_to_term_hack, @@ -452,7 +429,8 @@ impl<'tcx> InferCtxt<'tcx> { depth: usize, visitor: &mut V, ) -> V::Result { - let (_, proof_tree) = self.evaluate_root_goal(goal, GenerateProofTree::Yes); + let (_, proof_tree) = + <&SolverDelegate<'tcx>>::from(self).evaluate_root_goal(goal, GenerateProofTree::Yes); let proof_tree = proof_tree.unwrap(); visitor.visit_goal(&InspectGoal::new(self, depth, proof_tree, None, GoalSource::Misc)) } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index b4019585771..fe047f9966f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -19,7 +19,7 @@ use super::{ }; use crate::infer::{InferCtxt, InferOk, TypeFreshener}; -use crate::solve::InferCtxtSelectExt; +use crate::solve::InferCtxtSelectExt as _; use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::normalize::normalize_with_depth; use crate::traits::normalize::normalize_with_depth_to; |
