Fix a large number of Body -> (ReadOnly)BodyCache type errors, add predecessor_locations fn to ReadOnlyBodyCache
This commit is contained in:
parent
2eed90a621
commit
ab98c595ea
15 changed files with 206 additions and 182 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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`"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
®ioncx,
|
||||
&closure_region_requirements,
|
||||
);
|
||||
|
||||
// We also have a `#[rustc_nll]` annotation that causes us to dump
|
||||
// information
|
||||
dump_annotation(infcx, &body, def_id, ®ioncx, &closure_region_requirements, errors_buffer);
|
||||
dump_annotation(infcx, body_cache, def_id, ®ioncx, &closure_region_requirements, errors_buffer);
|
||||
|
||||
(regioncx, polonius_output, closure_region_requirements)
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
®ion_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);
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue