Return the canonicalized query from type ops
This commit is contained in:
parent
842f0590db
commit
4421dd17fa
6 changed files with 53 additions and 39 deletions
|
@ -1,13 +1,13 @@
|
|||
use crate::infer::{InferCtxt, InferOk};
|
||||
use crate::traits::query::Fallible;
|
||||
use std::fmt;
|
||||
|
||||
use crate::infer::canonical::query_response;
|
||||
use crate::infer::canonical::QueryRegionConstraints;
|
||||
use crate::infer::{InferCtxt, InferOk};
|
||||
use crate::traits::engine::TraitEngineExt as _;
|
||||
use crate::traits::query::type_op::TypeOpOutput;
|
||||
use crate::traits::query::Fallible;
|
||||
use crate::traits::{ObligationCause, TraitEngine};
|
||||
use rustc_infer::traits::TraitEngineExt as _;
|
||||
use rustc_span::source_map::DUMMY_SP;
|
||||
|
||||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct CustomTypeOp<F, G> {
|
||||
|
@ -35,10 +35,7 @@ where
|
|||
/// Processes the operation and all resulting obligations,
|
||||
/// returning the final result along with any region constraints
|
||||
/// (they will be given over to the NLL region solver).
|
||||
fn fully_perform(
|
||||
self,
|
||||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
) -> Fallible<(Self::Output, Option<Rc<QueryRegionConstraints<'tcx>>>)> {
|
||||
fn fully_perform(self, infcx: &InferCtxt<'_, 'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> {
|
||||
if cfg!(debug_assertions) {
|
||||
info!("fully_perform({:?})", self);
|
||||
}
|
||||
|
@ -58,10 +55,10 @@ where
|
|||
|
||||
/// Executes `op` and then scrapes out all the "old style" region
|
||||
/// constraints that result, creating query-region-constraints.
|
||||
fn scrape_region_constraints<'tcx, R>(
|
||||
fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
|
||||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
op: impl FnOnce() -> Fallible<InferOk<'tcx, R>>,
|
||||
) -> Fallible<(R, Option<Rc<QueryRegionConstraints<'tcx>>>)> {
|
||||
) -> Fallible<TypeOpOutput<'tcx, Op>> {
|
||||
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
|
||||
let dummy_body_id = ObligationCause::dummy().body_id;
|
||||
|
||||
|
@ -101,8 +98,12 @@ fn scrape_region_constraints<'tcx, R>(
|
|||
);
|
||||
|
||||
if region_constraints.is_empty() {
|
||||
Ok((value, None))
|
||||
Ok(TypeOpOutput { output: value, constraints: None, canonicalized_query: None })
|
||||
} else {
|
||||
Ok((value, Some(Rc::new(region_constraints))))
|
||||
Ok(TypeOpOutput {
|
||||
output: value,
|
||||
constraints: Some(Rc::new(region_constraints)),
|
||||
canonicalized_query: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::traits::query::outlives_bounds::OutlivesBound;
|
|||
use crate::traits::query::Fallible;
|
||||
use rustc_middle::ty::{ParamEnvAnd, Ty, TyCtxt};
|
||||
|
||||
#[derive(Clone, Debug, HashStable, TypeFoldable, Lift)]
|
||||
#[derive(Copy, Clone, Debug, HashStable, TypeFoldable, Lift)]
|
||||
pub struct ImpliedOutlivesBounds<'tcx> {
|
||||
pub ty: Ty<'tcx>,
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ use crate::infer::canonical::{
|
|||
use crate::infer::{InferCtxt, InferOk};
|
||||
use crate::traits::query::Fallible;
|
||||
use crate::traits::ObligationCause;
|
||||
use rustc_infer::infer::canonical::Canonical;
|
||||
use rustc_middle::ty::fold::TypeFoldable;
|
||||
use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
|
||||
use std::fmt;
|
||||
|
@ -30,10 +31,18 @@ pub trait TypeOp<'tcx>: Sized + fmt::Debug {
|
|||
/// Processes the operation and all resulting obligations,
|
||||
/// returning the final result along with any region constraints
|
||||
/// (they will be given over to the NLL region solver).
|
||||
fn fully_perform(
|
||||
self,
|
||||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
) -> Fallible<(Self::Output, Option<Rc<QueryRegionConstraints<'tcx>>>)>;
|
||||
fn fully_perform(self, infcx: &InferCtxt<'_, 'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>>;
|
||||
}
|
||||
|
||||
/// The output from performing a type op
|
||||
pub struct TypeOpOutput<'tcx, Op: TypeOp<'tcx>> {
|
||||
/// The output from the type op.
|
||||
pub output: Op::Output,
|
||||
/// Any region constraints from performing the type op.
|
||||
pub constraints: Option<Rc<QueryRegionConstraints<'tcx>>>,
|
||||
/// The canonicalized form of the query.
|
||||
/// This for error reporting to be able to rerun the query.
|
||||
pub canonicalized_query: Option<Canonical<'tcx, Op>>,
|
||||
}
|
||||
|
||||
/// "Query type ops" are type ops that are implemented using a
|
||||
|
@ -45,7 +54,7 @@ pub trait TypeOp<'tcx>: Sized + fmt::Debug {
|
|||
/// which produces the resulting query region constraints.
|
||||
///
|
||||
/// [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html
|
||||
pub trait QueryTypeOp<'tcx>: fmt::Debug + Sized + TypeFoldable<'tcx> + 'tcx {
|
||||
pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<'tcx> + 'tcx {
|
||||
type QueryResponse: TypeFoldable<'tcx>;
|
||||
|
||||
/// Give query the option for a simple fast path that never
|
||||
|
@ -71,9 +80,9 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Sized + TypeFoldable<'tcx> + 'tcx {
|
|||
query_key: ParamEnvAnd<'tcx, Self>,
|
||||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
output_query_region_constraints: &mut QueryRegionConstraints<'tcx>,
|
||||
) -> Fallible<Self::QueryResponse> {
|
||||
) -> Fallible<(Self::QueryResponse, Option<Canonical<'tcx, ParamEnvAnd<'tcx, Self>>>)> {
|
||||
if let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &query_key) {
|
||||
return Ok(result);
|
||||
return Ok((result, None));
|
||||
}
|
||||
|
||||
// FIXME(#33684) -- We need to use
|
||||
|
@ -101,14 +110,14 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Sized + TypeFoldable<'tcx> + 'tcx {
|
|||
// create obligations. In that case, we have to go
|
||||
// fulfill them. We do this via a (recursive) query.
|
||||
for obligation in obligations {
|
||||
let () = ProvePredicate::fully_perform_into(
|
||||
let ((), _) = ProvePredicate::fully_perform_into(
|
||||
obligation.param_env.and(ProvePredicate::new(obligation.predicate)),
|
||||
infcx,
|
||||
output_query_region_constraints,
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(value)
|
||||
Ok((value, Some(canonical_self)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,18 +127,16 @@ where
|
|||
{
|
||||
type Output = Q::QueryResponse;
|
||||
|
||||
fn fully_perform(
|
||||
self,
|
||||
infcx: &InferCtxt<'_, 'tcx>,
|
||||
) -> Fallible<(Self::Output, Option<Rc<QueryRegionConstraints<'tcx>>>)> {
|
||||
fn fully_perform(self, infcx: &InferCtxt<'_, 'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> {
|
||||
let mut region_constraints = QueryRegionConstraints::default();
|
||||
let r = Q::fully_perform_into(self, infcx, &mut region_constraints)?;
|
||||
let (output, canonicalized_query) =
|
||||
Q::fully_perform_into(self, infcx, &mut region_constraints)?;
|
||||
|
||||
// Promote the final query-region-constraints into a
|
||||
// (optional) ref-counted vector:
|
||||
let opt_qrc =
|
||||
let region_constraints =
|
||||
if region_constraints.is_empty() { None } else { Some(Rc::new(region_constraints)) };
|
||||
|
||||
Ok((r, opt_qrc))
|
||||
Ok(TypeOpOutput { output, constraints: region_constraints, canonicalized_query })
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue