make TypeOp
implement debug instead of carrying a closure
This allows us to avoid some silly clones etc.
This commit is contained in:
parent
e7a9e7aef2
commit
7a641cb145
@ -12,7 +12,7 @@ use borrow_check::location::{LocationIndex, LocationTable};
|
||||
use dataflow::indexes::BorrowIndex;
|
||||
use polonius_engine::AllFacts as PoloniusAllFacts;
|
||||
use polonius_engine::Atom;
|
||||
use rustc::ty::RegionVid;
|
||||
use rustc::ty::{RegionVid, TyCtxt};
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use std::error::Error;
|
||||
use std::fmt::Debug;
|
||||
|
@ -80,63 +80,66 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
let anon_type_map =
|
||||
self.fully_perform_op(
|
||||
Locations::All,
|
||||
|| format!("input_output"),
|
||||
CustomTypeOp::new(|cx| {
|
||||
let mut obligations = ObligationAccumulator::default();
|
||||
CustomTypeOp::new(
|
||||
|cx| {
|
||||
let mut obligations = ObligationAccumulator::default();
|
||||
|
||||
let dummy_body_id = ObligationCause::dummy().body_id;
|
||||
let (output_ty, anon_type_map) = obligations.add(infcx.instantiate_anon_types(
|
||||
mir_def_id,
|
||||
dummy_body_id,
|
||||
cx.param_env,
|
||||
&output_ty,
|
||||
));
|
||||
debug!(
|
||||
"equate_inputs_and_outputs: instantiated output_ty={:?}",
|
||||
output_ty
|
||||
);
|
||||
debug!(
|
||||
"equate_inputs_and_outputs: anon_type_map={:#?}",
|
||||
anon_type_map
|
||||
);
|
||||
|
||||
debug!(
|
||||
"equate_inputs_and_outputs: mir_output_ty={:?}",
|
||||
mir_output_ty
|
||||
);
|
||||
obligations.add(
|
||||
infcx
|
||||
.at(&ObligationCause::dummy(), cx.param_env)
|
||||
.eq(output_ty, mir_output_ty)?,
|
||||
);
|
||||
|
||||
for (&anon_def_id, anon_decl) in &anon_type_map {
|
||||
let anon_defn_ty = tcx.type_of(anon_def_id);
|
||||
let anon_defn_ty = anon_defn_ty.subst(tcx, anon_decl.substs);
|
||||
let anon_defn_ty = renumber::renumber_regions(
|
||||
cx.infcx,
|
||||
TyContext::Location(Location::START),
|
||||
&anon_defn_ty,
|
||||
let dummy_body_id = ObligationCause::dummy().body_id;
|
||||
let (output_ty, anon_type_map) =
|
||||
obligations.add(infcx.instantiate_anon_types(
|
||||
mir_def_id,
|
||||
dummy_body_id,
|
||||
cx.param_env,
|
||||
&output_ty,
|
||||
));
|
||||
debug!(
|
||||
"equate_inputs_and_outputs: instantiated output_ty={:?}",
|
||||
output_ty
|
||||
);
|
||||
debug!(
|
||||
"equate_inputs_and_outputs: concrete_ty={:?}",
|
||||
anon_decl.concrete_ty
|
||||
"equate_inputs_and_outputs: anon_type_map={:#?}",
|
||||
anon_type_map
|
||||
);
|
||||
|
||||
debug!(
|
||||
"equate_inputs_and_outputs: mir_output_ty={:?}",
|
||||
mir_output_ty
|
||||
);
|
||||
debug!("equate_inputs_and_outputs: anon_defn_ty={:?}", anon_defn_ty);
|
||||
obligations.add(
|
||||
infcx
|
||||
.at(&ObligationCause::dummy(), cx.param_env)
|
||||
.eq(anon_decl.concrete_ty, anon_defn_ty)?,
|
||||
.eq(output_ty, mir_output_ty)?,
|
||||
);
|
||||
}
|
||||
|
||||
debug!("equate_inputs_and_outputs: equated");
|
||||
for (&anon_def_id, anon_decl) in &anon_type_map {
|
||||
let anon_defn_ty = tcx.type_of(anon_def_id);
|
||||
let anon_defn_ty = anon_defn_ty.subst(tcx, anon_decl.substs);
|
||||
let anon_defn_ty = renumber::renumber_regions(
|
||||
cx.infcx,
|
||||
TyContext::Location(Location::START),
|
||||
&anon_defn_ty,
|
||||
);
|
||||
debug!(
|
||||
"equate_inputs_and_outputs: concrete_ty={:?}",
|
||||
anon_decl.concrete_ty
|
||||
);
|
||||
debug!("equate_inputs_and_outputs: anon_defn_ty={:?}", anon_defn_ty);
|
||||
obligations.add(
|
||||
infcx
|
||||
.at(&ObligationCause::dummy(), cx.param_env)
|
||||
.eq(anon_decl.concrete_ty, anon_defn_ty)?,
|
||||
);
|
||||
}
|
||||
|
||||
Ok(InferOk {
|
||||
value: Some(anon_type_map),
|
||||
obligations: obligations.into_vec(),
|
||||
})
|
||||
}),
|
||||
debug!("equate_inputs_and_outputs: equated");
|
||||
|
||||
Ok(InferOk {
|
||||
value: Some(anon_type_map),
|
||||
obligations: obligations.into_vec(),
|
||||
})
|
||||
},
|
||||
|| format!("input_output"),
|
||||
),
|
||||
).unwrap_or_else(|terr| {
|
||||
span_mirbug!(
|
||||
self,
|
||||
@ -156,14 +159,16 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
if let Some(anon_type_map) = anon_type_map {
|
||||
self.fully_perform_op(
|
||||
Locations::All,
|
||||
|| format!("anon_type_map"),
|
||||
CustomTypeOp::new(|_cx| {
|
||||
infcx.constrain_anon_types(&anon_type_map, universal_regions);
|
||||
Ok(InferOk {
|
||||
value: (),
|
||||
obligations: vec![],
|
||||
})
|
||||
}),
|
||||
CustomTypeOp::new(
|
||||
|_cx| {
|
||||
infcx.constrain_anon_types(&anon_type_map, universal_regions);
|
||||
Ok(InferOk {
|
||||
value: (),
|
||||
obligations: vec![],
|
||||
})
|
||||
},
|
||||
|| format!("anon_type_map"),
|
||||
),
|
||||
).unwrap();
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,8 @@
|
||||
// except according to those terms.
|
||||
|
||||
use borrow_check::nll::region_infer::Cause;
|
||||
use borrow_check::nll::type_check::AtLocation;
|
||||
use borrow_check::nll::type_check::type_op::CustomTypeOp;
|
||||
use borrow_check::nll::type_check::AtLocation;
|
||||
use dataflow::move_paths::{HasMoveData, MoveData};
|
||||
use dataflow::MaybeInitializedPlaces;
|
||||
use dataflow::{FlowAtLocation, FlowsAtLocation};
|
||||
@ -171,8 +171,7 @@ impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flo
|
||||
);
|
||||
|
||||
cx.tcx().for_each_free_region(&value, |live_region| {
|
||||
cx
|
||||
.constraints
|
||||
cx.constraints
|
||||
.liveness_set
|
||||
.push((live_region, location, cause.clone()));
|
||||
});
|
||||
@ -219,15 +218,15 @@ impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flo
|
||||
debug!("compute_drop_data(dropped_ty={:?})", dropped_ty,);
|
||||
|
||||
let (dropped_kinds, region_constraint_data) =
|
||||
cx.fully_perform_op_and_get_region_constraint_data(
|
||||
|| format!("compute_drop_data(dropped_ty={:?})", dropped_ty),
|
||||
CustomTypeOp::new(|cx| {
|
||||
cx.fully_perform_op_and_get_region_constraint_data(CustomTypeOp::new(
|
||||
|cx| {
|
||||
Ok(cx
|
||||
.infcx
|
||||
.at(&ObligationCause::dummy(), cx.param_env)
|
||||
.dropck_outlives(dropped_ty))
|
||||
}),
|
||||
).unwrap();
|
||||
},
|
||||
|| format!("compute_drop_data(dropped_ty={:?})", dropped_ty),
|
||||
)).unwrap();
|
||||
|
||||
DropData {
|
||||
dropped_kinds,
|
||||
|
@ -731,16 +731,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
fn fully_perform_op<R>(
|
||||
&mut self,
|
||||
locations: Locations,
|
||||
describe_op: impl Fn() -> String,
|
||||
op: impl type_op::TypeOp<'gcx, 'tcx, Output = R>,
|
||||
) -> Result<R, TypeError<'tcx>> {
|
||||
match op.trivial_noop() {
|
||||
Ok(r) => Ok(r),
|
||||
Err(op) => {
|
||||
let (r, opt_data) = self.fully_perform_op_and_get_region_constraint_data(
|
||||
|| format!("{} at {:?}", describe_op(), locations),
|
||||
op,
|
||||
)?;
|
||||
let (r, opt_data) = self.fully_perform_op_and_get_region_constraint_data(op)?;
|
||||
|
||||
if let Some(data) = opt_data {
|
||||
self.push_region_constraints(locations, data);
|
||||
@ -781,14 +777,10 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
/// be generated there, so this can be useful for caching.
|
||||
fn fully_perform_op_and_get_region_constraint_data<R>(
|
||||
&mut self,
|
||||
describe_op: impl Fn() -> String,
|
||||
op: impl type_op::TypeOp<'gcx, 'tcx, Output = R>,
|
||||
) -> Result<(R, Option<Rc<RegionConstraintData<'tcx>>>), TypeError<'tcx>> {
|
||||
if cfg!(debug_assertions) {
|
||||
info!(
|
||||
"fully_perform_op_and_get_region_constraint_data({})",
|
||||
describe_op(),
|
||||
);
|
||||
info!("fully_perform_op_and_get_region_constraint_data({:?})", op,);
|
||||
}
|
||||
|
||||
let mut fulfill_cx = TraitEngine::new(self.infcx.tcx);
|
||||
@ -822,20 +814,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
locations: Locations,
|
||||
) -> UnitResult<'tcx> {
|
||||
let param_env = self.param_env;
|
||||
self.fully_perform_op(
|
||||
locations,
|
||||
|| format!("sub_types({:?} <: {:?})", sub, sup),
|
||||
type_op::Subtype::new(param_env, sub, sup),
|
||||
)
|
||||
self.fully_perform_op(locations, type_op::Subtype::new(param_env, sub, sup))
|
||||
}
|
||||
|
||||
fn eq_types(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, locations: Locations) -> UnitResult<'tcx> {
|
||||
let param_env = self.param_env;
|
||||
self.fully_perform_op(
|
||||
locations,
|
||||
|| format!("eq_types({:?} = {:?})", a, b),
|
||||
type_op::Eq::new(param_env, b, a),
|
||||
)
|
||||
self.fully_perform_op(locations, type_op::Eq::new(param_env, b, a))
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
@ -1614,7 +1598,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
let param_env = self.param_env;
|
||||
self.fully_perform_op(
|
||||
location.at_self(),
|
||||
|| format!("prove_predicates({:?})", predicates_vec),
|
||||
type_op::ProvePredicates::new(param_env, predicates),
|
||||
).unwrap()
|
||||
}
|
||||
@ -1651,10 +1634,8 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
{
|
||||
debug!("normalize(value={:?}, location={:?})", value, location);
|
||||
let param_env = self.param_env;
|
||||
let value1 = value.clone(); // FIXME move describe into type_op
|
||||
self.fully_perform_op(
|
||||
location.to_locations(),
|
||||
|| format!("normalize(value={:?})", value1),
|
||||
type_op::Normalize::new(param_env, value),
|
||||
).unwrap()
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::ty::{ParamEnv, Predicate, Ty};
|
||||
use std::fmt;
|
||||
|
||||
pub(super) trait TypeOp<'gcx, 'tcx>: Sized {
|
||||
pub(super) trait TypeOp<'gcx, 'tcx>: Sized + fmt::Debug {
|
||||
type Output;
|
||||
|
||||
/// Micro-optimization: returns `Ok(x)` if we can trivially
|
||||
@ -30,22 +30,25 @@ pub(super) trait TypeOp<'gcx, 'tcx>: Sized {
|
||||
) -> InferResult<'tcx, Self::Output>;
|
||||
}
|
||||
|
||||
pub(super) struct CustomTypeOp<F> {
|
||||
pub(super) struct CustomTypeOp<F, G> {
|
||||
closure: F,
|
||||
description: G,
|
||||
}
|
||||
|
||||
impl<F> CustomTypeOp<F> {
|
||||
pub(super) fn new<'gcx, 'tcx, R>(closure: F) -> Self
|
||||
impl<F, G> CustomTypeOp<F, G> {
|
||||
pub(super) fn new<'gcx, 'tcx, R>(closure: F, description: G) -> Self
|
||||
where
|
||||
F: FnOnce(&mut TypeChecker<'_, 'gcx, 'tcx>) -> InferResult<'tcx, R>,
|
||||
G: Fn() -> String,
|
||||
{
|
||||
CustomTypeOp { closure }
|
||||
CustomTypeOp { closure, description }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'gcx, 'tcx, F, R> TypeOp<'gcx, 'tcx> for CustomTypeOp<F>
|
||||
impl<'gcx, 'tcx, F, R, G> TypeOp<'gcx, 'tcx> for CustomTypeOp<F, G>
|
||||
where
|
||||
F: FnOnce(&mut TypeChecker<'_, 'gcx, 'tcx>) -> InferResult<'tcx, R>,
|
||||
G: Fn() -> String,
|
||||
{
|
||||
type Output = R;
|
||||
|
||||
@ -58,7 +61,16 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) trait InfcxTypeOp<'gcx, 'tcx>: Sized {
|
||||
impl<F, G> fmt::Debug for CustomTypeOp<F, G>
|
||||
where
|
||||
G: Fn() -> String,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", (self.description)())
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) trait InfcxTypeOp<'gcx, 'tcx>: Sized + fmt::Debug {
|
||||
type Output;
|
||||
|
||||
/// Micro-optimization: returns `Ok(x)` if we can trivially
|
||||
@ -87,6 +99,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct Subtype<'tcx> {
|
||||
param_env: ParamEnv<'tcx>,
|
||||
sub: Ty<'tcx>,
|
||||
@ -121,6 +134,7 @@ impl<'gcx, 'tcx> InfcxTypeOp<'gcx, 'tcx> for Subtype<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct Eq<'tcx> {
|
||||
param_env: ParamEnv<'tcx>,
|
||||
a: Ty<'tcx>,
|
||||
@ -151,6 +165,7 @@ impl<'gcx, 'tcx> InfcxTypeOp<'gcx, 'tcx> for Eq<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct ProvePredicates<'tcx> {
|
||||
obligations: Vec<PredicateObligation<'tcx>>,
|
||||
}
|
||||
@ -188,6 +203,7 @@ impl<'gcx, 'tcx> InfcxTypeOp<'gcx, 'tcx> for ProvePredicates<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct Normalize<'tcx, T> {
|
||||
param_env: ParamEnv<'tcx>,
|
||||
value: T,
|
||||
@ -221,10 +237,7 @@ where
|
||||
.at(&ObligationCause::dummy(), self.param_env)
|
||||
.normalize(&self.value)
|
||||
.unwrap_or_else(|NoSolution| {
|
||||
bug!(
|
||||
"normalization of `{:?}` failed",
|
||||
self.value,
|
||||
);
|
||||
bug!("normalization of `{:?}` failed", self.value,);
|
||||
});
|
||||
Ok(InferOk { value, obligations })
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user