diff --git a/src/librustc_mir/borrow_check/nll/facts.rs b/src/librustc_mir/borrow_check/nll/facts.rs index fe2fc7e37b7..2523711f936 100644 --- a/src/librustc_mir/borrow_check/nll/facts.rs +++ b/src/librustc_mir/borrow_check/nll/facts.rs @@ -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; diff --git a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs index 708ff4aa2ba..afc21948e40 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs @@ -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(); } } diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs index d58dc1a601a..a032b2a9caa 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs @@ -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, diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 739f1eeb05f..959532fff8d 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -731,16 +731,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { fn fully_perform_op( &mut self, locations: Locations, - describe_op: impl Fn() -> String, op: impl type_op::TypeOp<'gcx, 'tcx, Output = R>, ) -> Result> { 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( &mut self, - describe_op: impl Fn() -> String, op: impl type_op::TypeOp<'gcx, 'tcx, Output = R>, ) -> Result<(R, Option>>), 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() } diff --git a/src/librustc_mir/borrow_check/nll/type_check/type_op.rs b/src/librustc_mir/borrow_check/nll/type_check/type_op.rs index b39ae0ed4ee..ff008d39d49 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/type_op.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/type_op.rs @@ -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 { +pub(super) struct CustomTypeOp { closure: F, + description: G, } -impl CustomTypeOp { - pub(super) fn new<'gcx, 'tcx, R>(closure: F) -> Self +impl CustomTypeOp { + 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 +impl<'gcx, 'tcx, F, R, G> TypeOp<'gcx, 'tcx> for CustomTypeOp 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 fmt::Debug for CustomTypeOp +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>, } @@ -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 }) }