diff --git a/compiler/rustc_trait_selection/src/solve/canonical/canonicalize.rs b/compiler/rustc_trait_selection/src/solve/canonicalize.rs similarity index 100% rename from compiler/rustc_trait_selection/src/solve/canonical/canonicalize.rs rename to compiler/rustc_trait_selection/src/solve/canonicalize.rs diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index 92aff517fbb..e64b4a7656f 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -1,7 +1,6 @@ use rustc_hir::def_id::DefId; use rustc_infer::infer::at::ToTrace; -use rustc_infer::infer::canonical::query_response::make_query_region_constraints; -use rustc_infer::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarValues}; +use rustc_infer::infer::canonical::CanonicalVarValues; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::{ DefineOpaqueTypes, InferCtxt, InferOk, LateBoundRegionConversionTime, TyCtxtInferExt, @@ -9,9 +8,7 @@ use rustc_infer::infer::{ use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::ObligationCause; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; -use rustc_middle::traits::solve::{ - CanonicalGoal, Certainty, ExternalConstraints, ExternalConstraintsData, MaybeCause, QueryResult, -}; +use rustc_middle::traits::solve::{CanonicalGoal, Certainty, MaybeCause, QueryResult}; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, @@ -21,11 +18,12 @@ use std::ops::ControlFlow; use crate::traits::specialization_graph; -use super::canonical::{CanonicalizeMode, Canonicalizer}; use super::search_graph::{self, OverflowHandler}; use super::SolverMode; use super::{search_graph::SearchGraph, Goal}; +mod canonical; + pub struct EvalCtxt<'a, 'tcx> { /// The inference context that backs (mostly) inference and placeholder terms /// instantiated while solving goals. @@ -414,7 +412,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { if let &ty::Infer(ty::TyVar(vid)) = ty.kind() { match self.infcx.probe_ty_var(vid) { Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"), - Err(universe) => universe == self.universe(), + Err(universe) => universe == self.infcx.universe(), } } else { false @@ -424,7 +422,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() { match self.infcx.probe_const_var(vid) { Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"), - Err(universe) => universe == self.universe(), + Err(universe) => universe == self.infcx.universe(), } } else { false @@ -566,22 +564,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.infcx.fresh_substs_for_item(DUMMY_SP, def_id) } - pub(super) fn universe(&self) -> ty::UniverseIndex { - self.infcx.universe() - } - - pub(super) fn create_next_universe(&self) -> ty::UniverseIndex { - self.infcx.create_next_universe() - } - - pub(super) fn instantiate_canonical_var( - &self, - cv_info: CanonicalVarInfo<'tcx>, - universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex, - ) -> ty::GenericArg<'tcx> { - self.infcx.instantiate_canonical_var(DUMMY_SP, cv_info, universe_map) - } - pub(super) fn translate_substs( &self, param_env: ty::ParamEnv<'tcx>, @@ -621,35 +603,4 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { crate::traits::wf::unnormalized_obligations(self.infcx, param_env, arg) .map(|obligations| obligations.into_iter().map(|obligation| obligation.into())) } - - #[instrument(level = "debug", skip(self), ret)] - pub(super) fn compute_external_query_constraints( - &self, - ) -> Result, NoSolution> { - // 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.infcx.inner.borrow().region_obligations().to_owned(); - let region_constraints = self.infcx.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, - ) - }); - let opaque_types = self.infcx.clone_opaque_types_for_query_response(); - Ok(self - .tcx() - .mk_external_constraints(ExternalConstraintsData { region_constraints, opaque_types })) - } - - pub(super) fn canonicalize>>( - &self, - canonicalize_mode: CanonicalizeMode, - variables: &mut Vec>, - value: T, - ) -> Canonical<'tcx, T> { - Canonicalizer::canonicalize(self.infcx, canonicalize_mode, variables, value) - } } diff --git a/compiler/rustc_trait_selection/src/solve/canonical/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs similarity index 81% rename from compiler/rustc_trait_selection/src/solve/canonical/mod.rs rename to compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index d393ab1ba4a..ee90488730a 100644 --- a/compiler/rustc_trait_selection/src/solve/canonical/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -8,20 +8,19 @@ /// section of the [rustc-dev-guide][c]. /// /// [c]: https://rustc-dev-guide.rust-lang.org/solve/canonicalization.html -pub use self::canonicalize::{CanonicalizeMode, Canonicalizer}; - use super::{CanonicalGoal, Certainty, EvalCtxt, Goal}; -use super::{CanonicalResponse, QueryResult, Response}; +use crate::solve::canonicalize::{CanonicalizeMode, Canonicalizer}; +use crate::solve::{CanonicalResponse, QueryResult, Response}; +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::traits::query::NoSolution; -use rustc_infer::traits::solve::ExternalConstraintsData; +use rustc_middle::traits::query::NoSolution; +use rustc_middle::traits::solve::{ExternalConstraints, ExternalConstraintsData}; use rustc_middle::ty::{self, GenericArgKind}; +use rustc_span::DUMMY_SP; use std::iter; use std::ops::Deref; -mod canonicalize; - impl<'tcx> EvalCtxt<'_, 'tcx> { /// Canonicalizes the goal remembering the original values /// for each bound variable. @@ -30,7 +29,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { goal: Goal<'tcx, ty::Predicate<'tcx>>, ) -> (Vec>, CanonicalGoal<'tcx>) { let mut orig_values = Default::default(); - let canonical_goal = self.canonicalize(CanonicalizeMode::Input, &mut orig_values, goal); + let canonical_goal = Canonicalizer::canonicalize( + self.infcx, + CanonicalizeMode::Input, + &mut orig_values, + goal, + ); (orig_values, canonical_goal) } @@ -41,7 +45,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// - `external_constraints`: additional constraints which aren't expressable /// using simple unification of inference variables. #[instrument(level = "debug", skip(self))] - pub(super) fn evaluate_added_goals_and_make_canonical_response( + pub(in crate::solve) fn evaluate_added_goals_and_make_canonical_response( &mut self, certainty: Certainty, ) -> QueryResult<'tcx> { @@ -51,7 +55,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let external_constraints = self.compute_external_query_constraints()?; let response = Response { var_values: self.var_values, external_constraints, certainty }; - let canonical = self.canonicalize( + let canonical = Canonicalizer::canonicalize( + self.infcx, CanonicalizeMode::Response { max_input_universe: self.max_input_universe }, &mut Default::default(), response, @@ -59,6 +64,26 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { Ok(canonical) } + #[instrument(level = "debug", skip(self), ret)] + fn compute_external_query_constraints(&self) -> Result, NoSolution> { + // 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.infcx.inner.borrow().region_obligations().to_owned(); + let region_constraints = self.infcx.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, + ) + }); + let opaque_types = self.infcx.clone_opaque_types_for_query_response(); + Ok(self + .tcx() + .mk_external_constraints(ExternalConstraintsData { region_constraints, opaque_types })) + } + /// After calling a canonical query, we apply the constraints returned /// by the query using this function. /// @@ -98,10 +123,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // FIXME: Longterm canonical queries should deal with all placeholders // created inside of the query directly instead of returning them to the // caller. - let prev_universe = self.universe(); + let prev_universe = self.infcx.universe(); let universes_created_in_query = response.max_universe.index() + 1; for _ in 0..universes_created_in_query { - self.create_next_universe(); + self.infcx.create_next_universe(); } let var_values = response.value.var_values; @@ -144,7 +169,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // A variable from inside a binder of the query. While ideally these shouldn't // exist at all (see the FIXME at the start of this method), we have to deal with // them for now. - self.instantiate_canonical_var(info, |idx| { + self.infcx.instantiate_canonical_var(DUMMY_SP, info, |idx| { ty::UniverseIndex::from(prev_universe.index() + idx.index()) }) } else if info.is_existential() { @@ -158,7 +183,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { if let Some(v) = opt_values[index] { v } else { - self.instantiate_canonical_var(info, |_| prev_universe) + self.infcx.instantiate_canonical_var(DUMMY_SP, info, |_| prev_universe) } } else { // For placeholders which were already part of the input, we simply map this diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 7c01d5d2bef..1925043e5fd 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -15,8 +15,7 @@ use rustc_hir::def_id::DefId; use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_infer::traits::query::NoSolution; use rustc_middle::traits::solve::{ - CanonicalGoal, CanonicalResponse, Certainty, ExternalConstraintsData, Goal, QueryResult, - Response, + CanonicalResponse, Certainty, ExternalConstraintsData, Goal, QueryResult, Response, }; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{ @@ -24,7 +23,7 @@ use rustc_middle::ty::{ }; mod assembly; -mod canonical; +mod canonicalize; mod eval_ctxt; mod fulfill; mod project_goals;