From 6027e0810ff9f60103d2ff4c24791e40db491316 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sat, 10 Nov 2018 23:52:20 +0000 Subject: [PATCH] Only handle ReVar regions in NLL borrowck Now that lexical MIR borrowck is gone, there's no need to store Regions unnecessarily. --- src/librustc_mir/borrow_check/borrow_set.rs | 28 +++--- src/librustc_mir/borrow_check/mod.rs | 7 +- .../borrow_check/nll/explain_borrow/mod.rs | 2 +- src/librustc_mir/dataflow/impls/borrows.rs | 91 ++----------------- 4 files changed, 23 insertions(+), 105 deletions(-) diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index c432826dca8..fd7dc7fc4bd 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -9,6 +9,7 @@ // except according to those terms. use borrow_check::place_ext::PlaceExt; +use borrow_check::nll::ToRegionVid; use dataflow::indexes::BorrowIndex; use dataflow::move_paths::MoveData; use rustc::mir::traversal; @@ -16,7 +17,7 @@ PlaceContext, Visitor, NonUseContext, MutatingUseContext, NonMutatingUseContext }; use rustc::mir::{self, Location, Mir, Place, Local}; -use rustc::ty::{Region, TyCtxt}; +use rustc::ty::{RegionVid, TyCtxt}; use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::bit_set::BitSet; @@ -42,7 +43,7 @@ /// Every borrow has a region; this maps each such regions back to /// its borrow-indexes. - crate region_map: FxHashMap, FxHashSet>, + crate region_map: FxHashMap>, /// Map from local to all the borrows on that local crate local_map: FxHashMap>, @@ -77,7 +78,7 @@ fn index(&self, index: BorrowIndex) -> &BorrowData<'tcx> { /// What kind of borrow this is crate kind: mir::BorrowKind, /// The region for which this borrow is live - crate region: Region<'tcx>, + crate region: RegionVid, /// Place from which we are borrowing crate borrowed_place: mir::Place<'tcx>, /// Place to which the borrow was stored @@ -92,13 +93,7 @@ fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { mir::BorrowKind::Unique => "uniq ", mir::BorrowKind::Mut { .. } => "mut ", }; - let region = self.region.to_string(); - let separator = if !region.is_empty() { - " " - } else { - "" - }; - write!(w, "&{}{}{}{:?}", region, separator, kind, self.borrowed_place) + write!(w, "&{:?} {}{:?}", self.region, kind, self.borrowed_place) } } @@ -189,7 +184,7 @@ struct GatherBorrows<'a, 'gcx: 'tcx, 'tcx: 'a> { idx_vec: IndexVec>, location_map: FxHashMap, activation_map: FxHashMap>, - region_map: FxHashMap, FxHashSet>, + region_map: FxHashMap>, local_map: FxHashMap>, /// When we encounter a 2-phase borrow statement, it will always @@ -219,6 +214,8 @@ fn visit_assign( return; } + let region = region.to_region_vid(); + let borrow = BorrowData { kind, region, @@ -230,7 +227,7 @@ fn visit_assign( let idx = self.idx_vec.push(borrow); self.location_map.insert(location, idx); - self.insert_as_pending_if_two_phase(location, &assigned_place, region, kind, idx); + self.insert_as_pending_if_two_phase(location, &assigned_place, kind, idx); self.region_map.entry(region).or_default().insert(idx); if let Some(local) = borrowed_place.root_local() { @@ -314,7 +311,7 @@ fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: mir::Location) let borrow_data = &self.idx_vec[borrow_index]; assert_eq!(borrow_data.reserve_location, location); assert_eq!(borrow_data.kind, kind); - assert_eq!(borrow_data.region, region); + assert_eq!(borrow_data.region, region.to_region_vid()); assert_eq!(borrow_data.borrowed_place, *place); } @@ -347,13 +344,12 @@ fn insert_as_pending_if_two_phase( &mut self, start_location: Location, assigned_place: &mir::Place<'tcx>, - region: Region<'tcx>, kind: mir::BorrowKind, borrow_index: BorrowIndex, ) { debug!( - "Borrows::insert_as_pending_if_two_phase({:?}, {:?}, {:?}, {:?})", - start_location, assigned_place, region, borrow_index, + "Borrows::insert_as_pending_if_two_phase({:?}, {:?}, {:?})", + start_location, assigned_place, borrow_index, ); if !self.allow_two_phase_borrow(kind) { diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 8819908de6a..76ba6ae5de6 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -14,7 +14,6 @@ use rustc::hir; use rustc::hir::Node; use rustc::hir::def_id::DefId; -use rustc::hir::map::definitions::DefPathData; use rustc::infer::InferCtxt; use rustc::lint::builtin::UNUSED_MUT; use rustc::middle::borrowck::SignalledError; @@ -162,10 +161,6 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( move_data: move_data, param_env: param_env, }; - let body_id = match tcx.def_key(def_id).disambiguated_data.data { - DefPathData::StructCtor | DefPathData::EnumVariant(_) => None, - _ => Some(tcx.hir.body_owned_by(id)), - }; let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len()); let mut flow_inits = FlowAtLocation::new(do_dataflow( @@ -212,7 +207,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>( id, &attributes, &dead_unwinds, - Borrows::new(tcx, mir, regioncx.clone(), def_id, body_id, &borrow_set), + Borrows::new(tcx, mir, regioncx.clone(), &borrow_set), |rs, i| DebugFormatted::new(&rs.location(i)), )); let flow_uninits = FlowAtLocation::new(do_dataflow( diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index 2bf531d1d3e..bb9a29b055b 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -206,7 +206,7 @@ pub(in borrow_check) fn explain_why_borrow_contains_point( let mir = self.mir; let tcx = self.infcx.tcx; - let borrow_region_vid = regioncx.to_region_vid(borrow.region); + let borrow_region_vid = borrow.region; debug!( "explain_why_borrow_contains_point: borrow_region_vid={:?}", borrow_region_vid diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 5e84aa05d38..27bc28ac81d 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -12,18 +12,13 @@ use borrow_check::place_ext::PlaceExt; use rustc; -use rustc::hir; -use rustc::hir::def_id::DefId; -use rustc::middle::region; use rustc::mir::{self, Location, Place, Mir}; use rustc::ty::TyCtxt; -use rustc::ty::{RegionKind, RegionVid}; -use rustc::ty::RegionKind::ReScope; +use rustc::ty::RegionVid; use rustc_data_structures::bit_set::{BitSet, BitSetOperator}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; -use rustc_data_structures::sync::Lrc; use dataflow::{BitDenotation, BlockSets, InitialFlow}; pub use dataflow::indexes::BorrowIndex; @@ -42,8 +37,6 @@ pub struct Borrows<'a, 'gcx: 'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, mir: &'a Mir<'tcx>, - scope_tree: Lrc, - root_scope: Option, borrow_set: Rc>, borrows_out_of_scope_at_location: FxHashMap>, @@ -150,18 +143,8 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { tcx: TyCtxt<'a, 'gcx, 'tcx>, mir: &'a Mir<'tcx>, nonlexical_regioncx: Rc>, - def_id: DefId, - body_id: Option, borrow_set: &Rc>, ) -> Self { - let scope_tree = tcx.region_scope_tree(def_id); - let root_scope = body_id.map(|body_id| { - region::Scope { - id: tcx.hir.body(body_id).value.hir_id.local_id, - data: region::ScopeData::CallSite - } - }); - let mut borrows_out_of_scope_at_location = FxHashMap::default(); for (borrow_index, borrow_data) in borrow_set.borrows.iter_enumerated() { let borrow_region = borrow_data.region.to_region_vid(); @@ -177,8 +160,6 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { mir: mir, borrow_set: borrow_set.clone(), borrows_out_of_scope_at_location, - scope_tree, - root_scope, _nonlexical_regioncx: nonlexical_regioncx, } } @@ -277,22 +258,13 @@ fn statement_effect(&self, sets: &mut BlockSets, location: Location panic!("could not find BorrowIndex for location {:?}", location); }); - if let RegionKind::ReEmpty = region { - // If the borrowed value dies before the borrow is used, the region for - // the borrow can be empty. Don't track the borrow in that case. - debug!("Borrows::statement_effect_on_borrows \ - location: {:?} stmt: {:?} has empty region, killing {:?}", - location, stmt.kind, index); - sets.kill(*index); - return - } else { - debug!("Borrows::statement_effect_on_borrows location: {:?} stmt: {:?}", - location, stmt.kind); - } - - assert!(self.borrow_set.region_map.get(region).unwrap_or_else(|| { - panic!("could not find BorrowIndexs for region {:?}", region); - }).contains(&index)); + assert!(self.borrow_set.region_map + .get(®ion.to_region_vid()) + .unwrap_or_else(|| { + panic!("could not find BorrowIndexs for RegionVid {:?}", region); + }) + .contains(&index) + ); sets.gen(*index); // Issue #46746: Two-phase borrows handles @@ -349,52 +321,7 @@ fn before_terminator_effect(&self, self.kill_loans_out_of_scope_at_location(sets, location); } - fn terminator_effect(&self, sets: &mut BlockSets, location: Location) { - debug!("Borrows::terminator_effect sets: {:?} location: {:?}", sets, location); - - let block = &self.mir.basic_blocks().get(location.block).unwrap_or_else(|| { - panic!("could not find block at location {:?}", location); - }); - - let term = block.terminator(); - match term.kind { - mir::TerminatorKind::Resume | - mir::TerminatorKind::Return | - mir::TerminatorKind::GeneratorDrop => { - // When we return from the function, then all `ReScope`-style regions - // are guaranteed to have ended. - // Normally, there would be `EndRegion` statements that come before, - // and hence most of these loans will already be dead -- but, in some cases - // like unwind paths, we do not always emit `EndRegion` statements, so we - // add some kills here as a "backup" and to avoid spurious error messages. - for (borrow_index, borrow_data) in self.borrow_set.borrows.iter_enumerated() { - if let ReScope(scope) = borrow_data.region { - // Check that the scope is not actually a scope from a function that is - // a parent of our closure. Note that the CallSite scope itself is - // *outside* of the closure, for some weird reason. - if let Some(root_scope) = self.root_scope { - if *scope != root_scope && - self.scope_tree.is_subscope_of(*scope, root_scope) - { - sets.kill(borrow_index); - } - } - } - } - } - mir::TerminatorKind::Abort | - mir::TerminatorKind::SwitchInt {..} | - mir::TerminatorKind::Drop {..} | - mir::TerminatorKind::DropAndReplace {..} | - mir::TerminatorKind::Call {..} | - mir::TerminatorKind::Assert {..} | - mir::TerminatorKind::Yield {..} | - mir::TerminatorKind::Goto {..} | - mir::TerminatorKind::FalseEdges {..} | - mir::TerminatorKind::FalseUnwind {..} | - mir::TerminatorKind::Unreachable => {} - } - } + fn terminator_effect(&self, _: &mut BlockSets, _: Location) {} fn propagate_call_return(&self, _in_out: &mut BitSet, -- 2.44.0