Perform MIR type ops locally in new solver

This commit is contained in:
Michael Goulet 2023-05-25 17:48:19 +00:00
parent 19ed0aade6
commit a25aee1957
8 changed files with 94 additions and 1 deletions

View File

@ -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<CanonicalQueryResponse<'tcx, ()>, NoSolution> {
tcx.type_op_ascribe_user_type(canonicalized)
}
fn perform_locally_in_new_solver(
_ocx: &ObligationCtxt<'_, 'tcx>,
_key: ParamEnvAnd<'tcx, Self>,
) -> Result<Self::QueryResponse, NoSolution> {
todo!()
}
}

View File

@ -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<CanonicalQueryResponse<'tcx, ()>, NoSolution> {
tcx.type_op_eq(canonicalized)
}
fn perform_locally_in_new_solver(
ocx: &ObligationCtxt<'_, 'tcx>,
key: ParamEnvAnd<'tcx, Self>,
) -> Result<Self::QueryResponse, NoSolution> {
ocx.eq(&ObligationCause::dummy(), key.param_env, key.value.a, key.value.b)?;
Ok(())
}
}

View File

@ -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<Self::QueryResponse, NoSolution> {
todo!()
}
}

View File

@ -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<CanonicalQueryResponse<'tcx, Self::QueryResponse>, 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<Self::QueryResponse, NoSolution>;
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<TypeOpOutput<'tcx, Self>, 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(|_| {

View File

@ -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<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution> {
T::type_op_method(tcx, canonicalized)
}
fn perform_locally_in_new_solver(
ocx: &ObligationCtxt<'_, 'tcx>,
key: ParamEnvAnd<'tcx, Self>,
) -> Result<Self::QueryResponse, NoSolution> {
// 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<TyCtxt<'tcx>> + Lift<'tcx> + Copy {

View File

@ -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<Self::QueryResponse, NoSolution> {
todo!()
}
}

View File

@ -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<CanonicalQueryResponse<'tcx, ()>, NoSolution> {
tcx.type_op_prove_predicate(canonicalized)
}
fn perform_locally_in_new_solver(
ocx: &ObligationCtxt<'_, 'tcx>,
key: ParamEnvAnd<'tcx, Self>,
) -> Result<Self::QueryResponse, NoSolution> {
ocx.register_obligation(Obligation::new(
ocx.infcx.tcx,
ObligationCause::dummy(),
key.param_env,
key.value.predicate,
));
Ok(())
}
}

View File

@ -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<CanonicalQueryResponse<'tcx, ()>, NoSolution> {
tcx.type_op_subtype(canonicalized)
}
fn perform_locally_in_new_solver(
ocx: &ObligationCtxt<'_, 'tcx>,
key: ParamEnvAnd<'tcx, Self>,
) -> Result<Self::QueryResponse, NoSolution> {
ocx.sub(&ObligationCause::dummy(), key.param_env, key.value.sub, key.value.sup)?;
Ok(())
}
}