From 17be6822f11727c313a5bca07d393222a862f495 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sat, 4 May 2019 02:24:42 +0900 Subject: [PATCH 1/2] Remove TypeckMir --- .../nll/type_check/liveness/mod.rs | 5 +- .../nll/type_check/liveness/trace.rs | 7 +- .../borrow_check/nll/type_check/mod.rs | 305 +++++++----------- src/librustc_mir/transform/mod.rs | 2 - 4 files changed, 129 insertions(+), 190 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs index 960e75048fa16..58a164b38f911 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs @@ -47,11 +47,10 @@ pub(super) fn generate<'gcx, 'tcx>( mir.local_decls.indices().collect() } else { let free_regions = { - let borrowck_context = typeck.borrowck_context.as_ref().unwrap(); regions_that_outlive_free_regions( typeck.infcx.num_region_vars(), - &borrowck_context.universal_regions, - &borrowck_context.constraints.outlives_constraints, + &typeck.borrowck_context.universal_regions, + &typeck.borrowck_context.constraints.outlives_constraints, ) }; compute_live_locals(typeck.tcx(), &free_regions, mir) diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs index 4c4b4c0431927..87e9a704fac1e 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs @@ -517,16 +517,15 @@ impl LivenessContext<'_, '_, '_, '_, 'tcx> { let tcx = typeck.tcx(); tcx.for_each_free_region(&value, |live_region| { - let borrowck_context = typeck.borrowck_context.as_mut().unwrap(); - let live_region_vid = borrowck_context + let live_region_vid = typeck.borrowck_context .universal_regions .to_region_vid(live_region); - borrowck_context + typeck.borrowck_context .constraints .liveness_constraints .add_elements(live_region_vid, live_at); - if let Some(facts) = borrowck_context.all_facts { + if let Some(facts) = typeck.borrowck_context.all_facts { for point in live_at.iter() { let loc = elements.to_location(point); facts.region_live_at.push((live_region_vid, location_table.start_index(loc))); 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 f1bbb1c880998..69e3005577577 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -20,7 +20,6 @@ use crate::borrow_check::nll::ToRegionVid; use crate::dataflow::move_paths::MoveData; use crate::dataflow::FlowAtLocation; use crate::dataflow::MaybeInitializedPlaces; -use crate::transform::{MirPass, MirSource}; use either::Either; use rustc::hir; use rustc::hir::def_id::DefId; @@ -159,16 +158,14 @@ pub(crate) fn type_check<'gcx, 'tcx>( param_env, mir, ®ion_bound_pairs, - Some(implicit_region_bound), - Some(&mut borrowck_context), - Some(&universal_region_relations), - |cx| { + implicit_region_bound, + &mut borrowck_context, + &universal_region_relations, + |mut cx| { cx.equate_inputs_and_outputs(mir, universal_regions, &normalized_inputs_and_output); - liveness::generate(cx, mir, elements, flow_inits, move_data, location_table); + liveness::generate(&mut cx, mir, elements, flow_inits, move_data, location_table); - cx.borrowck_context - .as_mut() - .map(|bcx| translate_outlives_facts(bcx)); + translate_outlives_facts(cx.borrowck_context); }, ); @@ -184,9 +181,9 @@ fn type_check_internal<'a, 'gcx, 'tcx, R>( param_env: ty::ParamEnv<'gcx>, mir: &'a Mir<'tcx>, region_bound_pairs: &'a RegionBoundPairs<'tcx>, - implicit_region_bound: Option>, - borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>, - universal_region_relations: Option<&'a UniversalRegionRelations<'tcx>>, + implicit_region_bound: ty::Region<'tcx>, + borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>, + universal_region_relations: &'a UniversalRegionRelations<'tcx>, mut extra: impl FnMut(&mut TypeChecker<'a, 'gcx, 'tcx>) -> R, ) -> R where { let mut checker = TypeChecker::new( @@ -548,15 +545,19 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { let all_facts = &mut None; let mut constraints = Default::default(); let mut closure_bounds = Default::default(); - if let Some(ref mut bcx) = self.cx.borrowck_context { - // Don't try to add borrow_region facts for the promoted MIR - mem::swap(bcx.all_facts, all_facts); - - // Use a new sets of constraints and closure bounds so that we can - // modify their locations. - mem::swap(&mut bcx.constraints.outlives_constraints, &mut constraints); - mem::swap(&mut bcx.constraints.closure_bounds_mapping, &mut closure_bounds); - }; + // Don't try to add borrow_region facts for the promoted MIR + mem::swap(self.cx.borrowck_context.all_facts, all_facts); + + // Use a new sets of constraints and closure bounds so that we can + // modify their locations. + mem::swap( + &mut self.cx.borrowck_context.constraints.outlives_constraints, + &mut constraints + ); + mem::swap( + &mut self.cx.borrowck_context.constraints.closure_bounds_mapping, + &mut closure_bounds + ); self.visit_mir(promoted_mir); @@ -567,40 +568,44 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { self.mir = parent_mir; // Merge the outlives constraints back in, at the given location. - if let Some(ref mut base_bcx) = self.cx.borrowck_context { - mem::swap(base_bcx.all_facts, all_facts); - mem::swap(&mut base_bcx.constraints.outlives_constraints, &mut constraints); - mem::swap(&mut base_bcx.constraints.closure_bounds_mapping, &mut closure_bounds); - - let locations = location.to_locations(); - for constraint in constraints.iter() { - let mut constraint = *constraint; - constraint.locations = locations; - if let ConstraintCategory::Return - | ConstraintCategory::UseAsConst - | ConstraintCategory::UseAsStatic = constraint.category - { - // "Returning" from a promoted is an assigment to a - // temporary from the user's point of view. - constraint.category = ConstraintCategory::Boring; - } - base_bcx.constraints.outlives_constraints.push(constraint) - } + mem::swap(self.cx.borrowck_context.all_facts, all_facts); + mem::swap( + &mut self.cx.borrowck_context.constraints.outlives_constraints, + &mut constraints + ); + mem::swap( + &mut self.cx.borrowck_context.constraints.closure_bounds_mapping, + &mut closure_bounds + ); - if !closure_bounds.is_empty() { - let combined_bounds_mapping = closure_bounds - .into_iter() - .flat_map(|(_, value)| value) - .collect(); - let existing = base_bcx - .constraints - .closure_bounds_mapping - .insert(location, combined_bounds_mapping); - assert!( - existing.is_none(), - "Multiple promoteds/closures at the same location." - ); + let locations = location.to_locations(); + for constraint in constraints.iter() { + let mut constraint = *constraint; + constraint.locations = locations; + if let ConstraintCategory::Return + | ConstraintCategory::UseAsConst + | ConstraintCategory::UseAsStatic = constraint.category + { + // "Returning" from a promoted is an assigment to a + // temporary from the user's point of view. + constraint.category = ConstraintCategory::Boring; } + self.cx.borrowck_context.constraints.outlives_constraints.push(constraint) + } + + if !closure_bounds.is_empty() { + let combined_bounds_mapping = closure_bounds + .into_iter() + .flat_map(|(_, value)| value) + .collect(); + let existing = self.cx.borrowck_context + .constraints + .closure_bounds_mapping + .insert(location, combined_bounds_mapping); + assert!( + existing.is_none(), + "Multiple promoteds/closures at the same location." + ); } } @@ -819,10 +824,10 @@ struct TypeChecker<'a, 'gcx: 'tcx, 'tcx: 'a> { user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>, mir_def_id: DefId, region_bound_pairs: &'a RegionBoundPairs<'tcx>, - implicit_region_bound: Option>, + implicit_region_bound: ty::Region<'tcx>, reported_errors: FxHashSet<(Ty<'tcx>, Span)>, - borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>, - universal_region_relations: Option<&'a UniversalRegionRelations<'tcx>>, + borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>, + universal_region_relations: &'a UniversalRegionRelations<'tcx>, } struct BorrowCheckContext<'a, 'tcx: 'a> { @@ -964,9 +969,9 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { mir_def_id: DefId, param_env: ty::ParamEnv<'gcx>, region_bound_pairs: &'a RegionBoundPairs<'tcx>, - implicit_region_bound: Option>, - borrowck_context: Option<&'a mut BorrowCheckContext<'a, 'tcx>>, - universal_region_relations: Option<&'a UniversalRegionRelations<'tcx>>, + implicit_region_bound: ty::Region<'tcx>, + borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>, + universal_region_relations: &'a UniversalRegionRelations<'tcx>, ) -> Self { let mut checker = Self { infcx, @@ -1080,18 +1085,16 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { locations, data ); - if let Some(ref mut borrowck_context) = self.borrowck_context { - constraint_conversion::ConstraintConversion::new( - self.infcx, - borrowck_context.universal_regions, - self.region_bound_pairs, - self.implicit_region_bound, - self.param_env, - locations, - category, - &mut borrowck_context.constraints, - ).convert_all(&data); - } + constraint_conversion::ConstraintConversion::new( + self.infcx, + self.borrowck_context.universal_regions, + self.region_bound_pairs, + Some(self.implicit_region_bound), + self.param_env, + locations, + category, + &mut self.borrowck_context.constraints, + ).convert_all(&data); } /// Convenient wrapper around `relate_tys::relate_types` -- see @@ -1111,7 +1114,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { b, locations, category, - self.borrowck_context.as_mut().map(|x| &mut **x), + Some(self.borrowck_context), ) } @@ -1264,10 +1267,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { ), )?; - let universal_region_relations = match self.universal_region_relations { - Some(rel) => rel, - None => return Ok(()), - }; + let universal_region_relations = self.universal_region_relations; // Finally, if we instantiated the anon types successfully, we // have to solve any bounds (e.g., `-> impl Iterator` needs to @@ -1312,14 +1312,14 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { // of lowering. Assignments to other sorts of places *are* interesting // though. let category = match *place { - Place::Base(PlaceBase::Local(RETURN_PLACE)) => if let Some(BorrowCheckContext { + Place::Base(PlaceBase::Local(RETURN_PLACE)) => if let BorrowCheckContext { universal_regions: UniversalRegions { defining_ty: DefiningTy::Const(def_id, _), .. }, .. - }) = self.borrowck_context + } = self.borrowck_context { if tcx.is_static(*def_id) { ConstraintCategory::UseAsStatic @@ -1547,15 +1547,13 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { // output) types in the signature must be live, since // all the inputs that fed into it were live. for &late_bound_region in map.values() { - if let Some(ref mut borrowck_context) = self.borrowck_context { - let region_vid = borrowck_context - .universal_regions - .to_region_vid(late_bound_region); - borrowck_context - .constraints - .liveness_constraints - .add_element(region_vid, term_location); - } + let region_vid = self.borrowck_context + .universal_regions + .to_region_vid(late_bound_region); + self.borrowck_context + .constraints + .liveness_constraints + .add_element(region_vid, term_location); } self.check_call_inputs(mir, term, &sig, args, term_location, from_hir_call); @@ -1617,14 +1615,14 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { let dest_ty = dest.ty(mir, tcx).ty; let category = match *dest { Place::Base(PlaceBase::Local(RETURN_PLACE)) => { - if let Some(BorrowCheckContext { + if let BorrowCheckContext { universal_regions: UniversalRegions { defining_ty: DefiningTy::Const(def_id, _), .. }, .. - }) = self.borrowck_context + } = self.borrowck_context { if tcx.is_static(*def_id) { ConstraintCategory::UseAsStatic @@ -2335,10 +2333,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { all_facts, constraints, .. - } = match self.borrowck_context { - Some(ref mut borrowck_context) => borrowck_context, - None => return, - }; + } = self.borrowck_context; // In Polonius mode, we also push a `borrow_region` fact // linking the loan to the region (in some cases, though, @@ -2504,45 +2499,43 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { let closure_constraints = closure_region_requirements.apply_requirements(tcx, def_id, substs); - if let Some(ref mut borrowck_context) = self.borrowck_context { - let bounds_mapping = closure_constraints - .iter() - .enumerate() - .filter_map(|(idx, constraint)| { - let ty::OutlivesPredicate(k1, r2) = - constraint.no_bound_vars().unwrap_or_else(|| { - bug!("query_constraint {:?} contained bound vars", constraint,); - }); - - match k1.unpack() { - UnpackedKind::Lifetime(r1) => { - // constraint is r1: r2 - let r1_vid = borrowck_context.universal_regions.to_region_vid(r1); - let r2_vid = borrowck_context.universal_regions.to_region_vid(r2); - let outlives_requirements = - &closure_region_requirements.outlives_requirements[idx]; - Some(( - (r1_vid, r2_vid), - ( - outlives_requirements.category, - outlives_requirements.blame_span, - ), - )) - } - UnpackedKind::Type(_) | UnpackedKind::Const(_) => None, + let bounds_mapping = closure_constraints + .iter() + .enumerate() + .filter_map(|(idx, constraint)| { + let ty::OutlivesPredicate(k1, r2) = + constraint.no_bound_vars().unwrap_or_else(|| { + bug!("query_constraint {:?} contained bound vars", constraint,); + }); + + match k1.unpack() { + UnpackedKind::Lifetime(r1) => { + // constraint is r1: r2 + let r1_vid = self.borrowck_context.universal_regions.to_region_vid(r1); + let r2_vid = self.borrowck_context.universal_regions.to_region_vid(r2); + let outlives_requirements = + &closure_region_requirements.outlives_requirements[idx]; + Some(( + (r1_vid, r2_vid), + ( + outlives_requirements.category, + outlives_requirements.blame_span, + ), + )) } - }) - .collect(); - - let existing = borrowck_context - .constraints - .closure_bounds_mapping - .insert(location, bounds_mapping); - assert!( - existing.is_none(), - "Multiple closures at the same location." - ); - } + UnpackedKind::Type(_) | UnpackedKind::Const(_) => None, + } + }) + .collect(); + + let existing = self.borrowck_context + .constraints + .closure_bounds_mapping + .insert(location, bounds_mapping); + assert!( + existing.is_none(), + "Multiple closures at the same location." + ); self.push_region_constraints( location.to_locations(), @@ -2660,56 +2653,6 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { } } -pub struct TypeckMir; - -impl MirPass for TypeckMir { - fn run_pass<'a, 'tcx>( - &self, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - src: MirSource<'tcx>, - mir: &mut Mir<'tcx>, - ) { - let def_id = src.def_id(); - debug!("run_pass: {:?}", def_id); - - // FIXME: We don't need this MIR pass anymore. - if true { - return; - } - - if tcx.sess.err_count() > 0 { - // compiling a broken program can obviously result in a - // broken MIR, so try not to report duplicate errors. - return; - } - - if tcx.is_constructor(def_id) { - // We just assume that the automatically generated struct/variant constructors are - // correct. See the comment in the `mir_borrowck` implementation for an - // explanation why we need this. - return; - } - - let param_env = tcx.param_env(def_id); - tcx.infer_ctxt().enter(|infcx| { - type_check_internal( - &infcx, - def_id, - param_env, - mir, - &vec![], - None, - None, - None, - |_| (), - ); - - // For verification purposes, we just ignore the resulting - // region constraint sets. Not our problem. =) - }); - } -} - trait NormalizeLocation: fmt::Debug + Copy { fn to_locations(self) -> Locations; } diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 27cb87f5dcaa0..b609164415717 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -1,4 +1,3 @@ -use crate::borrow_check::nll::type_check; use crate::build; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::mir::{Mir, MirPhase, Promoted}; @@ -205,7 +204,6 @@ fn mir_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Stea run_passes(tcx, &mut mir, InstanceDef::Item(def_id), MirPhase::Const, &[ // What we need to do constant evaluation. &simplify::SimplifyCfg::new("initial"), - &type_check::TypeckMir, &rustc_peek::SanityCheck, &uniform_array_move_out::UniformArrayMoveOut, ]); From f734057c3c8cf621dc59d4c8e29b361d40c42612 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sat, 4 May 2019 04:24:32 +0900 Subject: [PATCH 2/2] Fix test --- src/test/mir-opt/storage_ranges.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/mir-opt/storage_ranges.rs b/src/test/mir-opt/storage_ranges.rs index c099b1dccb668..6d22e9cd9fab9 100644 --- a/src/test/mir-opt/storage_ranges.rs +++ b/src/test/mir-opt/storage_ranges.rs @@ -7,7 +7,7 @@ fn main() { } // END RUST SOURCE -// START rustc.main.TypeckMir.before.mir +// START rustc.main.nll.0.mir // bb0: { // StorageLive(_1); // _1 = const 0i32; @@ -31,4 +31,4 @@ fn main() { // StorageDead(_1); // return; // } -// END rustc.main.TypeckMir.before.mir +// END rustc.main.nll.0.mir