From 70592664b6b071af2fe03afb60ffb9cfab6feaf7 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 6 Apr 2018 15:18:01 -0400 Subject: [PATCH] relocate `BorrowData` etc into `borrow_check::borrow_set` --- src/librustc_mir/borrow_check/borrow_set.rs | 78 ++++++++++++++ .../borrow_check/error_reporting.rs | 6 +- src/librustc_mir/borrow_check/mod.rs | 4 +- .../borrow_check/nll/explain_borrow/mod.rs | 2 +- src/librustc_mir/dataflow/impls/borrows.rs | 100 +++++------------- src/librustc_mir/dataflow/impls/mod.rs | 1 + src/librustc_mir/dataflow/mod.rs | 2 +- src/librustc_mir/lib.rs | 1 + 8 files changed, 113 insertions(+), 81 deletions(-) create mode 100644 src/librustc_mir/borrow_check/borrow_set.rs diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs new file mode 100644 index 00000000000..4d541d0ffd2 --- /dev/null +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -0,0 +1,78 @@ +// Copyright 2012-2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use dataflow::indexes::BorrowIndex; +use rustc::mir::{self, Location}; +use rustc::ty::{Region, RegionKind}; +use rustc::util::nodemap::{FxHashMap, FxHashSet}; +use rustc_data_structures::indexed_vec::IndexVec; +use std::fmt; +use syntax_pos::Span; + +crate struct BorrowSet<'tcx> { + /// The fundamental map relating bitvector indexes to the borrows + /// in the MIR. + crate borrows: IndexVec>, + + /// Each borrow is also uniquely identified in the MIR by the + /// `Location` of the assignment statement in which it appears on + /// the right hand side; we map each such location to the + /// corresponding `BorrowIndex`. + crate location_map: FxHashMap, + + /// Locations which activate borrows. + /// NOTE: A given location may activate more than one borrow in the future + /// when more general two-phase borrow support is introduced, but for now we + /// only need to store one borrow index + crate activation_map: FxHashMap>, + + /// Every borrow has a region; this maps each such regions back to + /// its borrow-indexes. + crate region_map: FxHashMap, FxHashSet>, + + /// Map from local to all the borrows on that local + crate local_map: FxHashMap>, + + /// Maps regions to their corresponding source spans + /// Only contains ReScope()s as keys + crate region_span_map: FxHashMap, +} + +#[derive(Debug)] +crate struct BorrowData<'tcx> { + /// Location where the borrow reservation starts. + /// In many cases, this will be equal to the activation location but not always. + crate reserve_location: Location, + /// Location where the borrow is activated. None if this is not a + /// 2-phase borrow. + crate activation_location: Option, + /// What kind of borrow this is + crate kind: mir::BorrowKind, + /// The region for which this borrow is live + crate region: Region<'tcx>, + /// Place from which we are borrowing + crate borrowed_place: mir::Place<'tcx>, + /// Place to which the borrow was stored + crate assigned_place: mir::Place<'tcx>, +} + +impl<'tcx> fmt::Display for BorrowData<'tcx> { + fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { + let kind = match self.kind { + mir::BorrowKind::Shared => "", + mir::BorrowKind::Unique => "uniq ", + mir::BorrowKind::Mut { .. } => "mut ", + }; + let region = format!("{}", self.region); + let region = if region.len() > 0 { format!("{} ", region) } else { region }; + write!(w, "&{}{}{:?}", region, kind, self.borrowed_place) + } +} + diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index aaed1dd871b..8160a3201da 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -18,7 +18,9 @@ use rustc_data_structures::sync::Lrc; use super::{Context, MirBorrowckCtxt}; use super::{InitializationRequiringAction, PrefixSet}; -use dataflow::{Borrows, BorrowData, FlowAtLocation, MovingOutStatements}; +use super::borrow_set::BorrowData; + +use dataflow::{Borrows, FlowAtLocation, MovingOutStatements}; use dataflow::move_paths::MovePathIndex; use util::borrowck_errors::{BorrowckErrors, Origin}; @@ -834,7 +836,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } // Retrieve span of given borrow from the current MIR representation - pub fn retrieve_borrow_span(&self, borrow: &BorrowData) -> Span { + crate fn retrieve_borrow_span(&self, borrow: &BorrowData) -> Span { self.mir.source_info(borrow.reserve_location).span } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 62acdf76546..69044a3c83e 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -37,7 +37,7 @@ use dataflow::MoveDataParamEnv; use dataflow::{DataflowResultsConsumer}; use dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; use dataflow::{EverInitializedPlaces, MovingOutStatements}; -use dataflow::{BorrowData, Borrows, ReserveOrActivateIndex}; +use dataflow::{Borrows, ReserveOrActivateIndex}; use dataflow::indexes::BorrowIndex; use dataflow::move_paths::{IllegalMoveOriginKind, MoveError}; use dataflow::move_paths::{HasMoveData, LookupResult, MoveData, MovePathIndex}; @@ -46,10 +46,12 @@ use util::collect_writes::FindAssignments; use std::iter; +use self::borrow_set::BorrowData; use self::flows::Flows; use self::prefixes::PrefixSet; use self::MutateMode::{JustWrite, WriteAndRead}; +crate mod borrow_set; mod error_reporting; mod flows; mod prefixes; 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 187bfc2bf90..b12beb524e2 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -10,7 +10,7 @@ use borrow_check::nll::region_infer::{Cause, RegionInferenceContext}; use borrow_check::{Context, MirBorrowckCtxt}; -use dataflow::BorrowData; +use borrow_check::borrow_set::BorrowData; use rustc::mir::visit::{MirVisitable, PlaceContext, Visitor}; use rustc::mir::{Local, Location, Mir}; use rustc_data_structures::fx::FxHashSet; diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index b83e78ef1d1..381718234a6 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use borrow_check::borrow_set::{BorrowSet, BorrowData}; + use rustc; use rustc::hir; use rustc::hir::def_id::DefId; @@ -32,7 +34,6 @@ use borrow_check::nll::ToRegionVid; use syntax_pos::Span; -use std::fmt; use std::hash::Hash; use std::rc::Rc; @@ -49,69 +50,12 @@ pub struct Borrows<'a, 'gcx: 'tcx, 'tcx: 'a> { scope_tree: Lrc, root_scope: Option, - /// The fundamental map relating bitvector indexes to the borrows - /// in the MIR. - borrows: IndexVec>, - - /// Each borrow is also uniquely identified in the MIR by the - /// `Location` of the assignment statement in which it appears on - /// the right hand side; we map each such location to the - /// corresponding `BorrowIndex`. - location_map: FxHashMap, - - /// Locations which activate borrows. - activation_map: FxHashMap>, - - /// Every borrow has a region; this maps each such regions back to - /// its borrow-indexes. - region_map: FxHashMap, FxHashSet>, - - /// Map from local to all the borrows on that local - local_map: FxHashMap>, - - /// Maps regions to their corresponding source spans - /// Only contains ReScope()s as keys - region_span_map: FxHashMap, + borrow_set: BorrowSet<'tcx>, /// NLL region inference context with which NLL queries should be resolved nonlexical_regioncx: Option>>, } -// temporarily allow some dead fields: `kind` and `region` will be -// needed by borrowck; `borrowed_place` will probably be a MovePathIndex when -// that is extended to include borrowed data paths. -#[allow(dead_code)] -#[derive(Debug)] -pub struct BorrowData<'tcx> { - /// Location where the borrow reservation starts. - /// In many cases, this will be equal to the activation location but not always. - pub(crate) reserve_location: Location, - /// Location where the borrow is activated. None if this is not a - /// 2-phase borrow. - pub(crate) activation_location: Option, - /// What kind of borrow this is - pub(crate) kind: mir::BorrowKind, - /// The region for which this borrow is live - pub(crate) region: Region<'tcx>, - /// Place from which we are borrowing - pub(crate) borrowed_place: mir::Place<'tcx>, - /// Place to which the borrow was stored - pub(crate) assigned_place: mir::Place<'tcx>, -} - -impl<'tcx> fmt::Display for BorrowData<'tcx> { - fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result { - let kind = match self.kind { - mir::BorrowKind::Shared => "", - mir::BorrowKind::Unique => "uniq ", - mir::BorrowKind::Mut { .. } => "mut ", - }; - let region = format!("{}", self.region); - let region = if region.len() > 0 { format!("{} ", region) } else { region }; - write!(w, "&{}{}{:?}", region, kind, self.borrowed_place) - } -} - impl ReserveOrActivateIndex { fn reserved(i: BorrowIndex) -> Self { ReserveOrActivateIndex::new(i.index() * 2) } fn active(i: BorrowIndex) -> Self { ReserveOrActivateIndex::new((i.index() * 2) + 1) } @@ -169,14 +113,16 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { return Borrows { tcx: tcx, mir: mir, - borrows: visitor.idx_vec, + borrow_set: BorrowSet { + borrows: visitor.idx_vec, + location_map: visitor.location_map, + activation_map: visitor.activation_map, + region_map: visitor.region_map, + local_map: visitor.local_map, + region_span_map: visitor.region_span_map, + }, scope_tree, root_scope, - location_map: visitor.location_map, - activation_map: visitor.activation_map, - region_map: visitor.region_map, - local_map: visitor.local_map, - region_span_map: visitor.region_span_map, nonlexical_regioncx }; struct GatherBorrows<'a, 'gcx: 'tcx, 'tcx: 'a> { @@ -514,7 +460,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { match self.nonlexical_regioncx { Some(_) => None, None => { - match self.region_span_map.get(region) { + match self.borrow_set.region_span_map.get(region) { Some(span) => Some(self.tcx.sess.codemap().end_point(*span)), None => Some(self.tcx.sess.codemap().end_point(self.mir.span)) } @@ -522,12 +468,12 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { } } - pub fn borrows(&self) -> &IndexVec> { &self.borrows } + crate fn borrows(&self) -> &IndexVec> { &self.borrow_set.borrows } pub fn scope_tree(&self) -> &Lrc { &self.scope_tree } pub fn location(&self, idx: BorrowIndex) -> &Location { - &self.borrows[idx].reserve_location + &self.borrow_set.borrows[idx].reserve_location } /// Add all borrows to the kill set, if those borrows are out of scope at `location`. @@ -548,7 +494,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { // terminator *does* introduce a new loan of the same // region, then setting that gen-bit will override any // potential kill introduced here. - for (borrow_index, borrow_data) in self.borrows.iter_enumerated() { + for (borrow_index, borrow_data) in self.borrow_set.borrows.iter_enumerated() { let borrow_region = borrow_data.region.to_region_vid(); if !regioncx.region_contains_point(borrow_region, location) { sets.kill(&ReserveOrActivateIndex::reserved(borrow_index)); @@ -562,7 +508,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { sets: &mut BlockSets, local: &rustc::mir::Local) { - if let Some(borrow_indexes) = self.local_map.get(local) { + if let Some(borrow_indexes) = self.borrow_set.local_map.get(local) { sets.kill_all(borrow_indexes.iter() .map(|b| ReserveOrActivateIndex::reserved(*b))); sets.kill_all(borrow_indexes.iter() @@ -575,7 +521,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { sets: &mut BlockSets, location: Location) { // Handle activations - match self.activation_map.get(&location) { + match self.borrow_set.activation_map.get(&location) { Some(activations) => { for activated in activations { debug!("activating borrow {:?}", activated); @@ -591,7 +537,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { type Idx = ReserveOrActivateIndex; fn name() -> &'static str { "borrows" } fn bits_per_block(&self) -> usize { - self.borrows.len() * 2 + self.borrow_set.borrows.len() * 2 } fn start_block_effect(&self, _entry_set: &mut IdxSet) { @@ -623,7 +569,9 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { match stmt.kind { // EndRegion kills any borrows (reservations and active borrows both) mir::StatementKind::EndRegion(region_scope) => { - if let Some(borrow_indexes) = self.region_map.get(&ReScope(region_scope)) { + if let Some(borrow_indexes) = + self.borrow_set.region_map.get(&ReScope(region_scope)) + { assert!(self.nonlexical_regioncx.is_none()); for idx in borrow_indexes { sets.kill(&ReserveOrActivateIndex::reserved(*idx)); @@ -650,7 +598,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { if let mir::Rvalue::Ref(region, _, ref place) = *rhs { if is_unsafe_place(self.tcx, self.mir, place) { return; } - let index = self.location_map.get(&location).unwrap_or_else(|| { + let index = self.borrow_set.location_map.get(&location).unwrap_or_else(|| { panic!("could not find BorrowIndex for location {:?}", location); }); @@ -661,7 +609,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { return } - assert!(self.region_map.get(region).unwrap_or_else(|| { + assert!(self.borrow_set.region_map.get(region).unwrap_or_else(|| { panic!("could not find BorrowIndexs for region {:?}", region); }).contains(&index)); sets.gen(&ReserveOrActivateIndex::reserved(*index)); @@ -739,7 +687,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { // 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.borrows.iter_enumerated() { + 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 diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs index 287640439c0..72b6f9d54fd 100644 --- a/src/librustc_mir/dataflow/impls/mod.rs +++ b/src/librustc_mir/dataflow/impls/mod.rs @@ -19,6 +19,7 @@ use rustc_data_structures::indexed_set::{IdxSet}; use rustc_data_structures::indexed_vec::Idx; use super::MoveDataParamEnv; + use util::elaborate_drops::DropFlagState; use super::move_paths::{HasMoveData, MoveData, MoveOutIndex, MovePathIndex, InitIndex}; diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index 454b6cbd27d..557799305f9 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -29,7 +29,7 @@ pub use self::impls::{MaybeStorageLive}; pub use self::impls::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; pub use self::impls::{DefinitelyInitializedPlaces, MovingOutStatements}; pub use self::impls::EverInitializedPlaces; -pub use self::impls::borrows::{Borrows, BorrowData}; +pub use self::impls::borrows::Borrows; pub use self::impls::HaveBeenBorrowedLocals; pub(crate) use self::impls::borrows::{ReserveOrActivateIndex}; pub use self::at_location::{FlowAtLocation, FlowsAtLocation}; diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index a701fe31442..de3063a5756 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -20,6 +20,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(box_patterns)] #![feature(box_syntax)] #![feature(catch_expr)] +#![feature(crate_visibility_modifier)] #![feature(const_fn)] #![feature(core_intrinsics)] #![feature(decl_macro)]