1
Fork 0

relocate BorrowData etc into borrow_check::borrow_set

This commit is contained in:
Niko Matsakis 2018-04-06 15:18:01 -04:00
parent 6c528ce784
commit 70592664b6
8 changed files with 113 additions and 81 deletions

View file

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<BorrowIndex, BorrowData<'tcx>>,
/// 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<Location, BorrowIndex>,
/// 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<Location, FxHashSet<BorrowIndex>>,
/// Every borrow has a region; this maps each such regions back to
/// its borrow-indexes.
crate region_map: FxHashMap<Region<'tcx>, FxHashSet<BorrowIndex>>,
/// Map from local to all the borrows on that local
crate local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>,
/// Maps regions to their corresponding source spans
/// Only contains ReScope()s as keys
crate region_span_map: FxHashMap<RegionKind, Span>,
}
#[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<Location>,
/// 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)
}
}

View file

@ -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
}

View file

@ -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;

View file

@ -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;

View file

@ -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<region::ScopeTree>,
root_scope: Option<region::Scope>,
/// The fundamental map relating bitvector indexes to the borrows
/// in the MIR.
borrows: IndexVec<BorrowIndex, BorrowData<'tcx>>,
/// 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<Location, BorrowIndex>,
/// Locations which activate borrows.
activation_map: FxHashMap<Location, FxHashSet<BorrowIndex>>,
/// Every borrow has a region; this maps each such regions back to
/// its borrow-indexes.
region_map: FxHashMap<Region<'tcx>, FxHashSet<BorrowIndex>>,
/// Map from local to all the borrows on that local
local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>,
/// Maps regions to their corresponding source spans
/// Only contains ReScope()s as keys
region_span_map: FxHashMap<RegionKind, Span>,
borrow_set: BorrowSet<'tcx>,
/// NLL region inference context with which NLL queries should be resolved
nonlexical_regioncx: Option<Rc<RegionInferenceContext<'tcx>>>,
}
// 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<Location>,
/// 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<BorrowIndex, BorrowData<'tcx>> { &self.borrows }
crate fn borrows(&self) -> &IndexVec<BorrowIndex, BorrowData<'tcx>> { &self.borrow_set.borrows }
pub fn scope_tree(&self) -> &Lrc<region::ScopeTree> { &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<ReserveOrActivateIndex>,
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<ReserveOrActivateIndex>,
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<ReserveOrActivateIndex>) {
@ -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

View file

@ -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};

View file

@ -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};

View file

@ -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)]