Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MIR-borrowck] Two phase borrows #46537

Merged
merged 23 commits into from
Dec 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
93c4ffe
Revised graphviz rendering API to avoid requiring borrowed state.
pnkfelix Nov 24, 2017
171c2ae
Expanded HIR `--unpretty hir,identified` to include HIR local id.
pnkfelix Nov 24, 2017
d4add5d
Refactoring: pull bitvector initialization out from other parts of da…
pnkfelix Nov 27, 2017
e123117
Refactoring: Allow `BlockSets.on_entry` to denote locally accumulated…
pnkfelix Nov 27, 2017
39e126c
Refactoring alpha-rename `place` (`BorrowData` field) to `borrowed_p…
pnkfelix Nov 28, 2017
e437e49
Implement Borrow/BorrowMut/ToOwned relationships betweed IdxSetBuf an…
pnkfelix Dec 1, 2017
ef64ace
Allow `mir::Place` to be used as a key in hashtables.
pnkfelix Dec 1, 2017
ced5a70
New `ActiveBorrows` dataflow for two-phase `&mut`; not yet borrowed-c…
pnkfelix Dec 1, 2017
658ed79
Add some doc to `each_borrow_involving_path` iteration function.
pnkfelix Dec 13, 2017
1334638
Add some doc to `struct Borrows`.
pnkfelix Dec 13, 2017
3621645
Incorporate active-borrows dataflow into MIR borrow check, yielding
pnkfelix Dec 1, 2017
5f759a9
the minimal test for two-phase borrows: the core example from niko's …
pnkfelix Dec 5, 2017
dbbec4d
tests transcribed from nikos blog post.
pnkfelix Dec 5, 2017
db5420b
test describing a currently unsupported corner case.
pnkfelix Dec 6, 2017
9cb92ac
two-phase-reservation-sharing-interference.rs variant that is perhaps…
pnkfelix Dec 6, 2017
18aedf6
Sidestep ICE from `MirBorrowckCtxt::find_closure_span`.
pnkfelix Dec 13, 2017
5cae7a0
Check activation points as the place where mutable borrows become rel…
pnkfelix Dec 7, 2017
3c7d9ff
Address review comment: use `.get` instead of indexing to cope w/ ter…
pnkfelix Dec 14, 2017
f96777c
After discussion with ariel, replacing a guard within kill_loans_out_…
pnkfelix Dec 14, 2017
b75248e
Address review note: `AccessErrorsReported` meant to track whether er…
pnkfelix Dec 14, 2017
b0421fa
Address review feedback: don't bother skipping reservations paired wi…
pnkfelix Dec 14, 2017
d654cd3
Review feedback: Added test with control flow merge of two borrows "b…
pnkfelix Dec 14, 2017
159037e
Address review feedback: don't treat "first" activation special.
pnkfelix Dec 14, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,7 @@ impl<'tcx> Debug for Statement<'tcx> {

/// A path to a value; something that can be evaluated without
/// changing or disturbing program state.
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum Place<'tcx> {
/// local variable
Local(Local),
Expand All @@ -1150,7 +1150,7 @@ pub enum Place<'tcx> {

/// The def-id of a static, along with its normalized type (which is
/// stored to avoid requiring normalization when reading MIR).
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct Static<'tcx> {
pub def_id: DefId,
pub ty: Ty<'tcx>,
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"emit EndRegion as part of MIR; enable transforms that solely process EndRegion"),
borrowck: Option<String> = (None, parse_opt_string, [UNTRACKED],
"select which borrowck is used (`ast`, `mir`, or `compare`)"),
two_phase_borrows: bool = (false, parse_bool, [UNTRACKED],
"use two-phase reserved/active distinction for `&mut` borrows in MIR borrowck"),
time_passes: bool = (false, parse_bool, [UNTRACKED],
"measure time of each rustc pass"),
count_llvm_insns: bool = (false, parse_bool,
Expand Down
20 changes: 20 additions & 0 deletions src/librustc_data_structures/indexed_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::borrow::{Borrow, BorrowMut, ToOwned};
use std::fmt;
use std::iter;
use std::marker::PhantomData;
Expand Down Expand Up @@ -73,6 +74,25 @@ pub struct IdxSet<T: Idx> {
bits: [Word],
}

impl<T: Idx> Borrow<IdxSet<T>> for IdxSetBuf<T> {
fn borrow(&self) -> &IdxSet<T> {
&*self
}
}

impl<T: Idx> BorrowMut<IdxSet<T>> for IdxSetBuf<T> {
fn borrow_mut(&mut self) -> &mut IdxSet<T> {
&mut *self
}
}

impl<T: Idx> ToOwned for IdxSet<T> {
type Owned = IdxSetBuf<T>;
fn to_owned(&self) -> Self::Owned {
IdxSet::to_owned(self)
}
}

impl<T: Idx> fmt::Debug for IdxSetBuf<T> {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
w.debug_list()
Expand Down
12 changes: 8 additions & 4 deletions src/librustc_driver/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,24 +423,28 @@ impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> {
pprust_hir::NodeName(_) => Ok(()),
pprust_hir::NodeItem(item) => {
s.s.space()?;
s.synth_comment(item.id.to_string())
s.synth_comment(format!("node_id: {} hir local_id: {}",
item.id, item.hir_id.local_id.0))
}
pprust_hir::NodeSubItem(id) => {
s.s.space()?;
s.synth_comment(id.to_string())
}
pprust_hir::NodeBlock(blk) => {
s.s.space()?;
s.synth_comment(format!("block {}", blk.id))
s.synth_comment(format!("block node_id: {} hir local_id: {}",
blk.id, blk.hir_id.local_id.0))
}
pprust_hir::NodeExpr(expr) => {
s.s.space()?;
s.synth_comment(expr.id.to_string())?;
s.synth_comment(format!("node_id: {} hir local_id: {}",
expr.id, expr.hir_id.local_id.0))?;
s.pclose()
}
pprust_hir::NodePat(pat) => {
s.s.space()?;
s.synth_comment(format!("pat {}", pat.id))
s.synth_comment(format!("pat node_id: {} hir local_id: {}",
pat.id, pat.hir_id.local_id.0))
}
}
}
Expand Down
25 changes: 11 additions & 14 deletions src/librustc_mir/borrow_check/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
use syntax_pos::Span;
use rustc::middle::region::ScopeTree;
use rustc::mir::{BorrowKind, Field, Local, Location, Operand};
use rustc::mir::{Place, ProjectionElem, Rvalue, StatementKind};
use rustc::mir::{Place, ProjectionElem, Rvalue, Statement, StatementKind};
use rustc::ty::{self, RegionKind};
use rustc_data_structures::indexed_vec::Idx;

use std::rc::Rc;

use super::{MirBorrowckCtxt, Context};
use super::{InitializationRequiringAction, PrefixSet};
use dataflow::{BorrowData, Borrows, FlowAtLocation, MovingOutStatements};
use dataflow::{ActiveBorrows, BorrowData, FlowAtLocation, MovingOutStatements};
use dataflow::move_paths::MovePathIndex;
use util::borrowck_errors::{BorrowckErrors, Origin};

Expand Down Expand Up @@ -96,7 +96,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
Some(name) => format!("`{}`", name),
None => "value".to_owned(),
};
let borrow_msg = match self.describe_place(&borrow.place) {
let borrow_msg = match self.describe_place(&borrow.borrowed_place) {
Some(name) => format!("`{}`", name),
None => "value".to_owned(),
};
Expand Down Expand Up @@ -124,7 +124,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
span,
&self.describe_place(place).unwrap_or("_".to_owned()),
self.retrieve_borrow_span(borrow),
&self.describe_place(&borrow.place).unwrap_or("_".to_owned()),
&self.describe_place(&borrow.borrowed_place).unwrap_or("_".to_owned()),
Origin::Mir,
);

Expand All @@ -143,12 +143,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
use rustc::hir::ExprClosure;
use rustc::mir::AggregateKind;

let local = if let StatementKind::Assign(Place::Local(local), _) =
self.mir[location.block].statements[location.statement_index].kind
{
local
} else {
return None;
let local = match self.mir[location.block].statements.get(location.statement_index) {
Some(&Statement { kind: StatementKind::Assign(Place::Local(local), _), .. }) => local,
_ => return None,
};

for stmt in &self.mir[location.block].statements[location.statement_index + 1..] {
Expand Down Expand Up @@ -324,11 +321,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
_: Context,
borrow: &BorrowData<'tcx>,
drop_span: Span,
borrows: &Borrows<'cx, 'gcx, 'tcx>
borrows: &ActiveBorrows<'cx, 'gcx, 'tcx>
) {
let end_span = borrows.opt_region_end_span(&borrow.region);
let scope_tree = borrows.scope_tree();
let root_place = self.prefixes(&borrow.place, PrefixSet::All).last().unwrap();
let scope_tree = borrows.0.scope_tree();
let root_place = self.prefixes(&borrow.borrowed_place, PrefixSet::All).last().unwrap();

match root_place {
&Place::Local(local) => {
Expand Down Expand Up @@ -357,7 +354,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
_ => drop_span,
};

match (borrow.region, &self.describe_place(&borrow.place)) {
match (borrow.region, &self.describe_place(&borrow.borrowed_place)) {
(RegionKind::ReScope(_), Some(name)) => {
self.report_scoped_local_value_does_not_live_long_enough(
name, &scope_tree, &borrow, drop_span, borrow_span, proper_span, end_span);
Expand Down
12 changes: 6 additions & 6 deletions src/librustc_mir/borrow_check/flows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ use rustc::mir::{BasicBlock, Location};

use dataflow::{MaybeInitializedLvals, MaybeUninitializedLvals};
use dataflow::{EverInitializedLvals, MovingOutStatements};
use dataflow::{Borrows, FlowAtLocation, FlowsAtLocation};
use dataflow::{ActiveBorrows, FlowAtLocation, FlowsAtLocation};
use dataflow::move_paths::HasMoveData;
use std::fmt;

// (forced to be `pub` due to its use as an associated type below.)
pub struct Flows<'b, 'gcx: 'tcx, 'tcx: 'b> {
pub borrows: FlowAtLocation<Borrows<'b, 'gcx, 'tcx>>,
pub(crate) struct Flows<'b, 'gcx: 'tcx, 'tcx: 'b> {
pub borrows: FlowAtLocation<ActiveBorrows<'b, 'gcx, 'tcx>>,
pub inits: FlowAtLocation<MaybeInitializedLvals<'b, 'gcx, 'tcx>>,
pub uninits: FlowAtLocation<MaybeUninitializedLvals<'b, 'gcx, 'tcx>>,
pub move_outs: FlowAtLocation<MovingOutStatements<'b, 'gcx, 'tcx>>,
Expand All @@ -32,7 +32,7 @@ pub struct Flows<'b, 'gcx: 'tcx, 'tcx: 'b> {

impl<'b, 'gcx, 'tcx> Flows<'b, 'gcx, 'tcx> {
pub fn new(
borrows: FlowAtLocation<Borrows<'b, 'gcx, 'tcx>>,
borrows: FlowAtLocation<ActiveBorrows<'b, 'gcx, 'tcx>>,
inits: FlowAtLocation<MaybeInitializedLvals<'b, 'gcx, 'tcx>>,
uninits: FlowAtLocation<MaybeUninitializedLvals<'b, 'gcx, 'tcx>>,
move_outs: FlowAtLocation<MovingOutStatements<'b, 'gcx, 'tcx>>,
Expand Down Expand Up @@ -87,7 +87,7 @@ impl<'b, 'gcx, 'tcx> fmt::Display for Flows<'b, 'gcx, 'tcx> {
s.push_str(", ");
};
saw_one = true;
let borrow_data = &self.borrows.operator().borrows()[borrow];
let borrow_data = &self.borrows.operator().borrows()[borrow.borrow_index()];
s.push_str(&format!("{}", borrow_data));
});
s.push_str("] ");
Expand All @@ -99,7 +99,7 @@ impl<'b, 'gcx, 'tcx> fmt::Display for Flows<'b, 'gcx, 'tcx> {
s.push_str(", ");
};
saw_one = true;
let borrow_data = &self.borrows.operator().borrows()[borrow];
let borrow_data = &self.borrows.operator().borrows()[borrow.borrow_index()];
s.push_str(&format!("{}", borrow_data));
});
s.push_str("] ");
Expand Down
Loading