mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Return the canonicalized query from type ops
This commit is contained in:
parent
842f0590db
commit
4421dd17fa
@ -11,6 +11,7 @@ use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
|
||||
use rustc_span::DUMMY_SP;
|
||||
use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
|
||||
use std::rc::Rc;
|
||||
use type_op::TypeOpOutput;
|
||||
|
||||
use crate::borrow_check::{
|
||||
nll::ToRegionVid,
|
||||
@ -255,7 +256,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
|
||||
let constraint_sets: Vec<_> = unnormalized_input_output_tys
|
||||
.flat_map(|ty| {
|
||||
debug!("build: input_or_output={:?}", ty);
|
||||
let (ty, constraints1) = self
|
||||
let TypeOpOutput { output: ty, constraints: constraints1, .. } = self
|
||||
.param_env
|
||||
.and(type_op::normalize::Normalize::new(ty))
|
||||
.fully_perform(self.infcx)
|
||||
@ -264,7 +265,11 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
|
||||
.tcx
|
||||
.sess
|
||||
.delay_span_bug(DUMMY_SP, &format!("failed to normalize {:?}", ty));
|
||||
(self.infcx.tcx.ty_error(), None)
|
||||
TypeOpOutput {
|
||||
output: self.infcx.tcx.ty_error(),
|
||||
constraints: None,
|
||||
canonicalized_query: None,
|
||||
}
|
||||
});
|
||||
let constraints2 = self.add_implied_bounds(ty);
|
||||
normalized_inputs_and_output.push(ty);
|
||||
@ -317,7 +322,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
|
||||
/// from this local.
|
||||
fn add_implied_bounds(&mut self, ty: Ty<'tcx>) -> Option<Rc<QueryRegionConstraints<'tcx>>> {
|
||||
debug!("add_implied_bounds(ty={:?})", ty);
|
||||
let (bounds, constraints) = self
|
||||
let TypeOpOutput { output: bounds, constraints, .. } = self
|
||||
.param_env
|
||||
.and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty })
|
||||
.fully_perform(self.infcx)
|
||||
|
@ -5,7 +5,7 @@ use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location};
|
||||
use rustc_middle::ty::{Ty, TypeFoldable};
|
||||
use rustc_trait_selection::traits::query::dropck_outlives::DropckOutlivesResult;
|
||||
use rustc_trait_selection::traits::query::type_op::outlives::DropckOutlives;
|
||||
use rustc_trait_selection::traits::query::type_op::TypeOp;
|
||||
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::dataflow::impls::MaybeInitializedPlaces;
|
||||
@ -519,9 +519,9 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
|
||||
debug!("compute_drop_data(dropped_ty={:?})", dropped_ty,);
|
||||
|
||||
let param_env = typeck.param_env;
|
||||
let (dropck_result, region_constraint_data) =
|
||||
let TypeOpOutput { output, constraints, .. } =
|
||||
param_env.and(DropckOutlives::new(dropped_ty)).fully_perform(typeck.infcx).unwrap();
|
||||
|
||||
DropData { dropck_result, region_constraint_data }
|
||||
DropData { dropck_result: output, region_constraint_data: constraints }
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ use rustc_trait_selection::traits::query::type_op;
|
||||
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
|
||||
use rustc_trait_selection::traits::query::{Fallible, NoSolution};
|
||||
use rustc_trait_selection::traits::{self, ObligationCause, PredicateObligations};
|
||||
use type_op::TypeOpOutput;
|
||||
|
||||
use crate::dataflow::impls::MaybeInitializedPlaces;
|
||||
use crate::dataflow::move_paths::MoveData;
|
||||
@ -1113,13 +1114,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
category: ConstraintCategory,
|
||||
op: impl type_op::TypeOp<'tcx, Output = R>,
|
||||
) -> Fallible<R> {
|
||||
let (r, opt_data) = op.fully_perform(self.infcx)?;
|
||||
let TypeOpOutput { output, constraints, .. } = op.fully_perform(self.infcx)?;
|
||||
|
||||
if let Some(data) = &opt_data {
|
||||
if let Some(data) = &constraints {
|
||||
self.push_region_constraints(locations, category, data);
|
||||
}
|
||||
|
||||
Ok(r)
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
fn push_region_constraints(
|
||||
|
@ -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…
Reference in New Issue
Block a user