1
Fork 0

Fix a large number of Body -> (ReadOnly)BodyCache type errors, add predecessor_locations fn to ReadOnlyBodyCache

This commit is contained in:
Paul Daniel Faria 2019-10-24 00:38:01 -04:00
parent 2eed90a621
commit ab98c595ea
15 changed files with 206 additions and 182 deletions

View file

@ -33,6 +33,41 @@ pub struct Cache {
// }
//}
macro_rules! get_predecessors {
(mut $self:ident, $block:expr, $body:expr) => {
$self.predecessors_for($block, $body)
};
($self:ident, $block:expr, $body:expr) => {
$self.unwrap_predecessors_for($block)
};
}
macro_rules! impl_predecessor_locations {
( ( $($pub:ident)? ) $name:ident $($mutability:ident)?) => {
$($pub)? fn $name<'a>(&'a $($mutability)? self, loc: Location, body: &'a Body<'a>) -> impl Iterator<Item = Location> + 'a {
let if_zero_locations = if loc.statement_index == 0 {
let predecessor_blocks = get_predecessors!($($mutability)? self, loc.block, body);
let num_predecessor_blocks = predecessor_blocks.len();
Some(
(0..num_predecessor_blocks)
.map(move |i| predecessor_blocks[i])
.map(move |bb| body.terminator_loc(bb)),
)
} else {
None
};
let if_not_zero_locations = if loc.statement_index == 0 {
None
} else {
Some(Location { block: loc.block, statement_index: loc.statement_index - 1 })
};
if_zero_locations.into_iter().flatten().chain(if_not_zero_locations)
}
};
}
impl Cache {
pub fn new() -> Self {
Self {
@ -80,27 +115,9 @@ impl Cache {
}
#[inline]
pub fn predecessor_locations<'a>(&'a mut self, loc: Location, body: &'a Body<'a>) -> impl Iterator<Item = Location> + 'a {
let if_zero_locations = if loc.statement_index == 0 {
let predecessor_blocks = self.predecessors_for(loc.block, body);
let num_predecessor_blocks = predecessor_blocks.len();
Some(
(0..num_predecessor_blocks)
.map(move |i| predecessor_blocks[i])
.map(move |bb| body.terminator_loc(bb)),
)
} else {
None
};
impl_predecessor_locations!((pub) predecessor_locations mut);
let if_not_zero_locations = if loc.statement_index == 0 {
None
} else {
Some(Location { block: loc.block, statement_index: loc.statement_index - 1 })
};
if_zero_locations.into_iter().flatten().chain(if_not_zero_locations)
}
impl_predecessor_locations!(() unwrap_predecessor_locations);
#[inline]
pub fn basic_blocks_mut<'a, 'tcx>(&mut self, body: &'a mut Body<'tcx>) -> &'a mut IndexVec<BasicBlock, BasicBlockData<'tcx>> {
@ -240,6 +257,11 @@ impl ReadOnlyBodyCache<'a, 'tcx> {
self.cache.unwrap_predecessors_for(bb)
}
#[inline]
pub fn predecessor_locations(&self, loc: Location) -> impl Iterator<Item = Location> + '_ {
self.cache.unwrap_predecessor_locations(loc, self.body)
}
#[inline]
pub fn body(&self) -> &'a Body<'tcx> {
self.body

View file

@ -5,7 +5,7 @@ use crate::dataflow::indexes::BorrowIndex;
use crate::dataflow::move_paths::MoveData;
use rustc::mir::traversal;
use rustc::mir::visit::{PlaceContext, Visitor, NonUseContext, MutatingUseContext};
use rustc::mir::{self, Location, Body, Local};
use rustc::mir::{self, Location, Body, Local, ReadOnlyBodyCache};
use rustc::ty::{RegionVid, TyCtxt};
use rustc::util::nodemap::{FxHashMap, FxHashSet};
use rustc_index::vec::IndexVec;
@ -90,7 +90,7 @@ crate enum LocalsStateAtExit {
impl LocalsStateAtExit {
fn build(
locals_are_invalidated_at_exit: bool,
body: &Body<'tcx>,
body_cache: &ReadOnlyBodyCache<'_, 'tcx>,
move_data: &MoveData<'tcx>
) -> Self {
struct HasStorageDead(BitSet<Local>);
@ -106,8 +106,8 @@ impl LocalsStateAtExit {
if locals_are_invalidated_at_exit {
LocalsStateAtExit::AllAreInvalidated
} else {
let mut has_storage_dead = HasStorageDead(BitSet::new_empty(body.local_decls.len()));
has_storage_dead.visit_body(body);
let mut has_storage_dead = HasStorageDead(BitSet::new_empty(body_cache.local_decls.len()));
has_storage_dead.visit_body(body_cache);
let mut has_storage_dead_or_moved = has_storage_dead.0;
for move_out in &move_data.moves {
if let Some(index) = move_data.base_local(move_out.path) {
@ -123,23 +123,23 @@ impl LocalsStateAtExit {
impl<'tcx> BorrowSet<'tcx> {
pub fn build(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
body_cache: &ReadOnlyBodyCache<'_, 'tcx>,
locals_are_invalidated_at_exit: bool,
move_data: &MoveData<'tcx>,
) -> Self {
let mut visitor = GatherBorrows {
tcx,
body,
body: body_cache.body(),
idx_vec: IndexVec::new(),
location_map: Default::default(),
activation_map: Default::default(),
local_map: Default::default(),
pending_activations: Default::default(),
locals_state_at_exit:
LocalsStateAtExit::build(locals_are_invalidated_at_exit, body, move_data),
LocalsStateAtExit::build(locals_are_invalidated_at_exit, body_cache, move_data),
};
for (block, block_data) in traversal::preorder(body) {
for (block, block_data) in traversal::preorder(body_cache) {
visitor.visit_basic_block_data(block, block_data);
}

View file

@ -206,7 +206,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
let ty =
Place::ty_from(used_place.base, used_place.projection, self.body, self.infcx.tcx)
Place::ty_from(used_place.base, used_place.projection, self.body_cache.body(), self.infcx.tcx)
.ty;
let needs_note = match ty.kind {
ty::Closure(id, _) => {
@ -222,7 +222,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let mpi = self.move_data.moves[move_out_indices[0]].path;
let place = &self.move_data.move_paths[mpi].place;
let ty = place.ty(self.body, self.infcx.tcx).ty;
let ty = place.ty(self.body_cache.body(), self.infcx.tcx).ty;
let opt_name =
self.describe_place_with_options(place.as_ref(), IncludingDowncast(true));
let note_msg = match opt_name {
@ -314,7 +314,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
None,
).add_explanation_to_diagnostic(
self.infcx.tcx,
self.body,
&self.body_cache,
&self.local_names,
&mut err,
"",
@ -356,7 +356,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
self.explain_why_borrow_contains_point(location, borrow, None)
.add_explanation_to_diagnostic(
self.infcx.tcx,
self.body,
&self.body_cache,
&self.local_names,
&mut err,
"",
@ -578,7 +578,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
explanation.add_explanation_to_diagnostic(
self.infcx.tcx,
self.body,
&self.body_cache,
&self.local_names,
&mut err,
first_borrow_desc,
@ -619,7 +619,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// Define a small closure that we can use to check if the type of a place
// is a union.
let union_ty = |place_base, place_projection| {
let ty = Place::ty_from(place_base, place_projection, self.body, self.infcx.tcx).ty;
let ty = Place::ty_from(place_base, place_projection, self.body_cache.body(), self.infcx.tcx).ty;
ty.ty_adt_def().filter(|adt| adt.is_union()).map(|_| ty)
};
let describe_place = |place| self.describe_place(place).unwrap_or_else(|| "_".to_owned());
@ -738,7 +738,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
assert!(root_place.projection.is_empty());
let proper_span = match root_place.base {
PlaceBase::Local(local) => self.body.local_decls[*local].source_info.span,
PlaceBase::Local(local) => self.body_cache.local_decls[*local].source_info.span,
_ => drop_span,
};
@ -965,7 +965,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} else {
explanation.add_explanation_to_diagnostic(
self.infcx.tcx,
self.body,
&self.body_cache,
&self.local_names,
&mut err,
"",
@ -991,7 +991,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);
explanation.add_explanation_to_diagnostic(
self.infcx.tcx, self.body, &self.local_names, &mut err, "", None);
self.infcx.tcx, &self.body_cache, &self.local_names, &mut err, "", None);
}
err
@ -1051,7 +1051,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
explanation.add_explanation_to_diagnostic(
self.infcx.tcx,
self.body,
&self.body_cache,
&self.local_names,
&mut err,
"",
@ -1138,7 +1138,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
explanation.add_explanation_to_diagnostic(
self.infcx.tcx,
self.body,
&self.body_cache,
&self.local_names,
&mut err,
"",
@ -1174,7 +1174,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
};
// FIXME use a better heuristic than Spans
let reference_desc = if return_span == self.body.source_info(borrow.reserve_location).span {
let reference_desc = if return_span == self.body_cache.source_info(borrow.reserve_location).span {
"reference to"
} else {
"value referencing"
@ -1182,7 +1182,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let (place_desc, note) = if let Some(place_desc) = opt_place_desc {
let local_kind = if let Some(local) = borrow.borrowed_place.as_local() {
match self.body.local_kind(local) {
match self.body_cache.local_kind(local) {
LocalKind::ReturnPointer
| LocalKind::Temp => bug!("temporary or return pointer with a name"),
LocalKind::Var => "local variable ",
@ -1215,7 +1215,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} else {
bug!("try_report_cannot_return_reference_to_local: not a local")
};
match self.body.local_kind(*local) {
match self.body_cache.local_kind(*local) {
LocalKind::ReturnPointer | LocalKind::Temp => (
"temporary value".to_string(),
"temporary value created here".to_string(),
@ -1372,10 +1372,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
fn get_moved_indexes(&mut self, location: Location, mpi: MovePathIndex) -> Vec<MoveSite> {
let body = self.body;
let mut stack = Vec::new();
stack.extend(body.predecessor_locations(location).map(|predecessor| {
stack.extend(self.body_cache.predecessor_locations(location).map(|predecessor| {
let is_back_edge = location.dominates(predecessor, &self.dominators);
(predecessor, is_back_edge)
}));
@ -1394,7 +1392,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
// check for moves
let stmt_kind = body[location.block]
let stmt_kind = self.body_cache[location.block]
.statements
.get(location.statement_index)
.map(|s| &s.kind);
@ -1449,7 +1447,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let mut any_match = false;
drop_flag_effects::for_location_inits(
self.infcx.tcx,
self.body,
&self.body_cache,
self.move_data,
location,
|m| {
@ -1462,7 +1460,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
continue 'dfs;
}
stack.extend(body.predecessor_locations(location).map(|predecessor| {
stack.extend(self.body_cache.predecessor_locations(location).map(|predecessor| {
let back_edge = location.dominates(predecessor, &self.dominators);
(predecessor, is_back_edge || back_edge)
}));
@ -1514,7 +1512,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
self.explain_why_borrow_contains_point(location, loan, None)
.add_explanation_to_diagnostic(
self.infcx.tcx,
self.body,
&self.body_cache,
&self.local_names,
&mut err,
"",
@ -1539,8 +1537,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
) {
let (from_arg, local_decl, local_name) = match err_place.as_local() {
Some(local) => (
self.body.local_kind(local) == LocalKind::Arg,
Some(&self.body.local_decls[local]),
self.body_cache.local_kind(local) == LocalKind::Arg,
Some(&self.body_cache.local_decls[local]),
self.local_names[local],
),
None => (false, None, None),
@ -1625,7 +1623,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
StorageDeadOrDrop::LocalStorageDead
| StorageDeadOrDrop::BoxedStorageDead => {
assert!(
Place::ty_from(&place.base, proj_base, self.body, tcx).ty.is_box(),
Place::ty_from(&place.base, proj_base, self.body_cache.body(), tcx).ty.is_box(),
"Drop of value behind a reference or raw pointer"
);
StorageDeadOrDrop::BoxedStorageDead
@ -1633,7 +1631,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
StorageDeadOrDrop::Destructor(_) => base_access,
},
ProjectionElem::Field(..) | ProjectionElem::Downcast(..) => {
let base_ty = Place::ty_from(&place.base, proj_base, self.body, tcx).ty;
let base_ty = Place::ty_from(&place.base, proj_base, self.body_cache.body(), tcx).ty;
match base_ty.kind {
ty::Adt(def, _) if def.has_dtor(tcx) => {
// Report the outermost adt with a destructor
@ -1721,7 +1719,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
location
);
if let Some(&Statement { kind: StatementKind::Assign(box(ref reservation, _)), ..})
= &self.body[location.block].statements.get(location.statement_index)
= &self.body_cache[location.block].statements.get(location.statement_index)
{
debug!(
"annotate_argument_and_return_for_borrow: reservation={:?}",
@ -1729,14 +1727,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);
// Check that the initial assignment of the reserve location is into a temporary.
let mut target = match reservation.as_local() {
Some(local) if self.body.local_kind(local) == LocalKind::Temp => local,
Some(local) if self.body_cache.local_kind(local) == LocalKind::Temp => local,
_ => return None,
};
// Next, look through the rest of the block, checking if we are assigning the
// `target` (that is, the place that contains our borrow) to anything.
let mut annotated_closure = None;
for stmt in &self.body[location.block].statements[location.statement_index + 1..] {
for stmt in &self.body_cache[location.block].statements[location.statement_index + 1..] {
debug!(
"annotate_argument_and_return_for_borrow: target={:?} stmt={:?}",
target, stmt
@ -1861,7 +1859,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
// Check the terminator if we didn't find anything in the statements.
let terminator = &self.body[location.block].terminator();
let terminator = &self.body_cache[location.block].terminator();
debug!(
"annotate_argument_and_return_for_borrow: target={:?} terminator={:?}",
target, terminator

View file

@ -39,7 +39,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
) {
debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place);
let mut target = place.local_or_deref_local();
for stmt in &self.body[location.block].statements[location.statement_index..] {
for stmt in &self.body_cache[location.block].statements[location.statement_index..] {
debug!("add_moved_or_invoked_closure_note: stmt={:?} target={:?}", stmt, target);
if let StatementKind::Assign(box(into, Rvalue::Use(from))) = &stmt.kind {
debug!("add_fnonce_closure_note: into={:?} from={:?}", into, from);
@ -53,7 +53,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
// Check if we are attempting to call a closure after it has been invoked.
let terminator = self.body[location.block].terminator();
let terminator = self.body_cache[location.block].terminator();
debug!("add_moved_or_invoked_closure_note: terminator={:?}", terminator);
if let TerminatorKind::Call {
func: Operand::Constant(box Constant {
@ -76,7 +76,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
};
debug!("add_moved_or_invoked_closure_note: closure={:?}", closure);
if let ty::Closure(did, _) = self.body.local_decls[closure].ty.kind {
if let ty::Closure(did, _) = self.body_cache.local_decls[closure].ty.kind {
let hir_id = self.infcx.tcx.hir().as_local_hir_id(did).unwrap();
if let Some((span, name)) = self.infcx.tcx.typeck_tables_of(did)
@ -99,7 +99,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// Check if we are just moving a closure after it has been invoked.
if let Some(target) = target {
if let ty::Closure(did, _) = self.body.local_decls[target].ty.kind {
if let ty::Closure(did, _) = self.body_cache.local_decls[target].ty.kind {
let hir_id = self.infcx.tcx.hir().as_local_hir_id(did).unwrap();
if let Some((span, name)) = self.infcx.tcx.typeck_tables_of(did)
@ -332,7 +332,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
/// Appends end-user visible description of the `local` place to `buf`. If `local` doesn't have
/// a name, or its name was generated by the compiler, then `Err` is returned
fn append_local_to_string(&self, local: Local, buf: &mut String) -> Result<(), ()> {
let decl = &self.body.local_decls[local];
let decl = &self.body_cache.local_decls[local];
match self.local_names[local] {
Some(name) if !decl.from_compiler_desugaring() => {
buf.push_str(&name.as_str());
@ -350,7 +350,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
base: PlaceBase::Local(local),
projection: [],
} => {
let local = &self.body.local_decls[*local];
let local = &self.body_cache.local_decls[*local];
self.describe_field_from_ty(&local.ty, field, None)
}
PlaceRef {
@ -370,7 +370,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
ProjectionElem::Downcast(_, variant_index) => {
let base_ty =
Place::ty_from(place.base, place.projection, self.body, self.infcx.tcx).ty;
Place::ty_from(place.base, place.projection, self.body_cache.body(), self.infcx.tcx).ty;
self.describe_field_from_ty(&base_ty, field, Some(*variant_index))
}
ProjectionElem::Field(_, field_type) => {
@ -481,7 +481,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
_ => continue,
};
let bbd = &self.body[loc.block];
let bbd = &self.body_cache[loc.block];
let is_terminator = bbd.statements.len() == loc.statement_index;
debug!(
"borrowed_content_source: loc={:?} is_terminator={:?}",
@ -499,7 +499,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
..
}) = bbd.terminator {
if let Some(source)
= BorrowedContentSource::from_call(func.ty(self.body, tcx), tcx)
= BorrowedContentSource::from_call(func.ty(self.body_cache.body(), tcx), tcx)
{
return source;
}
@ -512,7 +512,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// If we didn't find an overloaded deref or index, then assume it's a
// built in deref and check the type of the base.
let base_ty = Place::ty_from(deref_base.base, deref_base.projection, self.body, tcx).ty;
let base_ty = Place::ty_from(deref_base.base, deref_base.projection, self.body_cache.body(), tcx).ty;
if base_ty.is_unsafe_ptr() {
BorrowedContentSource::DerefRawPointer
} else if base_ty.is_mutable_ptr() {
@ -767,9 +767,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
) -> UseSpans {
use self::UseSpans::*;
let stmt = match self.body[location.block].statements.get(location.statement_index) {
let stmt = match self.body_cache[location.block].statements.get(location.statement_index) {
Some(stmt) => stmt,
None => return OtherUse(self.body.source_info(location).span),
None => return OtherUse(self.body_cache.source_info(location).span),
};
debug!("move_spans: moved_place={:?} location={:?} stmt={:?}", moved_place, location, stmt);
@ -807,7 +807,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
use self::UseSpans::*;
debug!("borrow_spans: use_span={:?} location={:?}", use_span, location);
let target = match self.body[location.block]
let target = match self.body_cache[location.block]
.statements
.get(location.statement_index)
{
@ -824,12 +824,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
_ => return OtherUse(use_span),
};
if self.body.local_kind(target) != LocalKind::Temp {
if self.body_cache.local_kind(target) != LocalKind::Temp {
// operands are always temporaries.
return OtherUse(use_span);
}
for stmt in &self.body[location.block].statements[location.statement_index + 1..] {
for stmt in &self.body_cache[location.block].statements[location.statement_index + 1..] {
if let StatementKind::Assign(
box(_, Rvalue::Aggregate(ref kind, ref places))
) = stmt.kind {
@ -901,7 +901,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
/// Helper to retrieve span(s) of given borrow from the current MIR
/// representation
pub(super) fn retrieve_borrow_spans(&self, borrow: &BorrowData<'_>) -> UseSpans {
let span = self.body.source_info(borrow.reserve_location).span;
let span = self.body_cache.source_info(borrow.reserve_location).span;
self.borrow_spans(span, borrow.reserve_location)
}
}

View file

@ -10,7 +10,7 @@ use rustc::lint::builtin::{MUTABLE_BORROW_RESERVATION_CONFLICT};
use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
use rustc::mir::{
ClearCrossCrate, Local, Location, Body, BodyCache, Mutability, Operand, Place, PlaceBase,
PlaceElem, PlaceRef, Static, StaticKind
PlaceElem, PlaceRef, ReadOnlyBodyCache, Static, StaticKind
};
use rustc::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
use rustc::mir::{Terminator, TerminatorKind};
@ -163,16 +163,19 @@ fn do_mir_borrowck<'a, 'tcx>(
// be modified (in place) to contain non-lexical lifetimes. It
// will have a lifetime tied to the inference context.
let mut body: Body<'tcx> = input_body.clone();
let mut promoted: IndexVec<Promoted, Body<'tcx>> = input_promoted.clone();
// TODO(pfaria) this very likely won't work because
let promoted: IndexVec<Promoted, Body<'tcx>> = input_promoted.clone();
let mut promoted_cache: IndexVec<Promoted, BodyCache<&mut Body<'tcx>>> = promoted.iter_mut().map(|body| BodyCache::new(body)).collect();
let mut body_cache = BodyCache::new(&mut body);
let free_regions =
nll::replace_regions_in_mir(infcx, def_id, param_env, &mut body, &mut promoted);
nll::replace_regions_in_mir(infcx, def_id, param_env, &mut body_cache, &mut promoted_cache);
let body_cache = BodyCache::new(&body).read_only(); // no further changes
let body_cache = &BodyCache::new(&body); // no further changes
let location_table = &LocationTable::new(body_cache);
let location_table = &LocationTable::new(&body_cache);
let mut errors_buffer = Vec::new();
let (move_data, move_errors): (MoveData<'tcx>, Option<Vec<(Place<'tcx>, MoveError<'tcx>)>>) =
match MoveData::gather_moves(body_cache, tcx) {
match MoveData::gather_moves(&body_cache, tcx) {
Ok(move_data) => (move_data, None),
Err((move_data, move_errors)) => (move_data, Some(move_errors)),
};
@ -185,24 +188,24 @@ fn do_mir_borrowck<'a, 'tcx>(
let dead_unwinds = BitSet::new_empty(body_cache.basic_blocks().len());
let mut flow_inits = FlowAtLocation::new(do_dataflow(
tcx,
body_cache,
&body_cache,
def_id,
&attributes,
&dead_unwinds,
MaybeInitializedPlaces::new(tcx, body_cache, &mdpe),
MaybeInitializedPlaces::new(tcx, &body_cache, &mdpe),
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
));
let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(id).is_fn_or_closure();
let borrow_set = Rc::new(BorrowSet::build(
tcx, body_cache, locals_are_invalidated_at_exit, &mdpe.move_data));
tcx, &body_cache, locals_are_invalidated_at_exit, &mdpe.move_data));
// If we are in non-lexical mode, compute the non-lexical lifetimes.
let (regioncx, polonius_output, opt_closure_req) = nll::compute_regions(
infcx,
def_id,
free_regions,
body_cache,
&body_cache,
&promoted,
&local_names,
&upvars,
@ -223,29 +226,29 @@ fn do_mir_borrowck<'a, 'tcx>(
let flow_borrows = FlowAtLocation::new(do_dataflow(
tcx,
body_cache,
&body_cache,
def_id,
&attributes,
&dead_unwinds,
Borrows::new(tcx, body_cache, param_env, regioncx.clone(), &borrow_set),
Borrows::new(tcx, &body_cache, param_env, regioncx.clone(), &borrow_set),
|rs, i| DebugFormatted::new(&rs.location(i)),
));
let flow_uninits = FlowAtLocation::new(do_dataflow(
tcx,
body_cache,
&body_cache,
def_id,
&attributes,
&dead_unwinds,
MaybeUninitializedPlaces::new(tcx, body_cache, &mdpe),
MaybeUninitializedPlaces::new(tcx, &body_cache, &mdpe),
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
));
let flow_ever_inits = FlowAtLocation::new(do_dataflow(
tcx,
body_cache,
&body_cache,
def_id,
&attributes,
&dead_unwinds,
EverInitializedPlaces::new(tcx, body_cache, &mdpe),
EverInitializedPlaces::new(tcx, &body_cache, &mdpe),
|bd, i| DebugFormatted::new(&bd.move_data().inits[i]),
));
@ -302,7 +305,7 @@ fn do_mir_borrowck<'a, 'tcx>(
mbcx.report_conflicting_borrow(location, (&place, span), bk, &borrow);
let scope = mbcx.body.source_info(location).scope;
let lint_root = match &mbcx.body.source_scopes[scope].local_data {
let lint_root = match &mbcx.body_cache.source_scopes[scope].local_data {
ClearCrossCrate::Set(data) => data.lint_root,
_ => id,
};
@ -324,21 +327,21 @@ fn do_mir_borrowck<'a, 'tcx>(
// would have a chance of erroneously adding non-user-defined mutable vars
// to the set.
let temporary_used_locals: FxHashSet<Local> = mbcx.used_mut.iter()
.filter(|&local| !mbcx.body.local_decls[*local].is_user_variable())
.filter(|&local| !mbcx.body_cache.local_decls[*local].is_user_variable())
.cloned()
.collect();
// For the remaining unused locals that are marked as mutable, we avoid linting any that
// were never initialized. These locals may have been removed as unreachable code; or will be
// linted as unused variables.
let unused_mut_locals = mbcx.body.mut_vars_iter()
let unused_mut_locals = mbcx.body_cache.mut_vars_iter()
.filter(|local| !mbcx.used_mut.contains(local))
.collect();
mbcx.gather_used_muts(temporary_used_locals, unused_mut_locals);
debug!("mbcx.used_mut: {:?}", mbcx.used_mut);
let used_mut = mbcx.used_mut;
for local in mbcx.body.mut_vars_and_args_iter().filter(|local| !used_mut.contains(local)) {
let local_decl = &mbcx.body.local_decls[local];
for local in mbcx.body_cache.mut_vars_and_args_iter().filter(|local| !used_mut.contains(local)) {
let local_decl = &mbcx.body_cache.local_decls[local];
let lint_root = match &mbcx.body.source_scopes[local_decl.source_info.scope].local_data {
ClearCrossCrate::Set(data) => data.lint_root,
_ => continue,
@ -399,7 +402,7 @@ fn do_mir_borrowck<'a, 'tcx>(
crate struct MirBorrowckCtxt<'cx, 'tcx> {
crate infcx: &'cx InferCtxt<'cx, 'tcx>,
body_cache: BodyCache<&'cx Body<'tcx>>,
body_cache: ReadOnlyBodyCache<'cx, 'tcx>,
mir_def_id: DefId,
param_env: ty::ParamEnv<'tcx>,
move_data: &'cx MoveData<'tcx>,
@ -490,7 +493,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx
type FlowState = Flows<'cx, 'tcx>;
fn body(&self) -> &'cx Body<'tcx> {
self.body_cache
&self.body_cache
}
fn visit_block_entry(&mut self, bb: BasicBlock, flow_state: &Self::FlowState) {
@ -640,7 +643,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx
let tcx = self.infcx.tcx;
// Compute the type with accurate region information.
let drop_place_ty = drop_place.ty(self.body_cache, self.infcx.tcx);
let drop_place_ty = drop_place.ty(self.body_cache.body(), self.infcx.tcx);
// Erase the regions.
let drop_place_ty = self.infcx.tcx.erase_regions(&drop_place_ty).ty;
@ -984,7 +987,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let mut error_reported = false;
let tcx = self.infcx.tcx;
let body = self.body_cache;
let body = self.body_cache.body();
let param_env = self.param_env;
let location_table = self.location_table.start_index(location);
let borrow_set = self.borrow_set.clone();
@ -1150,7 +1153,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// (e.g., `x = ...`) so long as it has never been initialized
// before (at this point in the flow).
if let Some(local) = place_span.0.as_local() {
if let Mutability::Not = self.body.local_decls[local].mutability {
if let Mutability::Not = self.body+cache.local_decls[local].mutability {
// check for reassignments to immutable local variables
self.check_if_reassignment_to_immutable_state(
location,
@ -1303,7 +1306,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
match *operand {
Operand::Move(ref place) | Operand::Copy(ref place) => {
match place.as_local() {
Some(local) if !self.body.local_decls[local].is_user_variable() => {
Some(local) if !self.body_cache.local_decls[local].is_user_variable() => {
if self.body.local_decls[local].ty.is_mutable_ptr() {
// The variable will be marked as mutable by the borrow.
return;
@ -1335,7 +1338,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
_ => bug!("temporary initialized in arguments"),
};
let bbd = &self.body[loc.block];
let bbd = &self.body_cache[loc.block];
let stmt = &bbd.statements[loc.statement_index];
debug!("temporary assigned in: stmt={:?}", stmt);
@ -1454,7 +1457,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if places_conflict::borrow_conflicts_with_place(
self.infcx.tcx,
self.param_env,
self.body,
&self.body_cache,
place,
borrow.kind,
root_place,
@ -1534,7 +1537,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if let Some(init_index) = self.is_local_ever_initialized(local, flow_state) {
// And, if so, report an error.
let init = &self.move_data.inits[init_index];
let span = init.span(&self.body);
let span = init.span(&self.body_cache);
self.report_illegal_reassignment(
location, place_span, span, place_span.0
);
@ -1745,7 +1748,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// assigning to `P.f` requires `P` itself
// be already initialized
let tcx = self.infcx.tcx;
let base_ty = Place::ty_from(&place.base, proj_base, self.body, tcx).ty;
let base_ty = Place::ty_from(&place.base, proj_base, self.body(), tcx).ty;
match base_ty.kind {
ty::Adt(def, _) if def.has_dtor(tcx) => {
self.check_if_path_or_subpath_is_moved(
@ -1852,12 +1855,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// of the union - we should error in that case.
let tcx = this.infcx.tcx;
if let ty::Adt(def, _) =
Place::ty_from(base.base, base.projection, this.body, tcx).ty.kind
Place::ty_from(base.base, base.projection, this.body(), tcx).ty.kind
{
if def.is_union() {
if this.move_data.path_map[mpi].iter().any(|moi| {
this.move_data.moves[*moi].source.is_predecessor_of(
location, this.body,
location, &this.body_cache,
)
}) {
return;
@ -2061,7 +2064,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
base: PlaceBase::Local(local),
projection: [],
} => {
let local = &self.body.local_decls[*local];
let local = &self.body_cache.local_decls[*local];
match local.mutability {
Mutability::Not => match is_local_mutation_allowed {
LocalMutationIsAllowed::Yes => Ok(RootPlace {
@ -2122,7 +2125,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
match elem {
ProjectionElem::Deref => {
let base_ty =
Place::ty_from(place.base, proj_base, self.body, self.infcx.tcx).ty;
Place::ty_from(place.base, proj_base, self.body(), self.infcx.tcx).ty;
// Check the kind of deref to decide
match base_ty.kind {
@ -2262,7 +2265,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
match place_projection {
[base @ .., ProjectionElem::Field(field, _ty)] => {
let tcx = self.infcx.tcx;
let base_ty = Place::ty_from(place_ref.base, base, self.body, tcx).ty;
let base_ty = Place::ty_from(place_ref.base, base, self.body(), tcx).ty;
if (base_ty.is_closure() || base_ty.is_generator()) &&
(!by_ref || self.upvars[field.index()].by_ref) {

View file

@ -90,13 +90,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
// flow could be used.
if let Some(StatementKind::Assign(
box(place, Rvalue::Use(Operand::Move(move_from)))
)) = self.body.basic_blocks()[location.block]
)) = self.body_cache.basic_blocks()[location.block]
.statements
.get(location.statement_index)
.map(|stmt| &stmt.kind)
{
if let Some(local) = place.as_local() {
let local_decl = &self.body.local_decls[local];
let local_decl = &self.body_cache.local_decls[local];
// opt_match_place is the
// match_span is the span of the expression being matched on
// match *x.y { ... } match_place is Some(*x.y)
@ -112,7 +112,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
pat_span: _,
},
))) = local_decl.local_info {
let stmt_source_info = self.body.source_info(location);
let stmt_source_info = self.body_cache.source_info(location);
self.append_binding_error(
grouped_errors,
kind,
@ -300,7 +300,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
// Inspect the type of the content behind the
// borrow to provide feedback about why this
// was a move rather than a copy.
let ty = deref_target_place.ty(self.body, self.infcx.tcx).ty;
let ty = deref_target_place.ty(self.body_cache.body(), self.infcx.tcx).ty;
let upvar_field = self.prefixes(move_place.as_ref(), PrefixSet::All)
.find_map(|p| self.is_upvar_field_projection(p));
@ -318,7 +318,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
base: PlaceBase::Local(local),
projection: [],
} = deref_base {
let decl = &self.body.local_decls[*local];
let decl = &self.body_cache.local_decls[*local];
if decl.is_ref_for_guard() {
let mut err = self.cannot_move_out_of(
span,
@ -411,7 +411,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
};
let move_ty = format!(
"{:?}",
move_place.ty(self.body, self.infcx.tcx).ty,
move_place.ty(self.body_cache.body(), self.infcx.tcx).ty,
);
if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
let is_option = move_ty.starts_with("std::option::Option");
@ -454,7 +454,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}
if binds_to.is_empty() {
let place_ty = move_from.ty(self.body, self.infcx.tcx).ty;
let place_ty = move_from.ty(self.body_cache.body(), self.infcx.tcx).ty;
let place_desc = match self.describe_place(move_from.as_ref()) {
Some(desc) => format!("`{}`", desc),
None => format!("value"),
@ -482,7 +482,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
// No binding. Nothing to suggest.
GroupedMoveError::OtherIllegalMove { ref original_path, use_spans, .. } => {
let span = use_spans.var_or_use();
let place_ty = original_path.ty(self.body, self.infcx.tcx).ty;
let place_ty = original_path.ty(self.body_cache.body(), self.infcx.tcx).ty;
let place_desc = match self.describe_place(original_path.as_ref()) {
Some(desc) => format!("`{}`", desc),
None => format!("value"),
@ -510,7 +510,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
) {
let mut suggestions: Vec<(Span, &str, String)> = Vec::new();
for local in binds_to {
let bind_to = &self.body.local_decls[*local];
let bind_to = &self.body_cache.local_decls[*local];
if let LocalInfo::User(
ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
pat_span,
@ -559,7 +559,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
binds_to: &[Local],
) {
for (j, local) in binds_to.into_iter().enumerate() {
let bind_to = &self.body.local_decls[*local];
let bind_to = &self.body_cache.local_decls[*local];
let binding_span = bind_to.source_info.span;
if j == 0 {

View file

@ -61,7 +61,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
projection: [proj_base @ .., ProjectionElem::Field(upvar_index, _)],
} => {
debug_assert!(is_closure_or_generator(
Place::ty_from(&the_place_err.base, proj_base, self.body, self.infcx.tcx).ty
Place::ty_from(&the_place_err.base, proj_base, self.body_cache.body(), self.infcx.tcx).ty
));
item_msg = format!("`{}`", access_place_desc.unwrap());
@ -106,12 +106,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
proj_base.is_empty() &&
!self.upvars.is_empty() {
item_msg = format!("`{}`", access_place_desc.unwrap());
debug_assert!(self.body.local_decls[Local::new(1)].ty.is_region_ptr());
debug_assert!(self.body_cache.local_decls[Local::new(1)].ty.is_region_ptr());
debug_assert!(is_closure_or_generator(
Place::ty_from(
the_place_err.base,
the_place_err.projection,
self.body,
self.body_cache.body(),
self.infcx.tcx
)
.ty
@ -225,7 +225,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if let Some((span, message)) = annotate_struct_field(
self.infcx.tcx,
Place::ty_from(base, proj_base, self.body, self.infcx.tcx).ty,
Place::ty_from(base, proj_base, self.body_cache.body(), self.infcx.tcx).ty,
field,
) {
err.span_suggestion(
@ -242,7 +242,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
base: PlaceBase::Local(local),
projection: [],
} if {
self.body.local_decls.get(*local).map(|local_decl| {
self.body_cache.local_decls.get(*local).map(|local_decl| {
if let LocalInfo::User(ClearCrossCrate::Set(
mir::BindingForm::ImplicitSelf(kind)
)) = local_decl.local_info {
@ -277,12 +277,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
PlaceRef {
base: PlaceBase::Local(local),
projection: [],
} if self.body.local_decls[*local].can_be_made_mutable() => {
} if self.body_cache.local_decls[*local].can_be_made_mutable() => {
// ... but it doesn't make sense to suggest it on
// variables that are `ref x`, `ref mut x`, `&self`,
// or `&mut self` (such variables are simply not
// mutable).
let local_decl = &self.body.local_decls[*local];
let local_decl = &self.body_cache.local_decls[*local];
assert_eq!(local_decl.mutability, Mutability::Not);
err.span_label(span, format!("cannot {ACT}", ACT = act));
@ -300,7 +300,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
projection: [proj_base @ .., ProjectionElem::Field(upvar_index, _)],
} => {
debug_assert!(is_closure_or_generator(
Place::ty_from(base, proj_base, self.body, self.infcx.tcx).ty
Place::ty_from(base, proj_base, self.body_cache.body(), self.infcx.tcx).ty
));
err.span_label(span, format!("cannot {ACT}", ACT = act));
@ -346,7 +346,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
PlaceRef {
base: PlaceBase::Local(local),
projection: [ProjectionElem::Deref],
} if self.body.local_decls[*local].is_ref_for_guard() => {
} if self.body_cache.local_decls[*local].is_ref_for_guard() => {
err.span_label(span, format!("cannot {ACT}", ACT = act));
err.note(
"variables bound in patterns are immutable until the end of the pattern guard",
@ -363,7 +363,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
projection: [ProjectionElem::Deref],
} if self.body.local_decls[*local].is_user_variable() =>
{
let local_decl = &self.body.local_decls[*local];
let local_decl = &self.body_cache.local_decls[*local];
let suggestion = match local_decl.local_info {
LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::ImplicitSelf(_))) => {
Some(suggest_ampmut_self(self.infcx.tcx, local_decl))
@ -377,7 +377,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
},
))) => Some(suggest_ampmut(
self.infcx.tcx,
self.body,
&self.body_cache,
*local,
local_decl,
opt_ty_info,
@ -451,7 +451,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
{
err.span_label(span, format!("cannot {ACT}", ACT = act));
err.span_help(
self.body.span,
self.body_cache.span,
"consider changing this to accept closures that implement `FnMut`"
);
}

View file

@ -237,7 +237,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);
let regioncx = &self.nonlexical_regioncx;
let body = self.body;
let body = self.body_cache.body();
let tcx = self.infcx.tcx;
let borrow_region_vid = borrow.region;
@ -297,9 +297,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if let Some(region) = regioncx.to_error_region_vid(borrow_region_vid) {
let (category, from_closure, span, region_name) =
self.nonlexical_regioncx.free_region_constraint_info(
self.body,
&self.local_names,
&self.upvars,
&self.body_cache,
&self.local_names,
&self.upvars,
self.mir_def_id,
self.infcx,
borrow_region_vid,
@ -365,7 +365,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
return outmost_back_edge;
}
let block = &self.body.basic_blocks()[location.block];
let block = &self.body_cache.basic_blocks()[location.block];
if location.statement_index < block.statements.len() {
let successor = location.successor_within_block();
@ -427,7 +427,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
if loop_head.dominates(from, &self.dominators) {
let block = &self.body.basic_blocks()[from.block];
let block = &self.body_cache.basic_blocks()[from.block];
if from.statement_index < block.statements.len() {
let successor = from.successor_within_block();
@ -475,7 +475,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
(LaterUseKind::ClosureCapture, var_span)
}
UseSpans::OtherUse(span) => {
let block = &self.body.basic_blocks()[location.block];
let block = &self.body_cache.basic_blocks()[location.block];
let kind = if let Some(&Statement {
kind: StatementKind::FakeRead(FakeReadCause::ForLet, _),
@ -498,7 +498,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
Operand::Copy(place) |
Operand::Move(place) => {
if let Some(l) = place.as_local() {
let local_decl = &self.body.local_decls[l];
let local_decl = &self.body_cache.local_decls[l];
if self.local_names[l].is_none() {
local_decl.source_info.span
} else {
@ -528,7 +528,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn was_captured_by_trait_object(&self, borrow: &BorrowData<'tcx>) -> bool {
// Start at the reserve location, find the place that we want to see cast to a trait object.
let location = borrow.reserve_location;
let block = &self.body[location.block];
let block = &self.body_cache[location.block];
let stmt = block.statements.get(location.statement_index);
debug!(
"was_captured_by_trait_object: location={:?} stmt={:?}",
@ -558,7 +558,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
);
while let Some(current_location) = queue.pop() {
debug!("was_captured_by_trait: target={:?}", target);
let block = &self.body[current_location.block];
let block = &self.body_cache[current_location.block];
// We need to check the current location to find out if it is a terminator.
let is_terminator = current_location.statement_index == block.statements.len();
if !is_terminator {

View file

@ -11,7 +11,7 @@ use crate::borrow_check::path_utils::*;
use crate::dataflow::indexes::BorrowIndex;
use rustc::ty::{self, TyCtxt};
use rustc::mir::visit::Visitor;
use rustc::mir::{BasicBlock, Location, Body, Place, Rvalue};
use rustc::mir::{BasicBlock, Location, Body, Place, ReadOnlyBodyCache, Rvalue};
use rustc::mir::{Statement, StatementKind};
use rustc::mir::TerminatorKind;
use rustc::mir::{Operand, BorrowKind};
@ -22,7 +22,7 @@ pub(super) fn generate_invalidates<'tcx>(
param_env: ty::ParamEnv<'tcx>,
all_facts: &mut Option<AllFacts>,
location_table: &LocationTable,
body: &Body<'tcx>,
body_cache: &ReadOnlyBodyCache<'_, 'tcx>,
borrow_set: &BorrowSet<'tcx>,
) {
if all_facts.is_none() {
@ -31,17 +31,17 @@ pub(super) fn generate_invalidates<'tcx>(
}
if let Some(all_facts) = all_facts {
let dominators = body.dominators();
let dominators = body_cache.dominators();
let mut ig = InvalidationGenerator {
all_facts,
borrow_set,
param_env,
tcx,
location_table,
body,
body: body_cache.body(),
dominators,
};
ig.visit_body(body);
ig.visit_body(&body_cache);
}
}

View file

@ -12,7 +12,8 @@ use crate::borrow_check::Upvar;
use rustc::hir::def_id::DefId;
use rustc::infer::InferCtxt;
use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements,
Local, Location, Body, LocalKind, BasicBlock, Promoted};
Local, Location, Body, BodyCache, LocalKind, BasicBlock,
Promoted, ReadOnlyBodyCache};
use rustc::ty::{self, RegionKind, RegionVid};
use rustc_index::vec::IndexVec;
use rustc_errors::Diagnostic;
@ -54,8 +55,8 @@ pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'tcx>(
infcx: &InferCtxt<'cx, 'tcx>,
def_id: DefId,
param_env: ty::ParamEnv<'tcx>,
body: &mut Body<'tcx>,
promoted: &mut IndexVec<Promoted, Body<'tcx>>,
body_cache: &mut BodyCache<&mut Body<'tcx>>,
promoted: &mut IndexVec<Promoted, BodyCache<&mut Body<'tcx>>>,
) -> UniversalRegions<'tcx> {
debug!("replace_regions_in_mir(def_id={:?})", def_id);
@ -63,10 +64,10 @@ pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'tcx>(
let universal_regions = UniversalRegions::new(infcx, def_id, param_env);
// Replace all remaining regions with fresh inference variables.
renumber::renumber_mir(infcx, body, promoted);
renumber::renumber_mir(infcx, body_cache, promoted);
let source = MirSource::item(def_id);
mir_util::dump_mir(infcx.tcx, None, "renumber", &0, source, body, |_, _| Ok(()));
mir_util::dump_mir(infcx.tcx, None, "renumber", &0, source, body_cache, |_, _| Ok(()));
universal_regions
}
@ -157,7 +158,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
infcx: &InferCtxt<'cx, 'tcx>,
def_id: DefId,
universal_regions: UniversalRegions<'tcx>,
body: &Body<'tcx>,
body_cache: &ReadOnlyBodyCache<'_, 'tcx>,
promoted: &IndexVec<Promoted, Body<'tcx>>,
local_names: &IndexVec<Local, Option<Symbol>>,
upvars: &[Upvar],
@ -180,7 +181,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
let universal_regions = Rc::new(universal_regions);
let elements = &Rc::new(RegionValueElements::new(body));
let elements = &Rc::new(RegionValueElements::new(body_cache));
// Run the MIR type-checker.
let MirTypeckResults {
@ -189,7 +190,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
} = type_check::type_check(
infcx,
param_env,
body,
body_cache,
promoted,
def_id,
&universal_regions,
@ -205,7 +206,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
all_facts
.universal_region
.extend(universal_regions.universal_regions());
populate_polonius_move_facts(all_facts, move_data, location_table, body);
populate_polonius_move_facts(all_facts, move_data, location_table, body_cache);
}
// Create the region inference context, taking ownership of the
@ -229,7 +230,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
&mut liveness_constraints,
&mut all_facts,
location_table,
&body,
body_cache,
borrow_set,
);
@ -238,7 +239,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
universal_regions,
placeholder_indices,
universal_region_relations,
body,
body_cache,
outlives_constraints,
member_constraints,
closure_bounds_mapping,
@ -253,7 +254,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
param_env,
&mut all_facts,
location_table,
&body,
body_cache,
borrow_set,
);
@ -283,21 +284,21 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
// Solve the region constraints.
let closure_region_requirements =
regioncx.solve(infcx, body, local_names, upvars, def_id, errors_buffer);
regioncx.solve(infcx, body_cache, local_names, upvars, def_id, errors_buffer);
// Dump MIR results into a file, if that is enabled. This let us
// write unit-tests, as well as helping with debugging.
dump_mir_results(
infcx,
MirSource::item(def_id),
&body,
body_cache,
&regioncx,
&closure_region_requirements,
);
// We also have a `#[rustc_nll]` annotation that causes us to dump
// information
dump_annotation(infcx, &body, def_id, &regioncx, &closure_region_requirements, errors_buffer);
dump_annotation(infcx, body_cache, def_id, &regioncx, &closure_region_requirements, errors_buffer);
(regioncx, polonius_output, closure_region_requirements)
}

View file

@ -1,4 +1,4 @@
use rustc::mir::{BasicBlock, Location, Body};
use rustc::mir::{BasicBlock, Location, Body, ReadOnlyBodyCache};
use rustc::ty::{self, RegionVid};
use rustc_index::bit_set::{HybridBitSet, SparseBitMatrix};
use rustc_data_structures::fx::FxHashMap;
@ -92,7 +92,7 @@ impl RegionValueElements {
/// Pushes all predecessors of `index` onto `stack`.
crate fn push_predecessors(
&self,
body: &Body<'_>,
body_cache: &ReadOnlyBodyCache<'_, '_>,
index: PointIndex,
stack: &mut Vec<PointIndex>,
) {
@ -104,9 +104,9 @@ impl RegionValueElements {
// If this is a basic block head, then the predecessors are
// the terminators of other basic blocks
stack.extend(
body.predecessors_for(block)
body_cache.predecessors_for(block)
.iter()
.map(|&pred_bb| body.terminator_loc(pred_bb))
.map(|&pred_bb| body_cache.terminator_loc(pred_bb))
.map(|pred_loc| self.point_from_location(pred_loc)),
);
} else {

View file

@ -1,6 +1,6 @@
use rustc::ty::subst::SubstsRef;
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::mir::{Body, Location, PlaceElem, Promoted};
use rustc::mir::{Body, BodyCache, Location, PlaceElem, Promoted};
use rustc::mir::visit::{MutVisitor, TyContext};
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
use rustc_index::vec::IndexVec;
@ -9,11 +9,11 @@ use rustc_index::vec::IndexVec;
/// inference variables, returning the number of variables created.
pub fn renumber_mir<'tcx>(
infcx: &InferCtxt<'_, 'tcx>,
body: &mut Body<'tcx>,
promoted: &mut IndexVec<Promoted, Body<'tcx>>,
body_cache: &mut BodyCache<&mut Body<'tcx>>,
promoted: &mut IndexVec<Promoted, BodyCache<&mut Body<'tcx>>>,
) {
debug!("renumber_mir()");
debug!("renumber_mir: body.arg_count={:?}", body.arg_count);
debug!("renumber_mir: body.arg_count={:?}", body_cache.arg_count);
let mut visitor = NLLVisitor { infcx };
@ -21,7 +21,7 @@ pub fn renumber_mir<'tcx>(
visitor.visit_body(body);
}
visitor.visit_body(body);
visitor.visit_body(body_cache);
}
/// Replaces all regions appearing in `value` with fresh inference

View file

@ -115,7 +115,7 @@ mod relate_tys;
pub(crate) fn type_check<'tcx>(
infcx: &InferCtxt<'_, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
body: &Body<'tcx>,
body_cache: &ReadOnlyBodyCache<'_, 'tcx>,
promoted: &IndexVec<Promoted, Body<'tcx>>,
mir_def_id: DefId,
universal_regions: &Rc<UniversalRegions<'tcx>>,
@ -161,15 +161,15 @@ pub(crate) fn type_check<'tcx>(
infcx,
mir_def_id,
param_env,
body,
body_cache,
promoted,
&region_bound_pairs,
implicit_region_bound,
&mut borrowck_context,
&universal_region_relations,
|mut cx| {
cx.equate_inputs_and_outputs(body, universal_regions, &normalized_inputs_and_output);
liveness::generate(&mut cx, body, elements, flow_inits, move_data, location_table);
cx.equate_inputs_and_outputs(body_cache, universal_regions, &normalized_inputs_and_output);
liveness::generate(&mut cx, body_cache, elements, flow_inits, move_data, location_table);
translate_outlives_facts(cx.borrowck_context);
},
@ -185,7 +185,7 @@ fn type_check_internal<'a, 'tcx, R>(
infcx: &'a InferCtxt<'a, 'tcx>,
mir_def_id: DefId,
param_env: ty::ParamEnv<'tcx>,
body: &'a Body<'tcx>,
body_cache: &ReadOnlyBodyCache<'a, 'tcx>,
promoted: &'a IndexVec<Promoted, Body<'tcx>>,
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
implicit_region_bound: ty::Region<'tcx>,
@ -195,7 +195,7 @@ fn type_check_internal<'a, 'tcx, R>(
) -> R where {
let mut checker = TypeChecker::new(
infcx,
body,
body_cache,
mir_def_id,
param_env,
region_bound_pairs,
@ -204,14 +204,14 @@ fn type_check_internal<'a, 'tcx, R>(
universal_region_relations,
);
let errors_reported = {
let mut verifier = TypeVerifier::new(&mut checker, body, promoted);
verifier.visit_body(body);
let mut verifier = TypeVerifier::new(&mut checker, body_cache, promoted);
verifier.visit_body(body_cache);
verifier.errors_reported
};
if !errors_reported {
// if verifier failed, don't do further checks to avoid ICEs
checker.typeck_mir(body);
checker.typeck_mir(body_cache);
}
extra(&mut checker)
@ -385,7 +385,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
}
}
fn visit_body(&mut self, body_cache: &BodyCache<&'_ Body<'tcx>>) {
fn visit_body(&mut self, body_cache: &ReadOnlyBodyCache<'_, 'tcx>) {
self.sanitize_type(&"return type", body_cache.return_ty());
for local_decl in &body_cache.local_decls {
self.sanitize_type(local_decl, local_decl.ty);

View file

@ -56,7 +56,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
Prefixes {
next: Some(place_ref),
kind,
body: self.body,
body: &self.body_cache,
tcx: self.infcx.tcx,
}
}

View file

@ -32,7 +32,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
never_initialized_mut_locals: &mut never_initialized_mut_locals,
mbcx: self,
};
visitor.visit_body(visitor.mbcx.body);
visitor.visit_body(&visitor.mbcx.body_cache);
}
// Take the union of the existed `used_mut` set with those variables we've found were