diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 51bbe35121878..c2219fba023bc 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -218,6 +218,13 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.check_and_mk_args(def_id, args) } + fn intern_canonical_goal_evaluation_step( + self, + step: solve::inspect::CanonicalGoalEvaluationStep>, + ) -> &'tcx solve::inspect::CanonicalGoalEvaluationStep> { + self.arena.alloc(step) + } + fn parent(self, def_id: Self::DefId) -> Self::DefId { self.parent(def_id) } diff --git a/compiler/rustc_trait_selection/src/solve/alias_relate.rs b/compiler/rustc_trait_selection/src/solve/alias_relate.rs index 33b30bef68328..4d7e2fc2cefab 100644 --- a/compiler/rustc_trait_selection/src/solve/alias_relate.rs +++ b/compiler/rustc_trait_selection/src/solve/alias_relate.rs @@ -26,7 +26,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { &mut self, goal: Goal<'tcx, (ty::Term<'tcx>, ty::Term<'tcx>, ty::AliasRelationDirection)>, ) -> QueryResult<'tcx> { - let tcx = self.tcx(); + let tcx = self.interner(); let Goal { param_env, predicate: (lhs, rhs, direction) } = goal; debug_assert!(lhs.to_alias_term().is_some() || rhs.to_alias_term().is_some()); diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index 1152441069280..aae6fa9f635b6 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -83,7 +83,7 @@ pub(super) trait GoalKind<'tcx>: assumption: ty::Clause<'tcx>, ) -> Result, NoSolution> { Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| { - let tcx = ecx.tcx(); + let tcx = ecx.interner(); let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else { bug!("expected object type in `probe_and_consider_object_bound_candidate`"); }; @@ -288,8 +288,10 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { return self.forced_ambiguity(MaybeCause::Ambiguity).into_iter().collect(); } - let goal: Goal<'tcx, G> = - goal.with(self.tcx(), goal.predicate.with_self_ty(self.tcx(), normalized_self_ty)); + let goal: Goal<'tcx, G> = goal.with( + self.interner(), + goal.predicate.with_self_ty(self.interner(), normalized_self_ty), + ); // Vars that show up in the rest of the goal substs may have been constrained by // normalizing the self type as well, since type variables are not uniquified. let goal = self.resolve_vars_if_possible(goal); @@ -339,7 +341,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { goal: Goal<'tcx, G>, candidates: &mut Vec>, ) { - let tcx = self.tcx(); + let tcx = self.interner(); let self_ty = goal.predicate.self_ty(); let trait_impls = tcx.trait_impls_of(goal.predicate.trait_def_id(tcx)); let mut consider_impls_for_simplified_type = |simp| { @@ -455,7 +457,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { goal: Goal<'tcx, G>, candidates: &mut Vec>, ) { - let tcx = self.tcx(); + let tcx = self.interner(); let trait_impls = tcx.trait_impls_of(goal.predicate.trait_def_id(tcx)); for &impl_def_id in trait_impls.blanket_impls() { // For every `default impl`, there's always a non-default `impl` @@ -478,7 +480,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { goal: Goal<'tcx, G>, candidates: &mut Vec>, ) { - let tcx = self.tcx(); + let tcx = self.interner(); let lang_items = tcx.lang_items(); let trait_def_id = goal.predicate.trait_def_id(tcx); @@ -505,9 +507,9 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { G::consider_builtin_pointer_like_candidate(self, goal) } else if lang_items.fn_ptr_trait() == Some(trait_def_id) { G::consider_builtin_fn_ptr_trait_candidate(self, goal) - } else if let Some(kind) = self.tcx().fn_trait_kind_from_def_id(trait_def_id) { + } else if let Some(kind) = self.interner().fn_trait_kind_from_def_id(trait_def_id) { G::consider_builtin_fn_trait_candidates(self, goal, kind) - } else if let Some(kind) = self.tcx().async_fn_trait_kind_from_def_id(trait_def_id) { + } else if let Some(kind) = self.interner().async_fn_trait_kind_from_def_id(trait_def_id) { G::consider_builtin_async_fn_trait_candidates(self, goal, kind) } else if lang_items.async_fn_kind_helper() == Some(trait_def_id) { G::consider_builtin_async_fn_kind_helper_candidate(self, goal) @@ -634,7 +636,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty), ty::Alias(ty::Inherent | ty::Weak, _) => { - self.tcx().sess.dcx().span_delayed_bug( + self.interner().sess.dcx().span_delayed_bug( DUMMY_SP, format!("could not normalize {self_ty}, it is not WF"), ); @@ -643,7 +645,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { }; for assumption in - self.tcx().item_bounds(alias_ty.def_id).instantiate(self.tcx(), alias_ty.args) + self.interner().item_bounds(alias_ty.def_id).instantiate(self.interner(), alias_ty.args) { candidates.extend(G::probe_and_consider_implied_clause( self, @@ -673,7 +675,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { goal: Goal<'tcx, G>, candidates: &mut Vec>, ) { - let tcx = self.tcx(); + let tcx = self.interner(); if !tcx.trait_def(goal.predicate.trait_def_id(tcx)).implement_via_object { return; } @@ -764,7 +766,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { goal: Goal<'tcx, G>, candidates: &mut Vec>, ) { - let tcx = self.tcx(); + let tcx = self.interner(); candidates.extend(self.probe_trait_candidate(CandidateSource::CoherenceUnknowable).enter( |ecx| { @@ -793,7 +795,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { goal: Goal<'tcx, G>, candidates: &mut Vec>, ) { - let tcx = self.tcx(); + let tcx = self.interner(); let trait_goal: Goal<'tcx, ty::TraitPredicate<'tcx>> = goal.with(tcx, goal.predicate.trait_ref(tcx)); diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs index 6f68875e6f63f..64d5f725a1f4d 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -22,7 +22,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>( ecx: &EvalCtxt<'_, InferCtxt<'tcx>>, ty: Ty<'tcx>, ) -> Result>>, NoSolution> { - let tcx = ecx.tcx(); + let tcx = ecx.interner(); match *ty.kind() { ty::Uint(_) | ty::Int(_) @@ -75,7 +75,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>( } ty::CoroutineWitness(def_id, args) => Ok(ecx - .tcx() + .interner() .bound_coroutine_hidden_types(def_id) .map(|bty| bty.instantiate(tcx, args)) .collect()), @@ -151,8 +151,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>( // "best effort" optimization and `sized_constraint` may return `Some`, even // if the ADT is sized for all possible args. ty::Adt(def, args) => { - if let Some(sized_crit) = def.sized_constraint(ecx.tcx()) { - Ok(vec![ty::Binder::dummy(sized_crit.instantiate(ecx.tcx(), args))]) + if let Some(sized_crit) = def.sized_constraint(ecx.interner()) { + Ok(vec![ty::Binder::dummy(sized_crit.instantiate(ecx.interner(), args))]) } else { Ok(vec![]) } @@ -210,10 +210,10 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>( // only when `coroutine_clone` is enabled and the coroutine is movable // impl Copy/Clone for Coroutine where T: Copy/Clone forall T in (upvars, witnesses) - ty::Coroutine(def_id, args) => match ecx.tcx().coroutine_movability(def_id) { + ty::Coroutine(def_id, args) => match ecx.interner().coroutine_movability(def_id) { Movability::Static => Err(NoSolution), Movability::Movable => { - if ecx.tcx().features().coroutine_clone { + if ecx.interner().features().coroutine_clone { let coroutine = args.as_coroutine(); Ok(vec![ ty::Binder::dummy(coroutine.tupled_upvars_ty()), @@ -227,9 +227,9 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>( // impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types ty::CoroutineWitness(def_id, args) => Ok(ecx - .tcx() + .interner() .bound_coroutine_hidden_types(def_id) - .map(|bty| bty.instantiate(ecx.tcx(), args)) + .map(|bty| bty.instantiate(ecx.interner(), args)) .collect()), } } @@ -666,7 +666,7 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>( trait_ref: ty::TraitRef<'tcx>, object_bound: &'tcx ty::List>, ) -> Vec>> { - let tcx = ecx.tcx(); + let tcx = ecx.interner(); let mut requirements = vec![]; requirements.extend( tcx.super_predicates_of(trait_ref.def_id).instantiate(tcx, trait_ref.args).predicates, @@ -722,7 +722,7 @@ struct ReplaceProjectionWith<'a, 'tcx> { impl<'tcx> TypeFolder> for ReplaceProjectionWith<'_, 'tcx> { fn interner(&self) -> TyCtxt<'tcx> { - self.ecx.tcx() + self.ecx.interner() } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { @@ -739,7 +739,7 @@ impl<'tcx> TypeFolder> for ReplaceProjectionWith<'_, 'tcx> { .eq_and_get_goals( self.param_env, alias_ty, - proj.projection_term.expect_ty(self.ecx.tcx()), + proj.projection_term.expect_ty(self.ecx.interner()), ) .expect("expected to be able to unify goal projection with dyn's projection"), ); diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index f6ec654908450..4977807aa6cf2 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -16,7 +16,6 @@ use crate::solve::{ use rustc_data_structures::fx::FxHashSet; use rustc_index::IndexVec; use rustc_infer::infer::canonical::query_response::make_query_region_constraints; -use rustc_infer::infer::canonical::CanonicalVarValues; use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints}; use rustc_infer::infer::RegionVariableOrigin; use rustc_infer::infer::{InferCtxt, InferOk}; @@ -32,22 +31,24 @@ use rustc_middle::ty::{self, BoundVar, GenericArgKind, Ty, TyCtxt, TypeFoldable} use rustc_next_trait_solver::canonicalizer::{CanonicalizeMode, Canonicalizer}; use rustc_next_trait_solver::resolve::EagerResolver; use rustc_span::{Span, DUMMY_SP}; +use rustc_type_ir::CanonicalVarValues; +use rustc_type_ir::{InferCtxtLike, Interner}; use std::assert_matches::assert_matches; use std::iter; use std::ops::Deref; trait ResponseT<'tcx> { - fn var_values(&self) -> CanonicalVarValues<'tcx>; + fn var_values(&self) -> CanonicalVarValues>; } impl<'tcx> ResponseT<'tcx> for Response> { - fn var_values(&self) -> CanonicalVarValues<'tcx> { + fn var_values(&self) -> CanonicalVarValues> { self.var_values } } impl<'tcx, T> ResponseT<'tcx> for inspect::State, T> { - fn var_values(&self) -> CanonicalVarValues<'tcx> { + fn var_values(&self) -> CanonicalVarValues> { self.var_values } } @@ -71,7 +72,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { QueryInput { goal, predefined_opaques_in_body: self - .tcx() + .interner() .mk_predefined_opaques_in_body(PredefinedOpaquesData { opaque_types }), }, ); @@ -144,7 +145,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { Response { var_values, certainty, - external_constraints: self.tcx().mk_external_constraints(external_constraints), + external_constraints: self.interner().mk_external_constraints(external_constraints), }, ); @@ -160,7 +161,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { maybe_cause: MaybeCause, ) -> CanonicalResponse<'tcx> { response_no_constraints_raw( - self.tcx(), + self.interner(), self.max_input_universe, self.variables, Certainty::Maybe(maybe_cause), @@ -194,7 +195,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { let region_obligations = self.infcx.inner.borrow().region_obligations().to_owned(); let mut region_constraints = self.infcx.with_region_constraints(|region_constraints| { make_query_region_constraints( - self.tcx(), + self.interner(), region_obligations.iter().map(|r_o| { (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category()) }), @@ -239,7 +240,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { ); let Response { var_values, external_constraints, certainty } = - response.instantiate(self.tcx(), &instantiation); + response.instantiate(self.interner(), &instantiation); Self::unify_query_var_values(self.infcx, param_env, &original_values, var_values); @@ -260,7 +261,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { infcx: &InferCtxt<'tcx>, original_values: &[ty::GenericArg<'tcx>], response: &Canonical<'tcx, T>, - ) -> CanonicalVarValues<'tcx> { + ) -> CanonicalVarValues> { // FIXME: Longterm canonical queries should deal with all placeholders // created inside of the query directly instead of returning them to the // caller. @@ -354,7 +355,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, original_values: &[ty::GenericArg<'tcx>], - var_values: CanonicalVarValues<'tcx>, + var_values: CanonicalVarValues>, ) { assert_eq!(original_values.len(), var_values.len()); @@ -393,13 +394,18 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { /// evaluating a goal. The `var_values` not only include the bound variables /// of the query input, but also contain all unconstrained inference vars /// created while evaluating this goal. -pub(in crate::solve) fn make_canonical_state<'tcx, T: TypeFoldable>>( - infcx: &InferCtxt<'tcx>, - var_values: &[ty::GenericArg<'tcx>], +pub(in crate::solve) fn make_canonical_state( + infcx: &Infcx, + var_values: &[I::GenericArg], max_input_universe: ty::UniverseIndex, data: T, -) -> inspect::CanonicalState, T> { - let var_values = CanonicalVarValues { var_values: infcx.tcx.mk_args(var_values) }; +) -> inspect::CanonicalState +where + Infcx: InferCtxtLike, + I: Interner, + T: TypeFoldable, +{ + let var_values = CanonicalVarValues { var_values: infcx.interner().mk_args(var_values) }; let state = inspect::State { var_values, data }; let state = state.fold_with(&mut EagerResolver::new(infcx)); Canonicalizer::canonicalize( diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 4cf0af948119d..98ba3feeca132 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -98,7 +98,7 @@ pub struct EvalCtxt< // evaluation code. tainted: Result<(), NoSolution>, - pub(super) inspect: ProofTreeBuilder, + pub(super) inspect: ProofTreeBuilder, } #[derive(derivative::Derivative)] @@ -218,7 +218,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { tcx: TyCtxt<'tcx>, search_graph: &'a mut search_graph::SearchGraph>, canonical_input: CanonicalInput<'tcx>, - canonical_goal_evaluation: &mut ProofTreeBuilder>, + canonical_goal_evaluation: &mut ProofTreeBuilder>, f: impl FnOnce(&mut EvalCtxt<'_, InferCtxt<'tcx>>, Goal<'tcx, ty::Predicate<'tcx>>) -> R, ) -> R { let intercrate = match search_graph.solver_mode() { @@ -280,7 +280,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { tcx: TyCtxt<'tcx>, search_graph: &'a mut search_graph::SearchGraph>, canonical_input: CanonicalInput<'tcx>, - goal_evaluation: &mut ProofTreeBuilder>, + goal_evaluation: &mut ProofTreeBuilder>, ) -> QueryResult<'tcx> { let mut canonical_goal_evaluation = goal_evaluation.new_canonical_goal_evaluation(canonical_input); @@ -347,7 +347,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { let mut goal_evaluation = self.inspect.new_goal_evaluation(goal, &orig_values, goal_evaluation_kind); let canonical_response = EvalCtxt::evaluate_canonical_goal( - self.tcx(), + self.interner(), self.search_graph, canonical_goal, &mut goal_evaluation, @@ -450,7 +450,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { } } else { self.infcx.enter_forall(kind, |kind| { - let goal = goal.with(self.tcx(), ty::Binder::dummy(kind)); + let goal = goal.with(self.interner(), ty::Binder::dummy(kind)); self.add_goal(GoalSource::InstantiateHigherRanked, goal); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) @@ -511,7 +511,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { /// /// Goals for the next step get directly added to the nested goals of the `EvalCtxt`. fn evaluate_added_goals_step(&mut self) -> Result, NoSolution> { - let tcx = self.tcx(); + let tcx = self.interner(); let mut goals = core::mem::take(&mut self.nested_goals); // If this loop did not result in any progress, what's our final certainty. @@ -597,11 +597,13 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { } } -impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { - pub(super) fn tcx(&self) -> TyCtxt<'tcx> { - self.infcx.tcx +impl, I: Interner> EvalCtxt<'_, Infcx> { + pub(super) fn interner(&self) -> I { + self.infcx.interner() } +} +impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { pub(super) fn next_ty_infer(&mut self) -> Ty<'tcx> { let ty = self.infcx.next_ty_var(DUMMY_SP); self.inspect.add_var_value(ty); @@ -759,7 +761,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { // NOTE: this check is purely an optimization, the structural eq would // always fail if the term is not an inference variable. if term.is_infer() { - let tcx = self.tcx(); + let tcx = self.interner(); // We need to relate `alias` to `term` treating only the outermost // constructor as rigid, relating any contained generic arguments as // normal. We do this by first structurally equating the `term` @@ -1054,10 +1056,10 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { ) -> Option> { use rustc_middle::mir::interpret::ErrorHandled; match self.infcx.const_eval_resolve(param_env, unevaluated, DUMMY_SP) { - Ok(Some(val)) => Some(ty::Const::new_value(self.tcx(), val, ty)), + Ok(Some(val)) => Some(ty::Const::new_value(self.interner(), val, ty)), Ok(None) | Err(ErrorHandled::TooGeneric(_)) => None, Err(ErrorHandled::Reported(e, _)) => { - Some(ty::Const::new_error(self.tcx(), e.into(), ty)) + Some(ty::Const::new_error(self.interner(), e.into(), ty)) } } } @@ -1070,7 +1072,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { principal: ty::PolyTraitRef<'tcx>, mut supertrait_visitor: impl FnMut(&mut Self, ty::PolyTraitRef<'tcx>, usize, Option), ) { - let tcx = self.tcx(); + let tcx = self.interner(); let mut offset = 0; prepare_vtable_segments::<()>(tcx, principal, |segment| { match segment { @@ -1112,7 +1114,7 @@ struct ReplaceAliasWithInfer<'me, 'a, 'tcx> { impl<'tcx> TypeFolder> for ReplaceAliasWithInfer<'_, '_, 'tcx> { fn interner(&self) -> TyCtxt<'tcx> { - self.ecx.tcx() + self.ecx.interner() } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { diff --git a/compiler/rustc_trait_selection/src/solve/inspect/build.rs b/compiler/rustc_trait_selection/src/solve/inspect/build.rs index 3c63336264831..84c04900ae484 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/build.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/build.rs @@ -3,18 +3,16 @@ //! This code is *a bit* of a mess and can hopefully be //! mostly ignored. For a general overview of how it works, //! see the comment on [ProofTreeBuilder]. +use std::marker::PhantomData; use std::mem; use crate::solve::eval_ctxt::canonical; use crate::solve::{self, inspect, GenerateProofTree}; -use rustc_infer::infer::InferCtxt; use rustc_middle::bug; -use rustc_middle::infer::canonical::CanonicalVarValues; -use rustc_middle::ty::{self, TyCtxt}; use rustc_next_trait_solver::solve::{ CanonicalInput, Certainty, Goal, GoalSource, QueryInput, QueryResult, }; -use rustc_type_ir::Interner; +use rustc_type_ir::{self as ty, InferCtxtLike, Interner}; /// The core data structure when building proof trees. /// @@ -36,7 +34,11 @@ use rustc_type_ir::Interner; /// trees. At the end of trait solving `ProofTreeBuilder::finalize` /// is called to recursively convert the whole structure to a /// finished proof tree. -pub(in crate::solve) struct ProofTreeBuilder { +pub(in crate::solve) struct ProofTreeBuilder< + Infcx: InferCtxtLike, + I: Interner = ::Interner, +> { + _infcx: PhantomData, state: Option>>, } @@ -229,36 +231,36 @@ impl WipProbeStep { } } -// FIXME: Genericize this impl. -impl<'tcx> ProofTreeBuilder> { - fn new(state: impl Into>>) -> ProofTreeBuilder> { - ProofTreeBuilder { state: Some(Box::new(state.into())) } +impl, I: Interner> ProofTreeBuilder { + fn new(state: impl Into>) -> ProofTreeBuilder { + ProofTreeBuilder { state: Some(Box::new(state.into())), _infcx: PhantomData } } - fn opt_nested>>>( - &self, - state: impl FnOnce() -> Option, - ) -> Self { + fn opt_nested>>(&self, state: impl FnOnce() -> Option) -> Self { ProofTreeBuilder { state: self.state.as_ref().and_then(|_| Some(state()?.into())).map(Box::new), + _infcx: PhantomData, } } - fn nested>>>(&self, state: impl FnOnce() -> T) -> Self { - ProofTreeBuilder { state: self.state.as_ref().map(|_| Box::new(state().into())) } + fn nested>>(&self, state: impl FnOnce() -> T) -> Self { + ProofTreeBuilder { + state: self.state.as_ref().map(|_| Box::new(state().into())), + _infcx: PhantomData, + } } - fn as_mut(&mut self) -> Option<&mut DebugSolver>> { + fn as_mut(&mut self) -> Option<&mut DebugSolver> { self.state.as_deref_mut() } - pub fn take_and_enter_probe(&mut self) -> ProofTreeBuilder> { - let mut nested = ProofTreeBuilder { state: self.state.take() }; + pub fn take_and_enter_probe(&mut self) -> ProofTreeBuilder { + let mut nested = ProofTreeBuilder { state: self.state.take(), _infcx: PhantomData }; nested.enter_probe(); nested } - pub fn finalize(self) -> Option>> { + pub fn finalize(self) -> Option> { match *self.state? { DebugSolver::GoalEvaluation(wip_goal_evaluation) => { Some(wip_goal_evaluation.finalize()) @@ -267,21 +269,19 @@ impl<'tcx> ProofTreeBuilder> { } } - pub fn new_maybe_root( - generate_proof_tree: GenerateProofTree, - ) -> ProofTreeBuilder> { + pub fn new_maybe_root(generate_proof_tree: GenerateProofTree) -> ProofTreeBuilder { match generate_proof_tree { GenerateProofTree::No => ProofTreeBuilder::new_noop(), GenerateProofTree::Yes => ProofTreeBuilder::new_root(), } } - pub fn new_root() -> ProofTreeBuilder> { + pub fn new_root() -> ProofTreeBuilder { ProofTreeBuilder::new(DebugSolver::Root) } - pub fn new_noop() -> ProofTreeBuilder> { - ProofTreeBuilder { state: None } + pub fn new_noop() -> ProofTreeBuilder { + ProofTreeBuilder { state: None, _infcx: PhantomData } } pub fn is_noop(&self) -> bool { @@ -290,10 +290,10 @@ impl<'tcx> ProofTreeBuilder> { pub(in crate::solve) fn new_goal_evaluation( &mut self, - goal: Goal, ty::Predicate<'tcx>>, - orig_values: &[ty::GenericArg<'tcx>], + goal: Goal, + orig_values: &[I::GenericArg], kind: solve::GoalEvaluationKind, - ) -> ProofTreeBuilder> { + ) -> ProofTreeBuilder { self.opt_nested(|| match kind { solve::GoalEvaluationKind::Root => Some(WipGoalEvaluation { uncanonicalized_goal: goal, @@ -306,8 +306,8 @@ impl<'tcx> ProofTreeBuilder> { pub fn new_canonical_goal_evaluation( &mut self, - goal: CanonicalInput>, - ) -> ProofTreeBuilder> { + goal: CanonicalInput, + ) -> ProofTreeBuilder { self.nested(|| WipCanonicalGoalEvaluation { goal, kind: None, @@ -318,12 +318,13 @@ impl<'tcx> ProofTreeBuilder> { pub fn finalize_canonical_goal_evaluation( &mut self, - tcx: TyCtxt<'tcx>, - ) -> Option<&'tcx inspect::CanonicalGoalEvaluationStep>> { + tcx: I, + ) -> Option { self.as_mut().map(|this| match this { DebugSolver::CanonicalGoalEvaluation(evaluation) => { let final_revision = mem::take(&mut evaluation.final_revision).unwrap(); - let final_revision = &*tcx.arena.alloc(final_revision.finalize()); + let final_revision = + tcx.intern_canonical_goal_evaluation_step(final_revision.finalize()); let kind = WipCanonicalGoalEvaluationKind::Interned { final_revision }; assert_eq!(evaluation.kind.replace(kind), None); final_revision @@ -334,7 +335,7 @@ impl<'tcx> ProofTreeBuilder> { pub fn canonical_goal_evaluation( &mut self, - canonical_goal_evaluation: ProofTreeBuilder>, + canonical_goal_evaluation: ProofTreeBuilder, ) { if let Some(this) = self.as_mut() { match (this, *canonical_goal_evaluation.state.unwrap()) { @@ -350,10 +351,7 @@ impl<'tcx> ProofTreeBuilder> { } } - pub fn canonical_goal_evaluation_kind( - &mut self, - kind: WipCanonicalGoalEvaluationKind>, - ) { + pub fn canonical_goal_evaluation_kind(&mut self, kind: WipCanonicalGoalEvaluationKind) { if let Some(this) = self.as_mut() { match this { DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => { @@ -364,7 +362,7 @@ impl<'tcx> ProofTreeBuilder> { } } - pub fn goal_evaluation(&mut self, goal_evaluation: ProofTreeBuilder>) { + pub fn goal_evaluation(&mut self, goal_evaluation: ProofTreeBuilder) { if let Some(this) = self.as_mut() { match this { DebugSolver::Root => *this = *goal_evaluation.state.unwrap(), @@ -378,9 +376,9 @@ impl<'tcx> ProofTreeBuilder> { pub fn new_goal_evaluation_step( &mut self, - var_values: CanonicalVarValues<'tcx>, - instantiated_goal: QueryInput, ty::Predicate<'tcx>>, - ) -> ProofTreeBuilder> { + var_values: ty::CanonicalVarValues, + instantiated_goal: QueryInput, + ) -> ProofTreeBuilder { self.nested(|| WipCanonicalGoalEvaluationStep { var_values: var_values.var_values.to_vec(), instantiated_goal, @@ -394,7 +392,7 @@ impl<'tcx> ProofTreeBuilder> { }) } - pub fn goal_evaluation_step(&mut self, goal_evaluation_step: ProofTreeBuilder>) { + pub fn goal_evaluation_step(&mut self, goal_evaluation_step: ProofTreeBuilder) { if let Some(this) = self.as_mut() { match (this, *goal_evaluation_step.state.unwrap()) { ( @@ -408,7 +406,7 @@ impl<'tcx> ProofTreeBuilder> { } } - pub fn add_var_value>>(&mut self, arg: T) { + pub fn add_var_value>(&mut self, arg: T) { match self.as_mut() { None => {} Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { @@ -435,7 +433,7 @@ impl<'tcx> ProofTreeBuilder> { } } - pub fn probe_kind(&mut self, probe_kind: inspect::ProbeKind>) { + pub fn probe_kind(&mut self, probe_kind: inspect::ProbeKind) { match self.as_mut() { None => {} Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { @@ -446,11 +444,7 @@ impl<'tcx> ProofTreeBuilder> { } } - pub fn probe_final_state( - &mut self, - infcx: &InferCtxt<'tcx>, - max_input_universe: ty::UniverseIndex, - ) { + pub fn probe_final_state(&mut self, infcx: &Infcx, max_input_universe: ty::UniverseIndex) { match self.as_mut() { None => {} Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { @@ -469,24 +463,24 @@ impl<'tcx> ProofTreeBuilder> { pub fn add_normalizes_to_goal( &mut self, - infcx: &InferCtxt<'tcx>, + infcx: &Infcx, max_input_universe: ty::UniverseIndex, - goal: Goal, ty::NormalizesTo<'tcx>>, + goal: Goal>, ) { self.add_goal( infcx, max_input_universe, GoalSource::Misc, - goal.with(infcx.tcx, goal.predicate), + goal.with(infcx.interner(), goal.predicate), ); } pub fn add_goal( &mut self, - infcx: &InferCtxt<'tcx>, + infcx: &Infcx, max_input_universe: ty::UniverseIndex, source: GoalSource, - goal: Goal, ty::Predicate<'tcx>>, + goal: Goal, ) { match self.as_mut() { None => {} @@ -505,9 +499,9 @@ impl<'tcx> ProofTreeBuilder> { pub(crate) fn record_impl_args( &mut self, - infcx: &InferCtxt<'tcx>, + infcx: &Infcx, max_input_universe: ty::UniverseIndex, - impl_args: ty::GenericArgsRef<'tcx>, + impl_args: I::GenericArgs, ) { match self.as_mut() { Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { @@ -540,7 +534,7 @@ impl<'tcx> ProofTreeBuilder> { } } - pub fn finish_probe(mut self) -> ProofTreeBuilder> { + pub fn finish_probe(mut self) -> ProofTreeBuilder { match self.as_mut() { None => {} Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { @@ -555,7 +549,7 @@ impl<'tcx> ProofTreeBuilder> { self } - pub fn query_result(&mut self, result: QueryResult>) { + pub fn query_result(&mut self, result: QueryResult) { if let Some(this) = self.as_mut() { match this { DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => { diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 60722d3618f9a..a432090f78cd3 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -133,7 +133,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> { } fn compute_object_safe_goal(&mut self, trait_def_id: DefId) -> QueryResult<'tcx> { - if self.tcx().check_is_object_safe(trait_def_id) { + if self.interner().check_is_object_safe(trait_def_id) { self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } else { Err(NoSolution) @@ -274,7 +274,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { if let ty::Alias(..) = ty.kind() { let normalized_ty = self.next_ty_infer(); let alias_relate_goal = Goal::new( - self.tcx(), + self.interner(), param_env, ty::PredicateKind::AliasRelate( ty.into(), diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs index c9621e705e575..362c4072278d6 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs @@ -12,7 +12,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { if let Some(normalized_const) = self.try_const_eval_resolve( goal.param_env, ty::UnevaluatedConst::new(goal.predicate.alias.def_id, goal.predicate.alias.args), - self.tcx() + self.interner() .type_of(goal.predicate.alias.def_id) .no_bound_vars() .expect("const ty should not rely on other generics"), diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs index 2146a2c2f0819..41b2b9cd4d260 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs @@ -15,7 +15,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { &mut self, goal: Goal<'tcx, ty::NormalizesTo<'tcx>>, ) -> QueryResult<'tcx> { - let tcx = self.tcx(); + let tcx = self.interner(); let inherent = goal.predicate.alias.expect_ty(tcx); let impl_def_id = tcx.parent(inherent.def_id); diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index 7ef8373663ba5..7fd2a3801cc4c 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -54,7 +54,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { &mut self, goal: Goal<'tcx, NormalizesTo<'tcx>>, ) -> QueryResult<'tcx> { - match goal.predicate.alias.kind(self.tcx()) { + match goal.predicate.alias.kind(self.interner()) { ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => { let candidates = self.assemble_and_evaluate_candidates(goal); self.merge_candidates(candidates) @@ -107,7 +107,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ) -> Result, NoSolution> { if let Some(projection_pred) = assumption.as_projection_clause() { if projection_pred.projection_def_id() == goal.predicate.def_id() { - let tcx = ecx.tcx(); + let tcx = ecx.interner(); ecx.probe_trait_candidate(source).enter(|ecx| { let assumption_projection_pred = ecx.instantiate_binder_with_infer(projection_pred); @@ -142,7 +142,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { goal: Goal<'tcx, NormalizesTo<'tcx>>, impl_def_id: DefId, ) -> Result, NoSolution> { - let tcx = ecx.tcx(); + let tcx = ecx.interner(); let goal_trait_ref = goal.predicate.alias.trait_ref(tcx); let impl_trait_header = tcx.impl_trait_header(impl_def_id).unwrap(); @@ -290,8 +290,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, ) -> Result, NoSolution> { - ecx.tcx().dcx().span_delayed_bug( - ecx.tcx().def_span(goal.predicate.def_id()), + ecx.interner().dcx().span_delayed_bug( + ecx.interner().def_span(goal.predicate.def_id()), "associated types not allowed on auto traits", ); Err(NoSolution) @@ -337,7 +337,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { goal: Goal<'tcx, Self>, goal_kind: ty::ClosureKind, ) -> Result, NoSolution> { - let tcx = ecx.tcx(); + let tcx = ecx.interner(); let tupled_inputs_and_output = match structural_traits::extract_tupled_inputs_and_output_from_callable( tcx, @@ -380,7 +380,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { goal: Goal<'tcx, Self>, goal_kind: ty::ClosureKind, ) -> Result, NoSolution> { - let tcx = ecx.tcx(); + let tcx = ecx.interner(); let env_region = match goal_kind { ty::ClosureKind::Fn | ty::ClosureKind::FnMut => goal.predicate.alias.args.region_at(2), @@ -493,7 +493,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { } let upvars_ty = ty::CoroutineClosureSignature::tupled_upvars_by_closure_kind( - ecx.tcx(), + ecx.interner(), goal_kind, tupled_inputs_ty.expect_ty(), tupled_upvars_ty.expect_ty(), @@ -518,7 +518,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, goal: Goal<'tcx, Self>, ) -> Result, NoSolution> { - let tcx = ecx.tcx(); + let tcx = ecx.interner(); let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None); assert_eq!(metadata_def_id, goal.predicate.def_id()); ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { @@ -606,7 +606,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { }; // Coroutines are not futures unless they come from `async` desugaring - let tcx = ecx.tcx(); + let tcx = ecx.interner(); if !tcx.coroutine_is_async(def_id) { return Err(NoSolution); } @@ -618,7 +618,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, ty::ProjectionPredicate { - projection_term: ty::AliasTerm::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]), + projection_term: ty::AliasTerm::new( + ecx.interner(), + goal.predicate.def_id(), + [self_ty], + ), term, } .upcast(tcx), @@ -638,7 +642,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { }; // Coroutines are not Iterators unless they come from `gen` desugaring - let tcx = ecx.tcx(); + let tcx = ecx.interner(); if !tcx.coroutine_is_gen(def_id) { return Err(NoSolution); } @@ -650,7 +654,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, ty::ProjectionPredicate { - projection_term: ty::AliasTerm::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]), + projection_term: ty::AliasTerm::new( + ecx.interner(), + goal.predicate.def_id(), + [self_ty], + ), term, } .upcast(tcx), @@ -677,7 +685,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { }; // Coroutines are not AsyncIterators unless they come from `gen` desugaring - let tcx = ecx.tcx(); + let tcx = ecx.interner(); if !tcx.coroutine_is_async_gen(def_id) { return Err(NoSolution); } @@ -713,7 +721,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { }; // `async`-desugared coroutines do not implement the coroutine trait - let tcx = ecx.tcx(); + let tcx = ecx.interner(); if !tcx.is_general_coroutine(def_id) { return Err(NoSolution); } @@ -735,7 +743,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { goal, ty::ProjectionPredicate { projection_term: ty::AliasTerm::new( - ecx.tcx(), + ecx.interner(), goal.predicate.def_id(), [self_ty, coroutine.resume_ty()], ), @@ -784,7 +792,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { | ty::Slice(_) | ty::Dynamic(_, _, _) | ty::Tuple(_) - | ty::Error(_) => self_ty.discriminant_ty(ecx.tcx()), + | ty::Error(_) => self_ty.discriminant_ty(ecx.interner()), // We do not call `Ty::discriminant_ty` on alias, param, or placeholder // types, which return `::Discriminant` @@ -831,7 +839,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { | ty::Str | ty::Slice(_) | ty::Tuple(_) - | ty::Error(_) => self_ty.async_destructor_ty(ecx.tcx(), goal.param_env), + | ty::Error(_) => self_ty.async_destructor_ty(ecx.interner(), goal.param_env), // We do not call `Ty::async_destructor_ty` on alias, param, or placeholder // types, which return `::AsyncDestructor` @@ -887,8 +895,9 @@ fn fetch_eligible_assoc_item_def<'tcx>( trait_assoc_def_id: DefId, impl_def_id: DefId, ) -> Result, NoSolution> { - let node_item = specialization_graph::assoc_def(ecx.tcx(), impl_def_id, trait_assoc_def_id) - .map_err(|ErrorGuaranteed { .. }| NoSolution)?; + let node_item = + specialization_graph::assoc_def(ecx.interner(), impl_def_id, trait_assoc_def_id) + .map_err(|ErrorGuaranteed { .. }| NoSolution)?; let eligible = if node_item.is_final() { // Non-specializable items are always projectable. diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs index 3b83d347276f7..67ec2f3be4814 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs @@ -15,7 +15,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { &mut self, goal: Goal<'tcx, ty::NormalizesTo<'tcx>>, ) -> QueryResult<'tcx> { - let tcx = self.tcx(); + let tcx = self.interner(); let opaque_ty = goal.predicate.alias; let expected = goal.predicate.term.ty().expect("no such thing as an opaque const"); @@ -31,7 +31,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { return Err(NoSolution); } // FIXME: This may have issues when the args contain aliases... - match self.tcx().uses_unique_placeholders_ignoring_regions(opaque_ty.args) { + match self.interner().uses_unique_placeholders_ignoring_regions(opaque_ty.args) { Err(NotUniqueParam::NotParam(param)) if param.is_non_region_infer() => { return self.evaluate_added_goals_and_make_canonical_response( Certainty::AMBIGUOUS, diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/weak_types.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/weak_types.rs index 109a9e9671f08..5442b9ccffc87 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/weak_types.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/weak_types.rs @@ -14,7 +14,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { &mut self, goal: Goal<'tcx, ty::NormalizesTo<'tcx>>, ) -> QueryResult<'tcx> { - let tcx = self.tcx(); + let tcx = self.interner(); let weak_ty = goal.predicate.alias; // Check where clauses diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 8fa78e49dc6e6..cae73cc2d073c 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -11,7 +11,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { &mut self, goal: Goal<'tcx, ProjectionPredicate<'tcx>>, ) -> QueryResult<'tcx> { - let tcx = self.tcx(); + let tcx = self.interner(); let projection_term = goal.predicate.projection_term.to_term(tcx); let goal = goal.with( tcx, diff --git a/compiler/rustc_trait_selection/src/solve/search_graph.rs b/compiler/rustc_trait_selection/src/solve/search_graph.rs index 6be623b6044f0..f1b8bf4676ee7 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph.rs @@ -3,6 +3,7 @@ use std::mem; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_index::Idx; use rustc_index::IndexVec; +use rustc_infer::infer::InferCtxt; use rustc_middle::dep_graph::dep_kinds; use rustc_middle::traits::solve::CacheData; use rustc_middle::traits::solve::EvaluationCache; @@ -261,10 +262,10 @@ impl<'tcx> SearchGraph> { &mut self, tcx: TyCtxt<'tcx>, input: CanonicalInput>, - inspect: &mut ProofTreeBuilder>, + inspect: &mut ProofTreeBuilder>, mut prove_goal: impl FnMut( &mut Self, - &mut ProofTreeBuilder>, + &mut ProofTreeBuilder>, ) -> QueryResult>, ) -> QueryResult> { self.check_invariants(); @@ -426,7 +427,7 @@ impl<'tcx> SearchGraph> { tcx: TyCtxt<'tcx>, input: CanonicalInput>, available_depth: Limit, - inspect: &mut ProofTreeBuilder>, + inspect: &mut ProofTreeBuilder>, ) -> Option>> { let CacheData { result, proof_tree, additional_depth, encountered_overflow } = self .global_cache(tcx) @@ -473,11 +474,11 @@ impl<'tcx> SearchGraph> { &mut self, tcx: TyCtxt<'tcx>, input: CanonicalInput>, - inspect: &mut ProofTreeBuilder>, + inspect: &mut ProofTreeBuilder>, prove_goal: &mut F, ) -> StepResult> where - F: FnMut(&mut Self, &mut ProofTreeBuilder>) -> QueryResult>, + F: FnMut(&mut Self, &mut ProofTreeBuilder>) -> QueryResult>, { let result = prove_goal(self, inspect); let stack_entry = self.pop_stack(); diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index e59eef22f4111..67dd3fa85fa1a 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -42,7 +42,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { goal: Goal<'tcx, TraitPredicate<'tcx>>, impl_def_id: DefId, ) -> Result, NoSolution> { - let tcx = ecx.tcx(); + let tcx = ecx.interner(); let impl_trait_header = tcx.impl_trait_header(impl_def_id).unwrap(); let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup }; @@ -181,7 +181,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { return Err(NoSolution); } - let tcx = ecx.tcx(); + let tcx = ecx.interner(); ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { let nested_obligations = tcx @@ -235,7 +235,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { } // The regions of a type don't affect the size of the type - let tcx = ecx.tcx(); + let tcx = ecx.interner(); // We should erase regions from both the param-env and type, since both // may have infer regions. Specifically, after canonicalizing and instantiating, // early bound regions turn into region vars in both the new and old solver. @@ -296,7 +296,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { return Err(NoSolution); } - let tcx = ecx.tcx(); + let tcx = ecx.interner(); let tupled_inputs_and_output = match structural_traits::extract_tupled_inputs_and_output_from_callable( tcx, @@ -337,7 +337,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { return Err(NoSolution); } - let tcx = ecx.tcx(); + let tcx = ecx.interner(); let (tupled_inputs_and_output_and_coroutine, nested_preds) = structural_traits::extract_tupled_inputs_and_output_from_async_callable( tcx, @@ -447,7 +447,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { }; // Coroutines are not futures unless they come from `async` desugaring - let tcx = ecx.tcx(); + let tcx = ecx.interner(); if !tcx.coroutine_is_async(def_id) { return Err(NoSolution); } @@ -473,7 +473,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { }; // Coroutines are not iterators unless they come from `gen` desugaring - let tcx = ecx.tcx(); + let tcx = ecx.interner(); if !tcx.coroutine_is_gen(def_id) { return Err(NoSolution); } @@ -499,7 +499,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { }; // Coroutines are not iterators unless they come from `gen` desugaring - let tcx = ecx.tcx(); + let tcx = ecx.interner(); if !tcx.coroutine_is_gen(def_id) { return Err(NoSolution); } @@ -523,7 +523,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { }; // Coroutines are not iterators unless they come from `gen` desugaring - let tcx = ecx.tcx(); + let tcx = ecx.interner(); if !tcx.coroutine_is_async_gen(def_id) { return Err(NoSolution); } @@ -550,7 +550,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { }; // `async`-desugared coroutines do not implement the coroutine trait - let tcx = ecx.tcx(); + let tcx = ecx.interner(); if !tcx.is_general_coroutine(def_id) { return Err(NoSolution); } @@ -625,10 +625,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // Erase regions because we compute layouts in `rustc_transmute`, // which will ICE for region vars. - let args = ecx.tcx().erase_regions(goal.predicate.trait_ref.args); + let args = ecx.interner().erase_regions(goal.predicate.trait_ref.args); let Some(assume) = - rustc_transmute::Assume::from_const(ecx.tcx(), goal.param_env, args.const_at(2)) + rustc_transmute::Assume::from_const(ecx.interner(), goal.param_env, args.const_at(2)) else { return Err(NoSolution); }; @@ -675,7 +675,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { return vec![]; }; - let goal = goal.with(ecx.tcx(), (a_ty, b_ty)); + let goal = goal.with(ecx.interner(), (a_ty, b_ty)); match (a_ty.kind(), b_ty.kind()) { (ty::Infer(ty::TyVar(..)), ..) => bug!("unexpected infer {a_ty:?} {b_ty:?}"), @@ -741,7 +741,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { b_data: &'tcx ty::List>, b_region: ty::Region<'tcx>, ) -> Vec> { - let tcx = self.tcx(); + let tcx = self.interner(); let Goal { predicate: (a_ty, _b_ty), .. } = goal; let mut responses = vec![]; @@ -787,7 +787,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { b_data: &'tcx ty::List>, b_region: ty::Region<'tcx>, ) -> Result, NoSolution> { - let tcx = self.tcx(); + let tcx = self.interner(); let Goal { predicate: (a_ty, _), .. } = goal; // Can only unsize to an object-safe trait. @@ -837,8 +837,8 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { let a_auto_traits: FxIndexSet = a_data .auto_traits() .chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| { - supertrait_def_ids(self.tcx(), principal_def_id) - .filter(|def_id| self.tcx().trait_is_auto(*def_id)) + supertrait_def_ids(self.interner(), principal_def_id) + .filter(|def_id| self.interner().trait_is_auto(*def_id)) })) .collect(); @@ -907,7 +907,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { ecx.add_goal( GoalSource::ImplWhereBound, Goal::new( - ecx.tcx(), + ecx.interner(), param_env, ty::Binder::dummy(ty::OutlivesPredicate(a_region, b_region)), ), @@ -956,7 +956,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { a_args: ty::GenericArgsRef<'tcx>, b_args: ty::GenericArgsRef<'tcx>, ) -> Result, NoSolution> { - let tcx = self.tcx(); + let tcx = self.interner(); let Goal { predicate: (_a_ty, b_ty), .. } = goal; let unsizing_params = tcx.unsizing_params_for_adt(def.did()); @@ -1017,7 +1017,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { a_tys: &'tcx ty::List>, b_tys: &'tcx ty::List>, ) -> Result, NoSolution> { - let tcx = self.tcx(); + let tcx = self.interner(); let Goal { predicate: (_a_ty, b_ty), .. } = goal; let (&a_last_ty, a_rest_tys) = a_tys.split_last().unwrap(); @@ -1077,9 +1077,9 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { // takes precedence over the structural auto trait candidate being // assembled. ty::Coroutine(def_id, _) - if Some(goal.predicate.def_id()) == self.tcx().lang_items().unpin_trait() => + if Some(goal.predicate.def_id()) == self.interner().lang_items().unpin_trait() => { - match self.tcx().coroutine_movability(def_id) { + match self.interner().coroutine_movability(def_id) { Movability::Static => Some(Err(NoSolution)), Movability::Movable => Some( self.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { @@ -1124,7 +1124,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { | ty::Tuple(_) | ty::Adt(_, _) => { let mut disqualifying_impl = None; - self.tcx().for_each_relevant_impl( + self.interner().for_each_relevant_impl( goal.predicate.def_id(), goal.predicate.self_ty(), |impl_def_id| { @@ -1164,7 +1164,10 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { .into_iter() .map(|ty| { ecx.enter_forall(ty, |ty| { - goal.with(ecx.tcx(), goal.predicate.with_self_ty(ecx.tcx(), ty)) + goal.with( + ecx.interner(), + goal.predicate.with_self_ty(ecx.interner(), ty), + ) }) }) .collect::>(), diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index e7e893f27daa9..7b1dfecfee2e0 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -132,7 +132,14 @@ pub trait GenericArgs>: } pub trait Predicate>: - Copy + Debug + Hash + Eq + TypeSuperVisitable + TypeSuperFoldable + Flags + Copy + + Debug + + Hash + + Eq + + TypeSuperVisitable + + TypeSuperFoldable + + Flags + + UpcastFrom> { fn is_coinductive(self, interner: I) -> bool; } diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index e49db171a534a..2a228c973d34a 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -3,6 +3,7 @@ use std::fmt::Debug; use std::hash::Hash; use std::ops::Deref; +use crate::fold::TypeFoldable; use crate::inherent::*; use crate::ir_print::IrPrint; use crate::solve::inspect::CanonicalGoalEvaluationStep; @@ -90,7 +91,7 @@ pub trait Interner: type PlaceholderRegion: PlaceholderLike; // Predicates - type ParamEnv: Copy + Debug + Hash + Eq; + type ParamEnv: Copy + Debug + Hash + Eq + TypeFoldable; type Predicate: Predicate; type Clause: Clause; type Clauses: Copy + Debug + Hash + Eq + TypeSuperVisitable + Flags; @@ -114,15 +115,18 @@ pub trait Interner: ) -> (ty::TraitRef, Self::OwnItemArgs); fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs; - fn mk_args_from_iter(self, args: impl Iterator) -> Self::GenericArgs; - fn check_and_mk_args( self, def_id: Self::DefId, args: impl IntoIterator>, ) -> Self::GenericArgs; + fn intern_canonical_goal_evaluation_step( + self, + step: CanonicalGoalEvaluationStep, + ) -> Self::CanonicalGoalEvaluationStepRef; + fn parent(self, def_id: Self::DefId) -> Self::DefId; fn recursion_limit(self) -> usize;