diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs index c61f5454ec5..a2cfdeefd6f 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs @@ -1,4 +1,5 @@ use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; +use crate::traits::ObligationCtxt; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; @@ -20,4 +21,11 @@ fn perform_query( ) -> Result, NoSolution> { tcx.type_op_ascribe_user_type(canonicalized) } + + fn perform_locally_in_new_solver( + _ocx: &ObligationCtxt<'_, 'tcx>, + _key: ParamEnvAnd<'tcx, Self>, + ) -> Result { + todo!() + } } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs index 40f8ecfd4ce..f6589308806 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs @@ -1,5 +1,7 @@ use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; +use crate::traits::ObligationCtxt; use rustc_middle::traits::query::NoSolution; +use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; pub use rustc_middle::traits::query::type_op::Eq; @@ -20,4 +22,12 @@ fn perform_query( ) -> Result, NoSolution> { tcx.type_op_eq(canonicalized) } + + fn perform_locally_in_new_solver( + ocx: &ObligationCtxt<'_, 'tcx>, + key: ParamEnvAnd<'tcx, Self>, + ) -> Result { + ocx.eq(&ObligationCause::dummy(), key.param_env, key.value.a, key.value.b)?; + Ok(()) + } } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index 26f0d554d35..9054bafc4a6 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -1,4 +1,5 @@ use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; +use crate::traits::ObligationCtxt; use rustc_infer::traits::query::OutlivesBound; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt}; @@ -39,4 +40,11 @@ fn perform_query( tcx.implied_outlives_bounds(canonicalized) } + + fn perform_locally_in_new_solver( + _ocx: &ObligationCtxt<'_, 'tcx>, + _key: ParamEnvAnd<'tcx, Self>, + ) -> Result { + todo!() + } } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index 64232659848..642fdec2d9a 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -2,7 +2,7 @@ Canonical, CanonicalQueryResponse, OriginalQueryValues, QueryRegionConstraints, }; use crate::infer::{InferCtxt, InferOk}; -use crate::traits::ObligationCause; +use crate::traits::{ObligationCause, ObligationCtxt}; use rustc_errors::ErrorGuaranteed; use rustc_infer::infer::canonical::Certainty; use rustc_infer::traits::PredicateObligations; @@ -23,6 +23,8 @@ pub use rustc_middle::traits::query::type_op::*; +use self::custom::scrape_region_constraints; + /// "Type ops" are used in NLL to perform some particular action and /// extract out the resulting region constraints (or an error if it /// cannot be completed). @@ -81,6 +83,17 @@ fn perform_query( canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, ) -> Result, NoSolution>; + /// In the new trait solver, we already do caching in the solver itself, + /// so there's no need to canonicalize and cache via the query system. + /// Additionally, even if we were to canonicalize, we'd still need to + /// make sure to feed it predefined opaque types and the defining anchor + /// and that would require duplicating all of the tcx queries. Instead, + /// just perform these ops locally. + fn perform_locally_in_new_solver( + ocx: &ObligationCtxt<'_, 'tcx>, + key: ParamEnvAnd<'tcx, Self>, + ) -> Result; + fn fully_perform_into( query_key: ParamEnvAnd<'tcx, Self>, infcx: &InferCtxt<'tcx>, @@ -133,6 +146,16 @@ fn fully_perform( infcx: &InferCtxt<'tcx>, span: Span, ) -> Result, ErrorGuaranteed> { + if infcx.tcx.trait_solver_next() { + return Ok(scrape_region_constraints( + infcx, + |ocx| QueryTypeOp::perform_locally_in_new_solver(ocx, self), + "query type op", + span, + )? + .0); + } + let mut region_constraints = QueryRegionConstraints::default(); let (output, error_info, mut obligations, _) = Q::fully_perform_into(self, infcx, &mut region_constraints).map_err(|_| { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs index 776c74fdfae..57ca14aa492 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs @@ -1,5 +1,7 @@ use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; +use crate::traits::ObligationCtxt; use rustc_middle::traits::query::NoSolution; +use rustc_middle::traits::ObligationCause; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt}; use std::fmt; @@ -22,6 +24,14 @@ fn perform_query( ) -> Result, NoSolution> { T::type_op_method(tcx, canonicalized) } + + fn perform_locally_in_new_solver( + ocx: &ObligationCtxt<'_, 'tcx>, + key: ParamEnvAnd<'tcx, Self>, + ) -> Result { + // FIXME(-Ztrait-solver=next): shouldn't be using old normalizer + Ok(ocx.normalize(&ObligationCause::dummy(), key.param_env, key.value.value)) + } } pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable> + Lift<'tcx> + Copy { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs index 7ce09bbdb7a..8b3a20a88f0 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs @@ -1,5 +1,6 @@ use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; use crate::traits::query::dropck_outlives::{trivial_dropck_outlives, DropckOutlivesResult}; +use crate::traits::ObligationCtxt; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{ParamEnvAnd, Ty, TyCtxt}; @@ -48,4 +49,11 @@ fn perform_query( tcx.dropck_outlives(canonicalized) } + + fn perform_locally_in_new_solver( + _ocx: &ObligationCtxt<'_, 'tcx>, + _key: ParamEnvAnd<'tcx, Self>, + ) -> Result { + todo!() + } } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs index 7c02f363960..47850bc330d 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs @@ -1,5 +1,8 @@ use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; +use crate::traits::ObligationCtxt; +use rustc_infer::traits::Obligation; use rustc_middle::traits::query::NoSolution; +use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt}; pub use rustc_middle::traits::query::type_op::ProvePredicate; @@ -36,4 +39,17 @@ fn perform_query( ) -> Result, NoSolution> { tcx.type_op_prove_predicate(canonicalized) } + + fn perform_locally_in_new_solver( + ocx: &ObligationCtxt<'_, 'tcx>, + key: ParamEnvAnd<'tcx, Self>, + ) -> Result { + ocx.register_obligation(Obligation::new( + ocx.infcx.tcx, + ObligationCause::dummy(), + key.param_env, + key.value.predicate, + )); + Ok(()) + } } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs index 2f2b931afcf..10976d5cd71 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs @@ -1,5 +1,7 @@ use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; +use crate::traits::ObligationCtxt; use rustc_middle::traits::query::NoSolution; +use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; pub use rustc_middle::traits::query::type_op::Subtype; @@ -17,4 +19,12 @@ fn perform_query( ) -> Result, NoSolution> { tcx.type_op_subtype(canonicalized) } + + fn perform_locally_in_new_solver( + ocx: &ObligationCtxt<'_, 'tcx>, + key: ParamEnvAnd<'tcx, Self>, + ) -> Result { + ocx.sub(&ObligationCause::dummy(), key.param_env, key.value.sub, key.value.sup)?; + Ok(()) + } }