Changed usages of mir
in librustc::mir and librustc_mir to body
This commit is contained in:
parent
07c3967de9
commit
80ff07f30d
82 changed files with 1323 additions and 1319 deletions
|
@ -47,19 +47,19 @@ impl Cache {
|
|||
|
||||
pub fn predecessors(
|
||||
&self,
|
||||
mir: &Body<'_>
|
||||
body: &Body<'_>
|
||||
) -> MappedReadGuard<'_, IndexVec<BasicBlock, Vec<BasicBlock>>> {
|
||||
if self.predecessors.borrow().is_none() {
|
||||
*self.predecessors.borrow_mut() = Some(calculate_predecessors(mir));
|
||||
*self.predecessors.borrow_mut() = Some(calculate_predecessors(body));
|
||||
}
|
||||
|
||||
ReadGuard::map(self.predecessors.borrow(), |p| p.as_ref().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
fn calculate_predecessors(mir: &Body<'_>) -> IndexVec<BasicBlock, Vec<BasicBlock>> {
|
||||
let mut result = IndexVec::from_elem(vec![], mir.basic_blocks());
|
||||
for (bb, data) in mir.basic_blocks().iter_enumerated() {
|
||||
fn calculate_predecessors(body: &Body<'_>) -> IndexVec<BasicBlock, Vec<BasicBlock>> {
|
||||
let mut result = IndexVec::from_elem(vec![], body.basic_blocks());
|
||||
for (bb, data) in body.basic_blocks().iter_enumerated() {
|
||||
if let Some(ref term) = data.terminator {
|
||||
for &tgt in term.successors() {
|
||||
result[tgt].push(bb);
|
||||
|
|
|
@ -2916,7 +2916,7 @@ impl Location {
|
|||
}
|
||||
|
||||
/// Returns `true` if `other` is earlier in the control flow graph than `self`.
|
||||
pub fn is_predecessor_of<'tcx>(&self, other: Location, mir: &Body<'tcx>) -> bool {
|
||||
pub fn is_predecessor_of<'tcx>(&self, other: Location, body: &Body<'tcx>) -> bool {
|
||||
// If we are in the same block as the other location and are an earlier statement
|
||||
// then we are a predecessor of `other`.
|
||||
if self.block == other.block && self.statement_index < other.statement_index {
|
||||
|
@ -2924,13 +2924,13 @@ impl Location {
|
|||
}
|
||||
|
||||
// If we're in another block, then we want to check that block is a predecessor of `other`.
|
||||
let mut queue: Vec<BasicBlock> = mir.predecessors_for(other.block).clone();
|
||||
let mut queue: Vec<BasicBlock> = body.predecessors_for(other.block).clone();
|
||||
let mut visited = FxHashSet::default();
|
||||
|
||||
while let Some(block) = queue.pop() {
|
||||
// If we haven't visited this block before, then make sure we visit it's predecessors.
|
||||
if visited.insert(block) {
|
||||
queue.append(&mut mir.predecessors_for(block).clone());
|
||||
queue.append(&mut body.predecessors_for(block).clone());
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -21,27 +21,27 @@ use super::*;
|
|||
/// A preorder traversal of this graph is either `A B D C` or `A C D B`
|
||||
#[derive(Clone)]
|
||||
pub struct Preorder<'a, 'tcx: 'a> {
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
visited: BitSet<BasicBlock>,
|
||||
worklist: Vec<BasicBlock>,
|
||||
root_is_start_block: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Preorder<'a, 'tcx> {
|
||||
pub fn new(mir: &'a Body<'tcx>, root: BasicBlock) -> Preorder<'a, 'tcx> {
|
||||
pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> Preorder<'a, 'tcx> {
|
||||
let worklist = vec![root];
|
||||
|
||||
Preorder {
|
||||
mir,
|
||||
visited: BitSet::new_empty(mir.basic_blocks().len()),
|
||||
body,
|
||||
visited: BitSet::new_empty(body.basic_blocks().len()),
|
||||
worklist,
|
||||
root_is_start_block: root == START_BLOCK,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn preorder<'a, 'tcx>(mir: &'a Body<'tcx>) -> Preorder<'a, 'tcx> {
|
||||
Preorder::new(mir, START_BLOCK)
|
||||
pub fn preorder<'a, 'tcx>(body: &'a Body<'tcx>) -> Preorder<'a, 'tcx> {
|
||||
Preorder::new(body, START_BLOCK)
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
|
||||
|
@ -53,7 +53,7 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
|
|||
continue;
|
||||
}
|
||||
|
||||
let data = &self.mir[idx];
|
||||
let data = &self.body[idx];
|
||||
|
||||
if let Some(ref term) = data.terminator {
|
||||
self.worklist.extend(term.successors());
|
||||
|
@ -67,7 +67,7 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
|
|||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
// All the blocks, minus the number of blocks we've visited.
|
||||
let upper = self.mir.basic_blocks().len() - self.visited.count();
|
||||
let upper = self.body.basic_blocks().len() - self.visited.count();
|
||||
|
||||
let lower = if self.root_is_start_block {
|
||||
// We will visit all remaining blocks exactly once.
|
||||
|
@ -99,23 +99,23 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
|
|||
///
|
||||
/// A Postorder traversal of this graph is `D B C A` or `D C B A`
|
||||
pub struct Postorder<'a, 'tcx: 'a> {
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
visited: BitSet<BasicBlock>,
|
||||
visit_stack: Vec<(BasicBlock, Successors<'a>)>,
|
||||
root_is_start_block: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Postorder<'a, 'tcx> {
|
||||
pub fn new(mir: &'a Body<'tcx>, root: BasicBlock) -> Postorder<'a, 'tcx> {
|
||||
pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> Postorder<'a, 'tcx> {
|
||||
let mut po = Postorder {
|
||||
mir,
|
||||
visited: BitSet::new_empty(mir.basic_blocks().len()),
|
||||
body,
|
||||
visited: BitSet::new_empty(body.basic_blocks().len()),
|
||||
visit_stack: Vec::new(),
|
||||
root_is_start_block: root == START_BLOCK,
|
||||
};
|
||||
|
||||
|
||||
let data = &po.mir[root];
|
||||
let data = &po.body[root];
|
||||
|
||||
if let Some(ref term) = data.terminator {
|
||||
po.visited.insert(root);
|
||||
|
@ -186,7 +186,7 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
|
|||
};
|
||||
|
||||
if self.visited.insert(bb) {
|
||||
if let Some(term) = &self.mir[bb].terminator {
|
||||
if let Some(term) = &self.body[bb].terminator {
|
||||
self.visit_stack.push((bb, term.successors()));
|
||||
}
|
||||
}
|
||||
|
@ -194,8 +194,8 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn postorder<'a, 'tcx>(mir: &'a Body<'tcx>) -> Postorder<'a, 'tcx> {
|
||||
Postorder::new(mir, START_BLOCK)
|
||||
pub fn postorder<'a, 'tcx>(body: &'a Body<'tcx>) -> Postorder<'a, 'tcx> {
|
||||
Postorder::new(body, START_BLOCK)
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> {
|
||||
|
@ -207,12 +207,12 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> {
|
|||
self.traverse_successor();
|
||||
}
|
||||
|
||||
next.map(|(bb, _)| (bb, &self.mir[bb]))
|
||||
next.map(|(bb, _)| (bb, &self.body[bb]))
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
// All the blocks, minus the number of blocks we've visited.
|
||||
let upper = self.mir.basic_blocks().len() - self.visited.count();
|
||||
let upper = self.body.basic_blocks().len() - self.visited.count();
|
||||
|
||||
let lower = if self.root_is_start_block {
|
||||
// We will visit all remaining blocks exactly once.
|
||||
|
@ -252,19 +252,19 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> {
|
|||
/// to re-use the traversal
|
||||
#[derive(Clone)]
|
||||
pub struct ReversePostorder<'a, 'tcx: 'a> {
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
blocks: Vec<BasicBlock>,
|
||||
idx: usize
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ReversePostorder<'a, 'tcx> {
|
||||
pub fn new(mir: &'a Body<'tcx>, root: BasicBlock) -> ReversePostorder<'a, 'tcx> {
|
||||
let blocks : Vec<_> = Postorder::new(mir, root).map(|(bb, _)| bb).collect();
|
||||
pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> ReversePostorder<'a, 'tcx> {
|
||||
let blocks : Vec<_> = Postorder::new(body, root).map(|(bb, _)| bb).collect();
|
||||
|
||||
let len = blocks.len();
|
||||
|
||||
ReversePostorder {
|
||||
mir,
|
||||
body,
|
||||
blocks,
|
||||
idx: len
|
||||
}
|
||||
|
@ -276,8 +276,8 @@ impl<'a, 'tcx> ReversePostorder<'a, 'tcx> {
|
|||
}
|
||||
|
||||
|
||||
pub fn reverse_postorder<'a, 'tcx>(mir: &'a Body<'tcx>) -> ReversePostorder<'a, 'tcx> {
|
||||
ReversePostorder::new(mir, START_BLOCK)
|
||||
pub fn reverse_postorder<'a, 'tcx>(body: &'a Body<'tcx>) -> ReversePostorder<'a, 'tcx> {
|
||||
ReversePostorder::new(body, START_BLOCK)
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Iterator for ReversePostorder<'a, 'tcx> {
|
||||
|
@ -287,7 +287,7 @@ impl<'a, 'tcx> Iterator for ReversePostorder<'a, 'tcx> {
|
|||
if self.idx == 0 { return None; }
|
||||
self.idx -= 1;
|
||||
|
||||
self.blocks.get(self.idx).map(|&bb| (bb, &self.mir[bb]))
|
||||
self.blocks.get(self.idx).map(|&bb| (bb, &self.body[bb]))
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
|
|
|
@ -71,8 +71,8 @@ macro_rules! make_mir_visitor {
|
|||
// Override these, and call `self.super_xxx` to revert back to the
|
||||
// default behavior.
|
||||
|
||||
fn visit_body(&mut self, mir: & $($mutability)? Body<'tcx>) {
|
||||
self.super_body(mir);
|
||||
fn visit_body(&mut self, body: & $($mutability)? Body<'tcx>) {
|
||||
self.super_body(body);
|
||||
}
|
||||
|
||||
fn visit_basic_block_data(&mut self,
|
||||
|
@ -253,41 +253,41 @@ macro_rules! make_mir_visitor {
|
|||
// not meant to be overridden.
|
||||
|
||||
fn super_body(&mut self,
|
||||
mir: & $($mutability)? Body<'tcx>) {
|
||||
if let Some(yield_ty) = &$($mutability)? mir.yield_ty {
|
||||
body: & $($mutability)? Body<'tcx>) {
|
||||
if let Some(yield_ty) = &$($mutability)? body.yield_ty {
|
||||
self.visit_ty(yield_ty, TyContext::YieldTy(SourceInfo {
|
||||
span: mir.span,
|
||||
span: body.span,
|
||||
scope: OUTERMOST_SOURCE_SCOPE,
|
||||
}));
|
||||
}
|
||||
|
||||
// for best performance, we want to use an iterator rather
|
||||
// than a for-loop, to avoid calling `mir::Body::invalidate` for
|
||||
// than a for-loop, to avoid calling `body::Body::invalidate` for
|
||||
// each basic block.
|
||||
macro_rules! basic_blocks {
|
||||
(mut) => (mir.basic_blocks_mut().iter_enumerated_mut());
|
||||
() => (mir.basic_blocks().iter_enumerated());
|
||||
(mut) => (body.basic_blocks_mut().iter_enumerated_mut());
|
||||
() => (body.basic_blocks().iter_enumerated());
|
||||
};
|
||||
for (bb, data) in basic_blocks!($($mutability)?) {
|
||||
self.visit_basic_block_data(bb, data);
|
||||
}
|
||||
|
||||
for scope in &$($mutability)? mir.source_scopes {
|
||||
for scope in &$($mutability)? body.source_scopes {
|
||||
self.visit_source_scope_data(scope);
|
||||
}
|
||||
|
||||
self.visit_ty(&$($mutability)? mir.return_ty(), TyContext::ReturnTy(SourceInfo {
|
||||
span: mir.span,
|
||||
self.visit_ty(&$($mutability)? body.return_ty(), TyContext::ReturnTy(SourceInfo {
|
||||
span: body.span,
|
||||
scope: OUTERMOST_SOURCE_SCOPE,
|
||||
}));
|
||||
|
||||
for local in mir.local_decls.indices() {
|
||||
self.visit_local_decl(local, & $($mutability)? mir.local_decls[local]);
|
||||
for local in body.local_decls.indices() {
|
||||
self.visit_local_decl(local, & $($mutability)? body.local_decls[local]);
|
||||
}
|
||||
|
||||
macro_rules! type_annotations {
|
||||
(mut) => (mir.user_type_annotations.iter_enumerated_mut());
|
||||
() => (mir.user_type_annotations.iter_enumerated());
|
||||
(mut) => (body.user_type_annotations.iter_enumerated_mut());
|
||||
() => (body.user_type_annotations.iter_enumerated());
|
||||
};
|
||||
|
||||
for (index, annotation) in type_annotations!($($mutability)?) {
|
||||
|
@ -296,7 +296,7 @@ macro_rules! make_mir_visitor {
|
|||
);
|
||||
}
|
||||
|
||||
self.visit_span(&$($mutability)? mir.span);
|
||||
self.visit_span(&$($mutability)? body.span);
|
||||
}
|
||||
|
||||
fn super_basic_block_data(&mut self,
|
||||
|
@ -834,8 +834,8 @@ macro_rules! make_mir_visitor {
|
|||
|
||||
// Convenience methods
|
||||
|
||||
fn visit_location(&mut self, mir: & $($mutability)? Body<'tcx>, location: Location) {
|
||||
let basic_block = & $($mutability)? mir[location.block];
|
||||
fn visit_location(&mut self, body: & $($mutability)? Body<'tcx>, location: Location) {
|
||||
let basic_block = & $($mutability)? body[location.block];
|
||||
if basic_block.statements.len() == location.statement_index {
|
||||
if let Some(ref $($mutability)? terminator) = basic_block.terminator {
|
||||
self.visit_terminator(terminator, location)
|
||||
|
|
|
@ -90,7 +90,7 @@ crate enum LocalsStateAtExit {
|
|||
impl LocalsStateAtExit {
|
||||
fn build(
|
||||
locals_are_invalidated_at_exit: bool,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'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(mir.local_decls.len()));
|
||||
has_storage_dead.visit_body(mir);
|
||||
let mut has_storage_dead = HasStorageDead(BitSet::new_empty(body.local_decls.len()));
|
||||
has_storage_dead.visit_body(body);
|
||||
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,24 +123,24 @@ impl LocalsStateAtExit {
|
|||
impl<'tcx> BorrowSet<'tcx> {
|
||||
pub fn build(
|
||||
tcx: TyCtxt<'_, '_, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
locals_are_invalidated_at_exit: bool,
|
||||
move_data: &MoveData<'tcx>
|
||||
) -> Self {
|
||||
|
||||
let mut visitor = GatherBorrows {
|
||||
tcx,
|
||||
mir,
|
||||
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, mir, move_data),
|
||||
LocalsStateAtExit::build(locals_are_invalidated_at_exit, body, move_data),
|
||||
};
|
||||
|
||||
for (block, block_data) in traversal::preorder(mir) {
|
||||
for (block, block_data) in traversal::preorder(body) {
|
||||
visitor.visit_basic_block_data(block, block_data);
|
||||
}
|
||||
|
||||
|
@ -163,7 +163,7 @@ impl<'tcx> BorrowSet<'tcx> {
|
|||
|
||||
struct GatherBorrows<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
idx_vec: IndexVec<BorrowIndex, BorrowData<'tcx>>,
|
||||
location_map: FxHashMap<Location, BorrowIndex>,
|
||||
activation_map: FxHashMap<Location, Vec<BorrowIndex>>,
|
||||
|
@ -191,7 +191,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> {
|
|||
) {
|
||||
if let mir::Rvalue::Ref(region, kind, ref borrowed_place) = *rvalue {
|
||||
if borrowed_place.ignore_borrow(
|
||||
self.tcx, self.mir, &self.locals_state_at_exit) {
|
||||
self.tcx, self.body, &self.locals_state_at_exit) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -246,7 +246,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> {
|
|||
if let TwoPhaseActivation::ActivatedAt(other_location) =
|
||||
borrow_data.activation_location {
|
||||
span_bug!(
|
||||
self.mir.source_info(location).span,
|
||||
self.body.source_info(location).span,
|
||||
"found two uses for 2-phase borrow temporary {:?}: \
|
||||
{:?} and {:?}",
|
||||
temp,
|
||||
|
@ -320,7 +320,7 @@ impl<'a, 'gcx, 'tcx> GatherBorrows<'a, 'gcx, 'tcx> {
|
|||
temp
|
||||
} else {
|
||||
span_bug!(
|
||||
self.mir.source_info(start_location).span,
|
||||
self.body.source_info(start_location).span,
|
||||
"expected 2-phase borrow to assign to a local, not `{:?}`",
|
||||
assigned_place,
|
||||
);
|
||||
|
@ -339,7 +339,7 @@ impl<'a, 'gcx, 'tcx> GatherBorrows<'a, 'gcx, 'tcx> {
|
|||
// assignment.
|
||||
let old_value = self.pending_activations.insert(temp, borrow_index);
|
||||
if let Some(old_index) = old_value {
|
||||
span_bug!(self.mir.source_info(start_location).span,
|
||||
span_bug!(self.body.source_info(start_location).span,
|
||||
"found already pending activation for temp: {:?} \
|
||||
at borrow_index: {:?} with associated data {:?}",
|
||||
temp, old_index, self.idx_vec[old_index]);
|
||||
|
|
|
@ -202,7 +202,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
);
|
||||
}
|
||||
|
||||
let ty = used_place.ty(self.mir, self.infcx.tcx).ty;
|
||||
let ty = used_place.ty(self.body, self.infcx.tcx).ty;
|
||||
let needs_note = match ty.sty {
|
||||
ty::Closure(id, _) => {
|
||||
let tables = self.infcx.tcx.typeck_tables_of(id);
|
||||
|
@ -217,7 +217,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, '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.mir, self.infcx.tcx).ty;
|
||||
let ty = place.ty(self.body, self.infcx.tcx).ty;
|
||||
let opt_name = self.describe_place_with_options(place, IncludingDowncast(true));
|
||||
let note_msg = match opt_name {
|
||||
Some(ref name) => format!("`{}`", name),
|
||||
|
@ -235,7 +235,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
let span = if let Place::Base(PlaceBase::Local(local)) = place {
|
||||
let decl = &self.mir.local_decls[*local];
|
||||
let decl = &self.body.local_decls[*local];
|
||||
Some(decl.source_info.span)
|
||||
} else {
|
||||
None
|
||||
|
@ -305,7 +305,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
location,
|
||||
borrow,
|
||||
None,
|
||||
).add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", Some(borrow_span));
|
||||
).add_explanation_to_diagnostic(self.infcx.tcx, self.body, &mut err, "", Some(borrow_span));
|
||||
err.buffer(&mut self.errors_buffer);
|
||||
}
|
||||
|
||||
|
@ -342,7 +342,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
});
|
||||
|
||||
self.explain_why_borrow_contains_point(location, borrow, None)
|
||||
.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
|
||||
.add_explanation_to_diagnostic(self.infcx.tcx, self.body, &mut err, "", None);
|
||||
err
|
||||
}
|
||||
|
||||
|
@ -552,7 +552,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
|
||||
explanation.add_explanation_to_diagnostic(
|
||||
self.infcx.tcx,
|
||||
self.mir,
|
||||
self.body,
|
||||
&mut err,
|
||||
first_borrow_desc,
|
||||
None,
|
||||
|
@ -592,7 +592,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
// Define a small closure that we can use to check if the type of a place
|
||||
// is a union.
|
||||
let union_ty = |place: &Place<'tcx>| -> Option<Ty<'tcx>> {
|
||||
let ty = place.ty(self.mir, self.infcx.tcx).ty;
|
||||
let ty = place.ty(self.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());
|
||||
|
@ -687,7 +687,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
let borrow_span = borrow_spans.var_or_use();
|
||||
|
||||
let proper_span = match *root_place {
|
||||
Place::Base(PlaceBase::Local(local)) => self.mir.local_decls[local].source_info.span,
|
||||
Place::Base(PlaceBase::Local(local)) => self.body.local_decls[local].source_info.span,
|
||||
_ => drop_span,
|
||||
};
|
||||
|
||||
|
@ -876,7 +876,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
} else {
|
||||
explanation.add_explanation_to_diagnostic(
|
||||
self.infcx.tcx,
|
||||
self.mir,
|
||||
self.body,
|
||||
&mut err,
|
||||
"",
|
||||
None,
|
||||
|
@ -900,7 +900,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
format!("value captured here{}", within),
|
||||
);
|
||||
|
||||
explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
|
||||
explanation.add_explanation_to_diagnostic(
|
||||
self.infcx.tcx, self.body, &mut err, "", None);
|
||||
}
|
||||
|
||||
err
|
||||
|
@ -960,7 +961,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
_ => {}
|
||||
}
|
||||
|
||||
explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
|
||||
explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.body, &mut err, "", None);
|
||||
|
||||
err.buffer(&mut self.errors_buffer);
|
||||
}
|
||||
|
@ -1043,7 +1044,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
|
||||
explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.body, &mut err, "", None);
|
||||
|
||||
let within = if borrow_spans.for_generator() {
|
||||
" by generator"
|
||||
|
@ -1076,7 +1077,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
};
|
||||
|
||||
// FIXME use a better heuristic than Spans
|
||||
let reference_desc = if return_span == self.mir.source_info(borrow.reserve_location).span {
|
||||
let reference_desc = if return_span == self.body.source_info(borrow.reserve_location).span {
|
||||
"reference to"
|
||||
} else {
|
||||
"value referencing"
|
||||
|
@ -1085,7 +1086,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
let (place_desc, note) = if let Some(place_desc) = opt_place_desc {
|
||||
let local_kind = match borrow.borrowed_place {
|
||||
Place::Base(PlaceBase::Local(local)) => {
|
||||
match self.mir.local_kind(local) {
|
||||
match self.body.local_kind(local) {
|
||||
LocalKind::ReturnPointer
|
||||
| LocalKind::Temp => bug!("temporary or return pointer with a name"),
|
||||
LocalKind::Var => "local variable ",
|
||||
|
@ -1114,7 +1115,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
} else {
|
||||
bug!("try_report_cannot_return_reference_to_local: not a local")
|
||||
};
|
||||
match self.mir.local_kind(local) {
|
||||
match self.body.local_kind(local) {
|
||||
LocalKind::ReturnPointer | LocalKind::Temp => {
|
||||
(
|
||||
"temporary value".to_string(),
|
||||
|
@ -1251,10 +1252,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
fn get_moved_indexes(&mut self, location: Location, mpi: MovePathIndex) -> Vec<MoveSite> {
|
||||
let mir = self.mir;
|
||||
let body = self.body;
|
||||
|
||||
let mut stack = Vec::new();
|
||||
stack.extend(mir.predecessor_locations(location).map(|predecessor| {
|
||||
stack.extend(body.predecessor_locations(location).map(|predecessor| {
|
||||
let is_back_edge = location.dominates(predecessor, &self.dominators);
|
||||
(predecessor, is_back_edge)
|
||||
}));
|
||||
|
@ -1273,7 +1274,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
// check for moves
|
||||
let stmt_kind = mir[location.block]
|
||||
let stmt_kind = body[location.block]
|
||||
.statements
|
||||
.get(location.statement_index)
|
||||
.map(|s| &s.kind);
|
||||
|
@ -1328,7 +1329,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
let mut any_match = false;
|
||||
drop_flag_effects::for_location_inits(
|
||||
self.infcx.tcx,
|
||||
self.mir,
|
||||
self.body,
|
||||
self.move_data,
|
||||
location,
|
||||
|m| {
|
||||
|
@ -1341,7 +1342,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
continue 'dfs;
|
||||
}
|
||||
|
||||
stack.extend(mir.predecessor_locations(location).map(|predecessor| {
|
||||
stack.extend(body.predecessor_locations(location).map(|predecessor| {
|
||||
let back_edge = location.dominates(predecessor, &self.dominators);
|
||||
(predecessor, is_back_edge || back_edge)
|
||||
}));
|
||||
|
@ -1391,7 +1392,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
);
|
||||
|
||||
self.explain_why_borrow_contains_point(location, loan, None)
|
||||
.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
|
||||
.add_explanation_to_diagnostic(self.infcx.tcx, self.body, &mut err, "", None);
|
||||
|
||||
err.buffer(&mut self.errors_buffer);
|
||||
}
|
||||
|
@ -1410,10 +1411,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
err_place: &Place<'tcx>,
|
||||
) {
|
||||
let (from_arg, local_decl) = if let Place::Base(PlaceBase::Local(local)) = *err_place {
|
||||
if let LocalKind::Arg = self.mir.local_kind(local) {
|
||||
(true, Some(&self.mir.local_decls[local]))
|
||||
if let LocalKind::Arg = self.body.local_kind(local) {
|
||||
(true, Some(&self.body.local_decls[local]))
|
||||
} else {
|
||||
(false, Some(&self.mir.local_decls[local]))
|
||||
(false, Some(&self.body.local_decls[local]))
|
||||
}
|
||||
} else {
|
||||
(false, None)
|
||||
|
@ -1493,7 +1494,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
StorageDeadOrDrop::LocalStorageDead
|
||||
| StorageDeadOrDrop::BoxedStorageDead => {
|
||||
assert!(
|
||||
base.ty(self.mir, tcx).ty.is_box(),
|
||||
base.ty(self.body, tcx).ty.is_box(),
|
||||
"Drop of value behind a reference or raw pointer"
|
||||
);
|
||||
StorageDeadOrDrop::BoxedStorageDead
|
||||
|
@ -1501,7 +1502,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
StorageDeadOrDrop::Destructor(_) => base_access,
|
||||
},
|
||||
ProjectionElem::Field(..) | ProjectionElem::Downcast(..) => {
|
||||
let base_ty = base.ty(self.mir, tcx).ty;
|
||||
let base_ty = base.ty(self.body, tcx).ty;
|
||||
match base_ty.sty {
|
||||
ty::Adt(def, _) if def.has_dtor(tcx) => {
|
||||
// Report the outermost adt with a destructor
|
||||
|
@ -1560,7 +1561,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
location
|
||||
);
|
||||
if let Some(&Statement { kind: StatementKind::Assign(ref reservation, _), ..})
|
||||
= &self.mir[location.block].statements.get(location.statement_index)
|
||||
= &self.body[location.block].statements.get(location.statement_index)
|
||||
{
|
||||
debug!(
|
||||
"annotate_argument_and_return_for_borrow: reservation={:?}",
|
||||
|
@ -1569,14 +1570,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
// Check that the initial assignment of the reserve location is into a temporary.
|
||||
let mut target = *match reservation {
|
||||
Place::Base(PlaceBase::Local(local))
|
||||
if self.mir.local_kind(*local) == LocalKind::Temp => local,
|
||||
if self.body.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.mir[location.block].statements[location.statement_index + 1..] {
|
||||
for stmt in &self.body[location.block].statements[location.statement_index + 1..] {
|
||||
debug!(
|
||||
"annotate_argument_and_return_for_borrow: target={:?} stmt={:?}",
|
||||
target, stmt
|
||||
|
@ -1701,7 +1702,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
// Check the terminator if we didn't find anything in the statements.
|
||||
let terminator = &self.mir[location.block].terminator();
|
||||
let terminator = &self.body[location.block].terminator();
|
||||
debug!(
|
||||
"annotate_argument_and_return_for_borrow: target={:?} terminator={:?}",
|
||||
target, terminator
|
||||
|
|
|
@ -38,7 +38,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
) {
|
||||
debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place);
|
||||
let mut target = place.local_or_deref_local();
|
||||
for stmt in &self.mir[location.block].statements[location.statement_index..] {
|
||||
for stmt in &self.body[location.block].statements[location.statement_index..] {
|
||||
debug!("add_moved_or_invoked_closure_note: stmt={:?} target={:?}", stmt, target);
|
||||
if let StatementKind::Assign(into, box Rvalue::Use(from)) = &stmt.kind {
|
||||
debug!("add_fnonce_closure_note: into={:?} from={:?}", into, from);
|
||||
|
@ -52,7 +52,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
// Check if we are attempting to call a closure after it has been invoked.
|
||||
let terminator = self.mir[location.block].terminator();
|
||||
let terminator = self.body[location.block].terminator();
|
||||
debug!("add_moved_or_invoked_closure_note: terminator={:?}", terminator);
|
||||
if let TerminatorKind::Call {
|
||||
func: Operand::Constant(box Constant {
|
||||
|
@ -75,7 +75,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
};
|
||||
|
||||
debug!("add_moved_or_invoked_closure_note: closure={:?}", closure);
|
||||
if let ty::Closure(did, _) = self.mir.local_decls[closure].ty.sty {
|
||||
if let ty::Closure(did, _) = self.body.local_decls[closure].ty.sty {
|
||||
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)
|
||||
|
@ -98,7 +98,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, '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.mir.local_decls[target].ty.sty {
|
||||
if let ty::Closure(did, _) = self.body.local_decls[target].ty.sty {
|
||||
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)
|
||||
|
@ -180,7 +180,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
&including_downcast,
|
||||
)?;
|
||||
} else if let Place::Base(PlaceBase::Local(local)) = proj.base {
|
||||
if self.mir.local_decls[local].is_ref_for_guard() {
|
||||
if self.body.local_decls[local].is_ref_for_guard() {
|
||||
self.append_place_to_string(
|
||||
&proj.base,
|
||||
buf,
|
||||
|
@ -276,7 +276,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, '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_index: Local, buf: &mut String) -> Result<(), ()> {
|
||||
let local = &self.mir.local_decls[local_index];
|
||||
let local = &self.body.local_decls[local_index];
|
||||
match local.name {
|
||||
Some(name) if !local.from_compiler_desugaring() => {
|
||||
buf.push_str(name.as_str().get());
|
||||
|
@ -290,7 +290,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
fn describe_field(&self, base: &Place<'tcx>, field: Field) -> String {
|
||||
match *base {
|
||||
Place::Base(PlaceBase::Local(local)) => {
|
||||
let local = &self.mir.local_decls[local];
|
||||
let local = &self.body.local_decls[local];
|
||||
self.describe_field_from_ty(&local.ty, field, None)
|
||||
}
|
||||
Place::Base(PlaceBase::Static(ref static_)) =>
|
||||
|
@ -298,7 +298,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
Place::Projection(ref proj) => match proj.elem {
|
||||
ProjectionElem::Deref => self.describe_field(&proj.base, field),
|
||||
ProjectionElem::Downcast(_, variant_index) => {
|
||||
let base_ty = base.ty(self.mir, self.infcx.tcx).ty;
|
||||
let base_ty = base.ty(self.body, self.infcx.tcx).ty;
|
||||
self.describe_field_from_ty(&base_ty, field, Some(variant_index))
|
||||
}
|
||||
ProjectionElem::Field(_, field_type) => {
|
||||
|
@ -556,9 +556,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
) -> UseSpans {
|
||||
use self::UseSpans::*;
|
||||
|
||||
let stmt = match self.mir[location.block].statements.get(location.statement_index) {
|
||||
let stmt = match self.body[location.block].statements.get(location.statement_index) {
|
||||
Some(stmt) => stmt,
|
||||
None => return OtherUse(self.mir.source_info(location).span),
|
||||
None => return OtherUse(self.body.source_info(location).span),
|
||||
};
|
||||
|
||||
debug!("move_spans: moved_place={:?} location={:?} stmt={:?}", moved_place, location, stmt);
|
||||
|
@ -596,7 +596,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
use self::UseSpans::*;
|
||||
debug!("borrow_spans: use_span={:?} location={:?}", use_span, location);
|
||||
|
||||
let target = match self.mir[location.block]
|
||||
let target = match self.body[location.block]
|
||||
.statements
|
||||
.get(location.statement_index)
|
||||
{
|
||||
|
@ -607,12 +607,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
_ => return OtherUse(use_span),
|
||||
};
|
||||
|
||||
if self.mir.local_kind(target) != LocalKind::Temp {
|
||||
if self.body.local_kind(target) != LocalKind::Temp {
|
||||
// operands are always temporaries.
|
||||
return OtherUse(use_span);
|
||||
}
|
||||
|
||||
for stmt in &self.mir[location.block].statements[location.statement_index + 1..] {
|
||||
for stmt in &self.body[location.block].statements[location.statement_index + 1..] {
|
||||
if let StatementKind::Assign(
|
||||
_, box Rvalue::Aggregate(ref kind, ref places)
|
||||
) = stmt.kind {
|
||||
|
@ -682,7 +682,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, '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.mir.source_info(borrow.reserve_location).span;
|
||||
let span = self.body.source_info(borrow.reserve_location).span;
|
||||
self.borrow_spans(span, borrow.reserve_location)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,9 +30,9 @@ crate enum RichLocation {
|
|||
}
|
||||
|
||||
impl LocationTable {
|
||||
crate fn new(mir: &Body<'_>) -> Self {
|
||||
crate fn new(body: &Body<'_>) -> Self {
|
||||
let mut num_points = 0;
|
||||
let statements_before_block = mir.basic_blocks()
|
||||
let statements_before_block = body.basic_blocks()
|
||||
.iter()
|
||||
.map(|block_data| {
|
||||
let v = num_points;
|
||||
|
|
|
@ -88,12 +88,12 @@ pub fn provide(providers: &mut Providers<'_>) {
|
|||
}
|
||||
|
||||
fn mir_borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> BorrowCheckResult<'tcx> {
|
||||
let input_mir = tcx.mir_validated(def_id);
|
||||
let input_body = tcx.mir_validated(def_id);
|
||||
debug!("run query mir_borrowck: {}", tcx.def_path_str(def_id));
|
||||
|
||||
let opt_closure_req = tcx.infer_ctxt().enter(|infcx| {
|
||||
let input_mir: &Body<'_> = &input_mir.borrow();
|
||||
do_mir_borrowck(&infcx, input_mir, def_id)
|
||||
let input_body: &Body<'_> = &input_body.borrow();
|
||||
do_mir_borrowck(&infcx, input_body, def_id)
|
||||
});
|
||||
debug!("mir_borrowck done");
|
||||
|
||||
|
@ -102,7 +102,7 @@ fn mir_borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> BorrowC
|
|||
|
||||
fn do_mir_borrowck<'a, 'gcx, 'tcx>(
|
||||
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
input_mir: &Body<'gcx>,
|
||||
input_body: &Body<'gcx>,
|
||||
def_id: DefId,
|
||||
) -> BorrowCheckResult<'gcx> {
|
||||
debug!("do_mir_borrowck(def_id = {:?})", def_id);
|
||||
|
@ -149,14 +149,14 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
|
|||
// requires first making our own copy of the MIR. This copy will
|
||||
// be modified (in place) to contain non-lexical lifetimes. It
|
||||
// will have a lifetime tied to the inference context.
|
||||
let mut mir: Body<'tcx> = input_mir.clone();
|
||||
let free_regions = nll::replace_regions_in_mir(infcx, def_id, param_env, &mut mir);
|
||||
let mir = &mir; // no further changes
|
||||
let location_table = &LocationTable::new(mir);
|
||||
let mut body: Body<'tcx> = input_body.clone();
|
||||
let free_regions = nll::replace_regions_in_mir(infcx, def_id, param_env, &mut body);
|
||||
let body = &body; // no further changes
|
||||
let location_table = &LocationTable::new(body);
|
||||
|
||||
let mut errors_buffer = Vec::new();
|
||||
let (move_data, move_errors): (MoveData<'tcx>, Option<Vec<(Place<'tcx>, MoveError<'tcx>)>>) =
|
||||
match MoveData::gather_moves(mir, tcx) {
|
||||
match MoveData::gather_moves(body, tcx) {
|
||||
Ok(move_data) => (move_data, None),
|
||||
Err((move_data, move_errors)) => (move_data, Some(move_errors)),
|
||||
};
|
||||
|
@ -166,27 +166,27 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
|
|||
param_env: param_env,
|
||||
};
|
||||
|
||||
let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len());
|
||||
let dead_unwinds = BitSet::new_empty(body.basic_blocks().len());
|
||||
let mut flow_inits = FlowAtLocation::new(do_dataflow(
|
||||
tcx,
|
||||
mir,
|
||||
body,
|
||||
def_id,
|
||||
&attributes,
|
||||
&dead_unwinds,
|
||||
MaybeInitializedPlaces::new(tcx, mir, &mdpe),
|
||||
MaybeInitializedPlaces::new(tcx, body, &mdpe),
|
||||
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
|
||||
));
|
||||
|
||||
let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind_by_hir_id(id).is_fn_or_closure();
|
||||
let borrow_set = Rc::new(BorrowSet::build(
|
||||
tcx, mir, locals_are_invalidated_at_exit, &mdpe.move_data));
|
||||
tcx, body, 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,
|
||||
mir,
|
||||
body,
|
||||
&upvars,
|
||||
location_table,
|
||||
param_env,
|
||||
|
@ -205,29 +205,29 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
|
|||
|
||||
let flow_borrows = FlowAtLocation::new(do_dataflow(
|
||||
tcx,
|
||||
mir,
|
||||
body,
|
||||
def_id,
|
||||
&attributes,
|
||||
&dead_unwinds,
|
||||
Borrows::new(tcx, mir, regioncx.clone(), &borrow_set),
|
||||
Borrows::new(tcx, body, regioncx.clone(), &borrow_set),
|
||||
|rs, i| DebugFormatted::new(&rs.location(i)),
|
||||
));
|
||||
let flow_uninits = FlowAtLocation::new(do_dataflow(
|
||||
tcx,
|
||||
mir,
|
||||
body,
|
||||
def_id,
|
||||
&attributes,
|
||||
&dead_unwinds,
|
||||
MaybeUninitializedPlaces::new(tcx, mir, &mdpe),
|
||||
MaybeUninitializedPlaces::new(tcx, body, &mdpe),
|
||||
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
|
||||
));
|
||||
let flow_ever_inits = FlowAtLocation::new(do_dataflow(
|
||||
tcx,
|
||||
mir,
|
||||
body,
|
||||
def_id,
|
||||
&attributes,
|
||||
&dead_unwinds,
|
||||
EverInitializedPlaces::new(tcx, mir, &mdpe),
|
||||
EverInitializedPlaces::new(tcx, body, &mdpe),
|
||||
|bd, i| DebugFormatted::new(&bd.move_data().inits[i]),
|
||||
));
|
||||
|
||||
|
@ -239,11 +239,11 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
|
|||
_ => true,
|
||||
};
|
||||
|
||||
let dominators = mir.dominators();
|
||||
let dominators = body.dominators();
|
||||
|
||||
let mut mbcx = MirBorrowckCtxt {
|
||||
infcx,
|
||||
mir,
|
||||
body,
|
||||
mir_def_id: def_id,
|
||||
move_data: &mdpe.move_data,
|
||||
location_table,
|
||||
|
@ -281,8 +281,8 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
|
|||
let mut initial_diag =
|
||||
mbcx.report_conflicting_borrow(location, (&place, span), bk, &borrow);
|
||||
|
||||
let lint_root = if let ClearCrossCrate::Set(ref vsi) = mbcx.mir.source_scope_local_data {
|
||||
let scope = mbcx.mir.source_info(location).scope;
|
||||
let lint_root = if let ClearCrossCrate::Set(ref vsi) = mbcx.body.source_scope_local_data {
|
||||
let scope = mbcx.body.source_info(location).scope;
|
||||
vsi[scope].lint_root
|
||||
} else {
|
||||
id
|
||||
|
@ -305,22 +305,22 @@ fn do_mir_borrowck<'a, 'gcx, '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.mir.local_decls[*local].is_user_variable.is_none())
|
||||
.filter(|&local| mbcx.body.local_decls[*local].is_user_variable.is_none())
|
||||
.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.mir.mut_vars_iter()
|
||||
let unused_mut_locals = mbcx.body.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.mir.mut_vars_and_args_iter().filter(|local| !used_mut.contains(local)) {
|
||||
if let ClearCrossCrate::Set(ref vsi) = mbcx.mir.source_scope_local_data {
|
||||
let local_decl = &mbcx.mir.local_decls[local];
|
||||
for local in mbcx.body.mut_vars_and_args_iter().filter(|local| !used_mut.contains(local)) {
|
||||
if let ClearCrossCrate::Set(ref vsi) = mbcx.body.source_scope_local_data {
|
||||
let local_decl = &mbcx.body.local_decls[local];
|
||||
|
||||
// Skip implicit `self` argument for closures
|
||||
if local.index() == 1 && tcx.is_closure(mbcx.mir_def_id) {
|
||||
|
@ -425,7 +425,7 @@ fn downgrade_if_error(diag: &mut Diagnostic) {
|
|||
|
||||
pub struct MirBorrowckCtxt<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
|
||||
infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
|
||||
mir: &'cx Body<'tcx>,
|
||||
body: &'cx Body<'tcx>,
|
||||
mir_def_id: DefId,
|
||||
move_data: &'cx MoveData<'tcx>,
|
||||
|
||||
|
@ -511,8 +511,8 @@ pub struct MirBorrowckCtxt<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
|
|||
impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
||||
type FlowState = Flows<'cx, 'gcx, 'tcx>;
|
||||
|
||||
fn mir(&self) -> &'cx Body<'tcx> {
|
||||
self.mir
|
||||
fn body(&self) -> &'cx Body<'tcx> {
|
||||
self.body
|
||||
}
|
||||
|
||||
fn visit_block_entry(&mut self, bb: BasicBlock, flow_state: &Self::FlowState) {
|
||||
|
@ -662,7 +662,7 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
|
|||
let gcx = self.infcx.tcx.global_tcx();
|
||||
|
||||
// Compute the type with accurate region information.
|
||||
let drop_place_ty = drop_place.ty(self.mir, self.infcx.tcx);
|
||||
let drop_place_ty = drop_place.ty(self.body, self.infcx.tcx);
|
||||
|
||||
// Erase the regions.
|
||||
let drop_place_ty = self.infcx.tcx.erase_regions(&drop_place_ty).ty;
|
||||
|
@ -1005,13 +1005,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
|
||||
let mut error_reported = false;
|
||||
let tcx = self.infcx.tcx;
|
||||
let mir = self.mir;
|
||||
let body = self.body;
|
||||
let location_table = self.location_table.start_index(location);
|
||||
let borrow_set = self.borrow_set.clone();
|
||||
each_borrow_involving_path(
|
||||
self,
|
||||
tcx,
|
||||
mir,
|
||||
body,
|
||||
location,
|
||||
(sd, place_span.0),
|
||||
&borrow_set,
|
||||
|
@ -1169,7 +1169,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
// (e.g., `x = ...`) so long as it has never been initialized
|
||||
// before (at this point in the flow).
|
||||
if let &Place::Base(PlaceBase::Local(local)) = place_span.0 {
|
||||
if let Mutability::Not = self.mir.local_decls[local].mutability {
|
||||
if let Mutability::Not = self.body.local_decls[local].mutability {
|
||||
// check for reassignments to immutable local variables
|
||||
self.check_if_reassignment_to_immutable_state(
|
||||
location,
|
||||
|
@ -1326,9 +1326,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
match *operand {
|
||||
Operand::Move(Place::Base(PlaceBase::Local(local)))
|
||||
| Operand::Copy(Place::Base(PlaceBase::Local(local)))
|
||||
if self.mir.local_decls[local].is_user_variable.is_none() =>
|
||||
if self.body.local_decls[local].is_user_variable.is_none() =>
|
||||
{
|
||||
if self.mir.local_decls[local].ty.is_mutable_pointer() {
|
||||
if self.body.local_decls[local].ty.is_mutable_pointer() {
|
||||
// The variable will be marked as mutable by the borrow.
|
||||
return;
|
||||
}
|
||||
|
@ -1359,7 +1359,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
_ => bug!("temporary initialized in arguments"),
|
||||
};
|
||||
|
||||
let bbd = &self.mir[loc.block];
|
||||
let bbd = &self.body[loc.block];
|
||||
let stmt = &bbd.statements[loc.statement_index];
|
||||
debug!("temporary assigned in: stmt={:?}", stmt);
|
||||
|
||||
|
@ -1474,7 +1474,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
|
||||
if places_conflict::borrow_conflicts_with_place(
|
||||
self.infcx.tcx,
|
||||
self.mir,
|
||||
self.body,
|
||||
place,
|
||||
borrow.kind,
|
||||
root_place,
|
||||
|
@ -1561,7 +1561,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, '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.mir);
|
||||
let span = init.span(&self.body);
|
||||
self.report_illegal_reassignment(
|
||||
location, place_span, span, place_span.0
|
||||
);
|
||||
|
@ -1771,7 +1771,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
// assigning to `P.f` requires `P` itself
|
||||
// be already initialized
|
||||
let tcx = self.infcx.tcx;
|
||||
match base.ty(self.mir, tcx).ty.sty {
|
||||
match base.ty(self.body, tcx).ty.sty {
|
||||
ty::Adt(def, _) if def.has_dtor(tcx) => {
|
||||
self.check_if_path_or_subpath_is_moved(
|
||||
location, InitializationRequiringAction::Assignment,
|
||||
|
@ -1875,11 +1875,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
// no move out from an earlier location) then this is an attempt at initialization
|
||||
// of the union - we should error in that case.
|
||||
let tcx = this.infcx.tcx;
|
||||
if let ty::Adt(def, _) = base.ty(this.mir, tcx).ty.sty {
|
||||
if let ty::Adt(def, _) = base.ty(this.body, tcx).ty.sty {
|
||||
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.mir,
|
||||
location, this.body,
|
||||
)
|
||||
}) {
|
||||
return;
|
||||
|
@ -2097,7 +2097,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
) -> Result<RootPlace<'d, 'tcx>, &'d Place<'tcx>> {
|
||||
match *place {
|
||||
Place::Base(PlaceBase::Local(local)) => {
|
||||
let local = &self.mir.local_decls[local];
|
||||
let local = &self.body.local_decls[local];
|
||||
match local.mutability {
|
||||
Mutability::Not => match is_local_mutation_allowed {
|
||||
LocalMutationIsAllowed::Yes => Ok(RootPlace {
|
||||
|
@ -2136,7 +2136,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
Place::Projection(ref proj) => {
|
||||
match proj.elem {
|
||||
ProjectionElem::Deref => {
|
||||
let base_ty = proj.base.ty(self.mir, self.infcx.tcx).ty;
|
||||
let base_ty = proj.base.ty(self.body, self.infcx.tcx).ty;
|
||||
|
||||
// Check the kind of deref to decide
|
||||
match base_ty.sty {
|
||||
|
@ -2264,7 +2264,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
Place::Projection(ref proj) => match proj.elem {
|
||||
ProjectionElem::Field(field, _ty) => {
|
||||
let tcx = self.infcx.tcx;
|
||||
let base_ty = proj.base.ty(self.mir, tcx).ty;
|
||||
let base_ty = proj.base.ty(self.body, tcx).ty;
|
||||
|
||||
if (base_ty.is_closure() || base_ty.is_generator()) &&
|
||||
(!by_ref || self.upvars[field.index()].by_ref)
|
||||
|
|
|
@ -158,12 +158,12 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
if let Some(StatementKind::Assign(
|
||||
Place::Base(PlaceBase::Local(local)),
|
||||
box Rvalue::Use(Operand::Move(move_from)),
|
||||
)) = self.mir.basic_blocks()[location.block]
|
||||
)) = self.body.basic_blocks()[location.block]
|
||||
.statements
|
||||
.get(location.statement_index)
|
||||
.map(|stmt| &stmt.kind)
|
||||
{
|
||||
let local_decl = &self.mir.local_decls[*local];
|
||||
let local_decl = &self.body.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)
|
||||
|
@ -178,7 +178,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
pat_span: _,
|
||||
}))) = local_decl.is_user_variable
|
||||
{
|
||||
let stmt_source_info = self.mir.source_info(location);
|
||||
let stmt_source_info = self.body.source_info(location);
|
||||
self.append_binding_error(
|
||||
grouped_errors,
|
||||
kind,
|
||||
|
@ -371,7 +371,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, '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.mir, self.infcx.tcx).ty;
|
||||
let ty = deref_target_place.ty(self.body, self.infcx.tcx).ty;
|
||||
let upvar_field = self.prefixes(&move_place, PrefixSet::All)
|
||||
.find_map(|p| self.is_upvar_field_projection(p));
|
||||
|
||||
|
@ -381,7 +381,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
};
|
||||
|
||||
if let Place::Base(PlaceBase::Local(local)) = *deref_base {
|
||||
let decl = &self.mir.local_decls[local];
|
||||
let decl = &self.body.local_decls[local];
|
||||
if decl.is_ref_for_guard() {
|
||||
let mut err = self.infcx.tcx.cannot_move_out_of(
|
||||
span,
|
||||
|
@ -470,7 +470,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
};
|
||||
let move_ty = format!(
|
||||
"{:?}",
|
||||
move_place.ty(self.mir, self.infcx.tcx).ty,
|
||||
move_place.ty(self.body, self.infcx.tcx).ty,
|
||||
);
|
||||
let snippet = self.infcx.tcx.sess.source_map().span_to_snippet(span).unwrap();
|
||||
let is_option = move_ty.starts_with("std::option::Option");
|
||||
|
@ -511,7 +511,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
);
|
||||
|
||||
if binds_to.is_empty() {
|
||||
let place_ty = move_from.ty(self.mir, self.infcx.tcx).ty;
|
||||
let place_ty = move_from.ty(self.body, self.infcx.tcx).ty;
|
||||
let place_desc = match self.describe_place(&move_from) {
|
||||
Some(desc) => format!("`{}`", desc),
|
||||
None => format!("value"),
|
||||
|
@ -539,7 +539,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, '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.mir, self.infcx.tcx).ty;
|
||||
let place_ty = original_path.ty(self.body, self.infcx.tcx).ty;
|
||||
let place_desc = match self.describe_place(original_path) {
|
||||
Some(desc) => format!("`{}`", desc),
|
||||
None => format!("value"),
|
||||
|
@ -567,7 +567,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
) {
|
||||
let mut suggestions: Vec<(Span, &str, String)> = Vec::new();
|
||||
for local in binds_to {
|
||||
let bind_to = &self.mir.local_decls[*local];
|
||||
let bind_to = &self.body.local_decls[*local];
|
||||
if let Some(
|
||||
ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
|
||||
pat_span,
|
||||
|
@ -617,7 +617,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
) {
|
||||
let mut noncopy_var_spans = Vec::new();
|
||||
for (j, local) in binds_to.into_iter().enumerate() {
|
||||
let bind_to = &self.mir.local_decls[*local];
|
||||
let bind_to = &self.body.local_decls[*local];
|
||||
let binding_span = bind_to.source_info.span;
|
||||
|
||||
if j == 0 {
|
||||
|
@ -667,7 +667,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
_ => continue,
|
||||
};
|
||||
|
||||
let bbd = &self.mir[loc.block];
|
||||
let bbd = &self.body[loc.block];
|
||||
let is_terminator = bbd.statements.len() == loc.statement_index;
|
||||
debug!(
|
||||
"borrowed_content_source: loc={:?} is_terminator={:?}",
|
||||
|
@ -685,7 +685,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
..
|
||||
}) = bbd.terminator {
|
||||
if let Some(source)
|
||||
= BorrowedContentSource::from_call(func.ty(self.mir, tcx), tcx)
|
||||
= BorrowedContentSource::from_call(func.ty(self.body, tcx), tcx)
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
@ -698,7 +698,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, '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 = deref_base.ty(self.mir, tcx).ty;
|
||||
let base_ty = deref_base.ty(self.body, tcx).ty;
|
||||
if base_ty.is_unsafe_ptr() {
|
||||
BorrowedContentSource::DerefRawPointer
|
||||
} else if base_ty.is_mutable_pointer() {
|
||||
|
|
|
@ -52,7 +52,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
if let Place::Base(PlaceBase::Local(_)) = access_place {
|
||||
reason = ", as it is not declared as mutable".to_string();
|
||||
} else {
|
||||
let name = self.mir.local_decls[*local]
|
||||
let name = self.body.local_decls[*local]
|
||||
.name
|
||||
.expect("immutable unnamed local");
|
||||
reason = format!(", as `{}` is not declared as mutable", name);
|
||||
|
@ -64,7 +64,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
elem: ProjectionElem::Field(upvar_index, _),
|
||||
}) => {
|
||||
debug_assert!(is_closure_or_generator(
|
||||
base.ty(self.mir, self.infcx.tcx).ty
|
||||
base.ty(self.body, self.infcx.tcx).ty
|
||||
));
|
||||
|
||||
item_msg = format!("`{}`", access_place_desc.unwrap());
|
||||
|
@ -83,9 +83,9 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
if *base == Place::Base(PlaceBase::Local(Local::new(1))) &&
|
||||
!self.upvars.is_empty() {
|
||||
item_msg = format!("`{}`", access_place_desc.unwrap());
|
||||
debug_assert!(self.mir.local_decls[Local::new(1)].ty.is_region_ptr());
|
||||
debug_assert!(self.body.local_decls[Local::new(1)].ty.is_region_ptr());
|
||||
debug_assert!(is_closure_or_generator(
|
||||
the_place_err.ty(self.mir, self.infcx.tcx).ty
|
||||
the_place_err.ty(self.body, self.infcx.tcx).ty
|
||||
));
|
||||
|
||||
reason = if self.is_upvar_field_projection(access_place).is_some() {
|
||||
|
@ -95,7 +95,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
} else if {
|
||||
if let Place::Base(PlaceBase::Local(local)) = *base {
|
||||
self.mir.local_decls[local].is_ref_for_guard()
|
||||
self.body.local_decls[local].is_ref_for_guard()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
reason = ", as it is immutable for the pattern guard".to_string();
|
||||
} else {
|
||||
let pointer_type =
|
||||
if base.ty(self.mir, self.infcx.tcx).ty.is_region_ptr() {
|
||||
if base.ty(self.body, self.infcx.tcx).ty.is_region_ptr() {
|
||||
"`&` reference"
|
||||
} else {
|
||||
"`*const` pointer"
|
||||
|
@ -226,7 +226,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
if let Some((span, message)) = annotate_struct_field(
|
||||
self.infcx.tcx,
|
||||
base.ty(self.mir, self.infcx.tcx).ty,
|
||||
base.ty(self.body, self.infcx.tcx).ty,
|
||||
field,
|
||||
) {
|
||||
err.span_suggestion(
|
||||
|
@ -241,7 +241,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
// Suggest removing a `&mut` from the use of a mutable reference.
|
||||
Place::Base(PlaceBase::Local(local))
|
||||
if {
|
||||
self.mir.local_decls.get(*local).map(|local_decl| {
|
||||
self.body.local_decls.get(*local).map(|local_decl| {
|
||||
if let ClearCrossCrate::Set(
|
||||
mir::BindingForm::ImplicitSelf(kind)
|
||||
) = local_decl.is_user_variable.as_ref().unwrap() {
|
||||
|
@ -275,12 +275,12 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
// We want to suggest users use `let mut` for local (user
|
||||
// variable) mutations...
|
||||
Place::Base(PlaceBase::Local(local))
|
||||
if self.mir.local_decls[*local].can_be_made_mutable() => {
|
||||
if self.body.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.mir.local_decls[*local];
|
||||
let local_decl = &self.body.local_decls[*local];
|
||||
assert_eq!(local_decl.mutability, Mutability::Not);
|
||||
|
||||
err.span_label(span, format!("cannot {ACT}", ACT = act));
|
||||
|
@ -298,7 +298,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
elem: ProjectionElem::Field(upvar_index, _),
|
||||
}) => {
|
||||
debug_assert!(is_closure_or_generator(
|
||||
base.ty(self.mir, self.infcx.tcx).ty
|
||||
base.ty(self.body, self.infcx.tcx).ty
|
||||
));
|
||||
|
||||
err.span_label(span, format!("cannot {ACT}", ACT = act));
|
||||
|
@ -344,7 +344,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
elem: ProjectionElem::Deref,
|
||||
}) if {
|
||||
if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard)) =
|
||||
self.mir.local_decls[*local].is_user_variable
|
||||
self.body.local_decls[*local].is_user_variable
|
||||
{
|
||||
true
|
||||
} else {
|
||||
|
@ -366,9 +366,9 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
Place::Projection(box Projection {
|
||||
base: Place::Base(PlaceBase::Local(local)),
|
||||
elem: ProjectionElem::Deref,
|
||||
}) if self.mir.local_decls[*local].is_user_variable.is_some() =>
|
||||
}) if self.body.local_decls[*local].is_user_variable.is_some() =>
|
||||
{
|
||||
let local_decl = &self.mir.local_decls[*local];
|
||||
let local_decl = &self.body.local_decls[*local];
|
||||
let suggestion = match local_decl.is_user_variable.as_ref().unwrap() {
|
||||
ClearCrossCrate::Set(mir::BindingForm::ImplicitSelf(_)) => {
|
||||
Some(suggest_ampmut_self(self.infcx.tcx, local_decl))
|
||||
|
@ -380,7 +380,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
..
|
||||
})) => Some(suggest_ampmut(
|
||||
self.infcx.tcx,
|
||||
self.mir,
|
||||
self.body,
|
||||
*local,
|
||||
local_decl,
|
||||
*opt_ty_info,
|
||||
|
@ -451,7 +451,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
{
|
||||
err.span_label(span, format!("cannot {ACT}", ACT = act));
|
||||
err.span_help(
|
||||
self.mir.span,
|
||||
self.body.span,
|
||||
"consider changing this to accept closures that implement `FnMut`"
|
||||
);
|
||||
}
|
||||
|
@ -482,7 +482,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||
},
|
||||
..
|
||||
}
|
||||
) = &self.mir.basic_blocks()[location.block].terminator {
|
||||
) = &self.body.basic_blocks()[location.block].terminator {
|
||||
let index_trait = self.infcx.tcx.lang_items().index_trait();
|
||||
if self.infcx.tcx.parent(id) == index_trait {
|
||||
let mut found = false;
|
||||
|
@ -557,14 +557,14 @@ fn suggest_ampmut_self<'cx, 'gcx, 'tcx>(
|
|||
// by trying (3.), then (2.) and finally falling back on (1.).
|
||||
fn suggest_ampmut<'cx, 'gcx, 'tcx>(
|
||||
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
local: Local,
|
||||
local_decl: &mir::LocalDecl<'tcx>,
|
||||
opt_ty_info: Option<Span>,
|
||||
) -> (Span, String) {
|
||||
let locations = mir.find_assignments(local);
|
||||
let locations = body.find_assignments(local);
|
||||
if !locations.is_empty() {
|
||||
let assignment_rhs_span = mir.source_info(locations[0]).span;
|
||||
let assignment_rhs_span = body.source_info(locations[0]).span;
|
||||
if let Ok(src) = tcx.sess.source_map().span_to_snippet(assignment_rhs_span) {
|
||||
if let (true, Some(ws_pos)) = (
|
||||
src.starts_with("&'"),
|
||||
|
|
|
@ -18,7 +18,7 @@ pub(super) fn generate_constraints<'cx, 'gcx, 'tcx>(
|
|||
liveness_constraints: &mut LivenessValues<RegionVid>,
|
||||
all_facts: &mut Option<AllFacts>,
|
||||
location_table: &LocationTable,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
borrow_set: &BorrowSet<'tcx>,
|
||||
) {
|
||||
let mut cg = ConstraintGeneration {
|
||||
|
@ -29,7 +29,7 @@ pub(super) fn generate_constraints<'cx, 'gcx, 'tcx>(
|
|||
all_facts,
|
||||
};
|
||||
|
||||
for (bb, data) in mir.basic_blocks().iter_enumerated() {
|
||||
for (bb, data) in body.basic_blocks().iter_enumerated() {
|
||||
cg.visit_basic_block_data(bb, data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,14 +10,14 @@ use rustc::ty::{RegionVid, TyCtxt};
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
|
||||
crate fn find<'tcx>(
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
regioncx: &Rc<RegionInferenceContext<'tcx>>,
|
||||
tcx: TyCtxt<'_, '_, 'tcx>,
|
||||
region_vid: RegionVid,
|
||||
start_point: Location,
|
||||
) -> Option<Cause> {
|
||||
let mut uf = UseFinder {
|
||||
mir,
|
||||
body,
|
||||
regioncx,
|
||||
tcx,
|
||||
region_vid,
|
||||
|
@ -28,7 +28,7 @@ crate fn find<'tcx>(
|
|||
}
|
||||
|
||||
struct UseFinder<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
|
||||
mir: &'cx Body<'tcx>,
|
||||
body: &'cx Body<'tcx>,
|
||||
regioncx: &'cx Rc<RegionInferenceContext<'tcx>>,
|
||||
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||
region_vid: RegionVid,
|
||||
|
@ -50,7 +50,7 @@ impl<'cx, 'gcx, 'tcx> UseFinder<'cx, 'gcx, 'tcx> {
|
|||
continue;
|
||||
}
|
||||
|
||||
let block_data = &self.mir[p.block];
|
||||
let block_data = &self.body[p.block];
|
||||
|
||||
match self.def_use(p, block_data.visitable(p.statement_index)) {
|
||||
Some(DefUseResult::Def) => {}
|
||||
|
@ -87,7 +87,7 @@ impl<'cx, 'gcx, 'tcx> UseFinder<'cx, 'gcx, 'tcx> {
|
|||
|
||||
fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> Option<DefUseResult> {
|
||||
let mut visitor = DefUseVisitor {
|
||||
mir: self.mir,
|
||||
body: self.body,
|
||||
tcx: self.tcx,
|
||||
region_vid: self.region_vid,
|
||||
def_use_result: None,
|
||||
|
@ -100,7 +100,7 @@ impl<'cx, 'gcx, 'tcx> UseFinder<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
struct DefUseVisitor<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
|
||||
mir: &'cx Body<'tcx>,
|
||||
body: &'cx Body<'tcx>,
|
||||
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||
region_vid: RegionVid,
|
||||
def_use_result: Option<DefUseResult>,
|
||||
|
@ -114,7 +114,7 @@ enum DefUseResult {
|
|||
|
||||
impl<'cx, 'gcx, 'tcx> Visitor<'tcx> for DefUseVisitor<'cx, 'gcx, 'tcx> {
|
||||
fn visit_local(&mut self, &local: &Local, context: PlaceContext, _: Location) {
|
||||
let local_ty = self.mir.local_decls[local].ty;
|
||||
let local_ty = self.body.local_decls[local].ty;
|
||||
|
||||
let mut found_it = false;
|
||||
self.tcx.for_each_free_region(&local_ty, |r| {
|
||||
|
|
|
@ -54,7 +54,7 @@ impl BorrowExplanation {
|
|||
pub(in crate::borrow_check) fn add_explanation_to_diagnostic<'cx, 'gcx, 'tcx>(
|
||||
&self,
|
||||
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
borrow_desc: &str,
|
||||
borrow_span: Option<Span>,
|
||||
|
@ -94,7 +94,7 @@ impl BorrowExplanation {
|
|||
dropped_local,
|
||||
should_note_order,
|
||||
} => {
|
||||
let local_decl = &mir.local_decls[dropped_local];
|
||||
let local_decl = &body.local_decls[dropped_local];
|
||||
let (dtor_desc, type_desc) = match local_decl.ty.sty {
|
||||
// If type is an ADT that implements Drop, then
|
||||
// simplify output by reporting just the ADT name.
|
||||
|
@ -121,7 +121,7 @@ impl BorrowExplanation {
|
|||
TYPE = type_desc,
|
||||
DTOR = dtor_desc
|
||||
);
|
||||
err.span_label(mir.source_info(drop_loc).span, message);
|
||||
err.span_label(body.source_info(drop_loc).span, message);
|
||||
|
||||
if should_note_order {
|
||||
err.note(
|
||||
|
@ -147,7 +147,7 @@ impl BorrowExplanation {
|
|||
TYPE = type_desc,
|
||||
DTOR = dtor_desc
|
||||
);
|
||||
err.span_label(mir.source_info(drop_loc).span, message);
|
||||
err.span_label(body.source_info(drop_loc).span, message);
|
||||
|
||||
if let Some(info) = &local_decl.is_block_tail {
|
||||
// FIXME: use span_suggestion instead, highlighting the
|
||||
|
@ -233,7 +233,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
);
|
||||
|
||||
let regioncx = &self.nonlexical_regioncx;
|
||||
let mir = self.mir;
|
||||
let body = self.body;
|
||||
let tcx = self.infcx.tcx;
|
||||
|
||||
let borrow_region_vid = borrow.region;
|
||||
|
@ -248,9 +248,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
region_sub
|
||||
);
|
||||
|
||||
match find_use::find(mir, regioncx, tcx, region_sub, location) {
|
||||
match find_use::find(body, regioncx, tcx, region_sub, location) {
|
||||
Some(Cause::LiveVar(local, location)) => {
|
||||
let span = mir.source_info(location).span;
|
||||
let span = body.source_info(location).span;
|
||||
let spans = self
|
||||
.move_spans(&Place::Base(PlaceBase::Local(local)), location)
|
||||
.or_else(|| self.borrow_spans(span, location));
|
||||
|
@ -270,10 +270,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
|
||||
Some(Cause::DropVar(local, location)) => {
|
||||
let mut should_note_order = false;
|
||||
if mir.local_decls[local].name.is_some() {
|
||||
if body.local_decls[local].name.is_some() {
|
||||
if let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place {
|
||||
if let Place::Base(PlaceBase::Local(borrowed_local)) = place {
|
||||
if mir.local_decls[*borrowed_local].name.is_some()
|
||||
if body.local_decls[*borrowed_local].name.is_some()
|
||||
&& local != *borrowed_local
|
||||
{
|
||||
should_note_order = true;
|
||||
|
@ -293,7 +293,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, '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.mir,
|
||||
self.body,
|
||||
&self.upvars,
|
||||
self.mir_def_id,
|
||||
self.infcx,
|
||||
|
@ -359,7 +359,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
return outmost_back_edge;
|
||||
}
|
||||
|
||||
let block = &self.mir.basic_blocks()[location.block];
|
||||
let block = &self.body.basic_blocks()[location.block];
|
||||
|
||||
if location.statement_index < block.statements.len() {
|
||||
let successor = location.successor_within_block();
|
||||
|
@ -421,7 +421,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
if loop_head.dominates(from, &self.dominators) {
|
||||
let block = &self.mir.basic_blocks()[from.block];
|
||||
let block = &self.body.basic_blocks()[from.block];
|
||||
|
||||
if from.statement_index < block.statements.len() {
|
||||
let successor = from.successor_within_block();
|
||||
|
@ -453,7 +453,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
/// True if an edge `source -> target` is a backedge -- in other words, if the target
|
||||
/// dominates the source.
|
||||
fn is_back_edge(&self, source: Location, target: Location) -> bool {
|
||||
target.dominates(source, &self.mir.dominators())
|
||||
target.dominates(source, &self.body.dominators())
|
||||
}
|
||||
|
||||
/// Determine how the borrow was later used.
|
||||
|
@ -469,7 +469,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
(LaterUseKind::ClosureCapture, var_span)
|
||||
}
|
||||
UseSpans::OtherUse(span) => {
|
||||
let block = &self.mir.basic_blocks()[location.block];
|
||||
let block = &self.body.basic_blocks()[location.block];
|
||||
|
||||
let kind = if let Some(&Statement {
|
||||
kind: StatementKind::FakeRead(FakeReadCause::ForLet, _),
|
||||
|
@ -491,7 +491,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
Operand::Constant(c) => c.span,
|
||||
Operand::Copy(Place::Base(PlaceBase::Local(l))) |
|
||||
Operand::Move(Place::Base(PlaceBase::Local(l))) => {
|
||||
let local_decl = &self.mir.local_decls[*l];
|
||||
let local_decl = &self.body.local_decls[*l];
|
||||
if local_decl.name.is_none() {
|
||||
local_decl.source_info.span
|
||||
} else {
|
||||
|
@ -519,7 +519,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, '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.mir[location.block];
|
||||
let block = &self.body[location.block];
|
||||
let stmt = block.statements.get(location.statement_index);
|
||||
debug!(
|
||||
"was_captured_by_trait_object: location={:?} stmt={:?}",
|
||||
|
@ -546,7 +546,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
);
|
||||
while let Some(current_location) = queue.pop() {
|
||||
debug!("was_captured_by_trait: target={:?}", target);
|
||||
let block = &self.mir[current_location.block];
|
||||
let block = &self.body[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 {
|
||||
|
|
|
@ -21,7 +21,7 @@ pub(super) fn generate_invalidates<'cx, 'gcx, 'tcx>(
|
|||
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||
all_facts: &mut Option<AllFacts>,
|
||||
location_table: &LocationTable,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
borrow_set: &BorrowSet<'tcx>,
|
||||
) {
|
||||
if all_facts.is_none() {
|
||||
|
@ -30,16 +30,16 @@ pub(super) fn generate_invalidates<'cx, 'gcx, 'tcx>(
|
|||
}
|
||||
|
||||
if let Some(all_facts) = all_facts {
|
||||
let dominators = mir.dominators();
|
||||
let dominators = body.dominators();
|
||||
let mut ig = InvalidationGenerator {
|
||||
all_facts,
|
||||
borrow_set,
|
||||
tcx,
|
||||
location_table,
|
||||
mir,
|
||||
body,
|
||||
dominators,
|
||||
};
|
||||
ig.visit_body(mir);
|
||||
ig.visit_body(body);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ struct InvalidationGenerator<'cx, 'tcx: 'cx, 'gcx: 'tcx> {
|
|||
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||
all_facts: &'cx mut AllFacts,
|
||||
location_table: &'cx LocationTable,
|
||||
mir: &'cx Body<'tcx>,
|
||||
body: &'cx Body<'tcx>,
|
||||
dominators: Dominators<BasicBlock>,
|
||||
borrow_set: &'cx BorrowSet<'tcx>,
|
||||
}
|
||||
|
@ -400,13 +400,13 @@ impl<'cg, 'cx, 'tcx, 'gcx> InvalidationGenerator<'cx, 'tcx, 'gcx> {
|
|||
rw,
|
||||
);
|
||||
let tcx = self.tcx;
|
||||
let mir = self.mir;
|
||||
let body = self.body;
|
||||
let borrow_set = self.borrow_set.clone();
|
||||
let indices = self.borrow_set.borrows.indices();
|
||||
each_borrow_involving_path(
|
||||
self,
|
||||
tcx,
|
||||
mir,
|
||||
body,
|
||||
location,
|
||||
(sd, place),
|
||||
&borrow_set.clone(),
|
||||
|
|
|
@ -50,7 +50,7 @@ pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'gcx, 'tcx>(
|
|||
infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
|
||||
def_id: DefId,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
mir: &mut Body<'tcx>,
|
||||
body: &mut Body<'tcx>,
|
||||
) -> UniversalRegions<'tcx> {
|
||||
debug!("replace_regions_in_mir(def_id={:?})", def_id);
|
||||
|
||||
|
@ -58,10 +58,10 @@ pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'gcx, 'tcx>(
|
|||
let universal_regions = UniversalRegions::new(infcx, def_id, param_env);
|
||||
|
||||
// Replace all remaining regions with fresh inference variables.
|
||||
renumber::renumber_mir(infcx, mir);
|
||||
renumber::renumber_mir(infcx, body);
|
||||
|
||||
let source = MirSource::item(def_id);
|
||||
mir_util::dump_mir(infcx.tcx, None, "renumber", &0, source, mir, |_, _| Ok(()));
|
||||
mir_util::dump_mir(infcx.tcx, None, "renumber", &0, source, body, |_, _| Ok(()));
|
||||
|
||||
universal_regions
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
|
|||
infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
|
||||
def_id: DefId,
|
||||
universal_regions: UniversalRegions<'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
upvars: &[Upvar],
|
||||
location_table: &LocationTable,
|
||||
param_env: ty::ParamEnv<'gcx>,
|
||||
|
@ -94,7 +94,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
|
|||
|
||||
let universal_regions = Rc::new(universal_regions);
|
||||
|
||||
let elements = &Rc::new(RegionValueElements::new(mir));
|
||||
let elements = &Rc::new(RegionValueElements::new(body));
|
||||
|
||||
// Run the MIR type-checker.
|
||||
let MirTypeckResults {
|
||||
|
@ -103,7 +103,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
|
|||
} = type_check::type_check(
|
||||
infcx,
|
||||
param_env,
|
||||
mir,
|
||||
body,
|
||||
def_id,
|
||||
&universal_regions,
|
||||
location_table,
|
||||
|
@ -139,7 +139,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
|
|||
&mut liveness_constraints,
|
||||
&mut all_facts,
|
||||
location_table,
|
||||
&mir,
|
||||
&body,
|
||||
borrow_set,
|
||||
);
|
||||
|
||||
|
@ -148,7 +148,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
|
|||
universal_regions,
|
||||
placeholder_indices,
|
||||
universal_region_relations,
|
||||
mir,
|
||||
body,
|
||||
outlives_constraints,
|
||||
closure_bounds_mapping,
|
||||
type_tests,
|
||||
|
@ -161,7 +161,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
|
|||
infcx.tcx,
|
||||
&mut all_facts,
|
||||
location_table,
|
||||
&mir,
|
||||
&body,
|
||||
borrow_set,
|
||||
);
|
||||
|
||||
|
@ -191,21 +191,21 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
|
|||
|
||||
// Solve the region constraints.
|
||||
let closure_region_requirements =
|
||||
regioncx.solve(infcx, &mir, upvars, def_id, errors_buffer);
|
||||
regioncx.solve(infcx, &body, 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),
|
||||
&mir,
|
||||
&body,
|
||||
®ioncx,
|
||||
&closure_region_requirements,
|
||||
);
|
||||
|
||||
// We also have a `#[rustc_nll]` annotation that causes us to dump
|
||||
// information
|
||||
dump_annotation(infcx, &mir, def_id, ®ioncx, &closure_region_requirements, errors_buffer);
|
||||
dump_annotation(infcx, &body, def_id, ®ioncx, &closure_region_requirements, errors_buffer);
|
||||
|
||||
(regioncx, polonius_output, closure_region_requirements)
|
||||
}
|
||||
|
@ -213,7 +213,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
|
|||
fn dump_mir_results<'a, 'gcx, 'tcx>(
|
||||
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
source: MirSource<'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
regioncx: &RegionInferenceContext<'_>,
|
||||
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
|
||||
) {
|
||||
|
@ -227,7 +227,7 @@ fn dump_mir_results<'a, 'gcx, 'tcx>(
|
|||
"nll",
|
||||
&0,
|
||||
source,
|
||||
mir,
|
||||
body,
|
||||
|pass_where, out| {
|
||||
match pass_where {
|
||||
// Before the CFG, dump out the values for each region variable.
|
||||
|
@ -273,7 +273,7 @@ fn dump_mir_results<'a, 'gcx, 'tcx>(
|
|||
|
||||
fn dump_annotation<'a, 'gcx, 'tcx>(
|
||||
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
mir_def_id: DefId,
|
||||
regioncx: &RegionInferenceContext<'tcx>,
|
||||
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
|
||||
|
@ -296,7 +296,7 @@ fn dump_annotation<'a, 'gcx, 'tcx>(
|
|||
let mut err = tcx
|
||||
.sess
|
||||
.diagnostic()
|
||||
.span_note_diag(mir.span, "External requirements");
|
||||
.span_note_diag(body.span, "External requirements");
|
||||
|
||||
regioncx.annotate(tcx, &mut err);
|
||||
|
||||
|
@ -317,7 +317,7 @@ fn dump_annotation<'a, 'gcx, 'tcx>(
|
|||
let mut err = tcx
|
||||
.sess
|
||||
.diagnostic()
|
||||
.span_note_diag(mir.span, "No external requirements");
|
||||
.span_note_diag(body.span, "No external requirements");
|
||||
regioncx.annotate(tcx, &mut err);
|
||||
|
||||
err.buffer(errors_buffer);
|
||||
|
|
|
@ -62,7 +62,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
/// path to blame.
|
||||
fn best_blame_constraint(
|
||||
&self,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
from_region: RegionVid,
|
||||
target_test: impl Fn(RegionVid) -> bool,
|
||||
) -> (ConstraintCategory, bool, Span) {
|
||||
|
@ -88,9 +88,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
let mut categorized_path: Vec<(ConstraintCategory, bool, Span)> = path.iter()
|
||||
.map(|constraint| {
|
||||
if constraint.category == ConstraintCategory::ClosureBounds {
|
||||
self.retrieve_closure_constraint_info(mir, &constraint)
|
||||
self.retrieve_closure_constraint_info(body, &constraint)
|
||||
} else {
|
||||
(constraint.category, false, constraint.locations.span(mir))
|
||||
(constraint.category, false, constraint.locations.span(body))
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
@ -237,7 +237,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
/// Here we would be invoked with `fr = 'a` and `outlived_fr = `'b`.
|
||||
pub(super) fn report_error(
|
||||
&self,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
upvars: &[Upvar],
|
||||
infcx: &InferCtxt<'_, '_, 'tcx>,
|
||||
mir_def_id: DefId,
|
||||
|
@ -247,7 +247,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
) {
|
||||
debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr);
|
||||
|
||||
let (category, _, span) = self.best_blame_constraint(mir, fr, |r| {
|
||||
let (category, _, span) = self.best_blame_constraint(body, fr, |r| {
|
||||
self.provides_universal_region(r, fr, outlived_fr)
|
||||
});
|
||||
|
||||
|
@ -274,7 +274,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
match (category, fr_is_local, outlived_fr_is_local) {
|
||||
(ConstraintCategory::Return, true, false) if self.is_closure_fn_mut(infcx, fr) => {
|
||||
self.report_fnmut_error(
|
||||
mir,
|
||||
body,
|
||||
upvars,
|
||||
infcx,
|
||||
mir_def_id,
|
||||
|
@ -286,7 +286,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
}
|
||||
(ConstraintCategory::Assignment, true, false)
|
||||
| (ConstraintCategory::CallArgument, true, false) => self.report_escaping_data_error(
|
||||
mir,
|
||||
body,
|
||||
upvars,
|
||||
infcx,
|
||||
mir_def_id,
|
||||
|
@ -297,7 +297,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
errors_buffer,
|
||||
),
|
||||
_ => self.report_general_error(
|
||||
mir,
|
||||
body,
|
||||
upvars,
|
||||
infcx,
|
||||
mir_def_id,
|
||||
|
@ -357,7 +357,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
/// ```
|
||||
fn report_fnmut_error(
|
||||
&self,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
upvars: &[Upvar],
|
||||
infcx: &InferCtxt<'_, '_, 'tcx>,
|
||||
mir_def_id: DefId,
|
||||
|
@ -383,7 +383,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
|
||||
diag.span_label(span, message);
|
||||
|
||||
match self.give_region_a_name(infcx, mir, upvars, mir_def_id, outlived_fr, &mut 1)
|
||||
match self.give_region_a_name(infcx, body, upvars, mir_def_id, outlived_fr, &mut 1)
|
||||
.unwrap().source
|
||||
{
|
||||
RegionNameSource::NamedEarlyBoundRegion(fr_span)
|
||||
|
@ -422,7 +422,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
/// ```
|
||||
fn report_escaping_data_error(
|
||||
&self,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
upvars: &[Upvar],
|
||||
infcx: &InferCtxt<'_, '_, 'tcx>,
|
||||
mir_def_id: DefId,
|
||||
|
@ -433,9 +433,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
errors_buffer: &mut Vec<Diagnostic>,
|
||||
) {
|
||||
let fr_name_and_span =
|
||||
self.get_var_name_and_span_for_region(infcx.tcx, mir, upvars, fr);
|
||||
self.get_var_name_and_span_for_region(infcx.tcx, body, upvars, fr);
|
||||
let outlived_fr_name_and_span =
|
||||
self.get_var_name_and_span_for_region(infcx.tcx, mir, upvars, outlived_fr);
|
||||
self.get_var_name_and_span_for_region(infcx.tcx, body, upvars, outlived_fr);
|
||||
|
||||
let escapes_from = match self.universal_regions.defining_ty {
|
||||
DefiningTy::Closure(..) => "closure",
|
||||
|
@ -451,7 +451,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
|| escapes_from == "const"
|
||||
{
|
||||
return self.report_general_error(
|
||||
mir,
|
||||
body,
|
||||
upvars,
|
||||
infcx,
|
||||
mir_def_id,
|
||||
|
@ -514,7 +514,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
/// ```
|
||||
fn report_general_error(
|
||||
&self,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
upvars: &[Upvar],
|
||||
infcx: &InferCtxt<'_, '_, 'tcx>,
|
||||
mir_def_id: DefId,
|
||||
|
@ -532,10 +532,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
);
|
||||
|
||||
let counter = &mut 1;
|
||||
let fr_name = self.give_region_a_name(infcx, mir, upvars, mir_def_id, fr, counter).unwrap();
|
||||
let fr_name = self.give_region_a_name(
|
||||
infcx, body, upvars, mir_def_id, fr, counter).unwrap();
|
||||
fr_name.highlight_region_name(&mut diag);
|
||||
let outlived_fr_name =
|
||||
self.give_region_a_name(infcx, mir, upvars, mir_def_id, outlived_fr, counter).unwrap();
|
||||
self.give_region_a_name(infcx, body, upvars, mir_def_id, outlived_fr, counter).unwrap();
|
||||
outlived_fr_name.highlight_region_name(&mut diag);
|
||||
|
||||
let mir_def_name = if infcx.tcx.is_closure(mir_def_id) {
|
||||
|
@ -667,7 +668,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
|
||||
crate fn free_region_constraint_info(
|
||||
&self,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
upvars: &[Upvar],
|
||||
mir_def_id: DefId,
|
||||
infcx: &InferCtxt<'_, '_, 'tcx>,
|
||||
|
@ -675,12 +676,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
outlived_region: RegionVid,
|
||||
) -> (ConstraintCategory, bool, Span, Option<RegionName>) {
|
||||
let (category, from_closure, span) = self.best_blame_constraint(
|
||||
mir,
|
||||
body,
|
||||
borrow_region,
|
||||
|r| self.provides_universal_region(r, borrow_region, outlived_region)
|
||||
);
|
||||
let outlived_fr_name =
|
||||
self.give_region_a_name(infcx, mir, upvars, mir_def_id, outlived_region, &mut 1);
|
||||
self.give_region_a_name(infcx, body, upvars, mir_def_id, outlived_region, &mut 1);
|
||||
(category, from_closure, span, outlived_fr_name)
|
||||
}
|
||||
|
||||
|
@ -724,18 +725,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
// Finds a good span to blame for the fact that `fr1` outlives `fr2`.
|
||||
crate fn find_outlives_blame_span(
|
||||
&self,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
fr1: RegionVid,
|
||||
fr2: RegionVid,
|
||||
) -> (ConstraintCategory, Span) {
|
||||
let (category, _, span) =
|
||||
self.best_blame_constraint(mir, fr1, |r| self.provides_universal_region(r, fr1, fr2));
|
||||
self.best_blame_constraint(body, fr1, |r| self.provides_universal_region(r, fr1, fr2));
|
||||
(category, span)
|
||||
}
|
||||
|
||||
fn retrieve_closure_constraint_info(
|
||||
&self,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
constraint: &OutlivesConstraint,
|
||||
) -> (ConstraintCategory, bool, Span) {
|
||||
let loc = match constraint.locations {
|
||||
|
@ -747,7 +748,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
self.closure_bounds_mapping[&loc].get(&(constraint.sup, constraint.sub));
|
||||
opt_span_category
|
||||
.map(|&(category, span)| (category, true, span))
|
||||
.unwrap_or((constraint.category, false, mir.source_info(loc).span))
|
||||
.unwrap_or((constraint.category, false, body.source_info(loc).span))
|
||||
}
|
||||
|
||||
/// Returns `true` if a closure is inferred to be an `FnMut` closure.
|
||||
|
|
|
@ -152,7 +152,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
crate fn give_region_a_name(
|
||||
&self,
|
||||
infcx: &InferCtxt<'_, '_, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
upvars: &[Upvar],
|
||||
mir_def_id: DefId,
|
||||
fr: RegionVid,
|
||||
|
@ -165,7 +165,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
let value = self.give_name_from_error_region(infcx.tcx, mir_def_id, fr, counter)
|
||||
.or_else(|| {
|
||||
self.give_name_if_anonymous_region_appears_in_arguments(
|
||||
infcx, mir, mir_def_id, fr, counter,
|
||||
infcx, body, mir_def_id, fr, counter,
|
||||
)
|
||||
})
|
||||
.or_else(|| {
|
||||
|
@ -175,12 +175,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
})
|
||||
.or_else(|| {
|
||||
self.give_name_if_anonymous_region_appears_in_output(
|
||||
infcx, mir, mir_def_id, fr, counter,
|
||||
infcx, body, mir_def_id, fr, counter,
|
||||
)
|
||||
})
|
||||
.or_else(|| {
|
||||
self.give_name_if_anonymous_region_appears_in_yield_ty(
|
||||
infcx, mir, mir_def_id, fr, counter,
|
||||
infcx, body, mir_def_id, fr, counter,
|
||||
)
|
||||
});
|
||||
|
||||
|
@ -332,7 +332,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
fn give_name_if_anonymous_region_appears_in_arguments(
|
||||
&self,
|
||||
infcx: &InferCtxt<'_, '_, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
mir_def_id: DefId,
|
||||
fr: RegionVid,
|
||||
counter: &mut usize,
|
||||
|
@ -344,7 +344,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
self.universal_regions.unnormalized_input_tys[implicit_inputs + argument_index];
|
||||
if let Some(region_name) = self.give_name_if_we_can_match_hir_ty_from_argument(
|
||||
infcx,
|
||||
mir,
|
||||
body,
|
||||
mir_def_id,
|
||||
fr,
|
||||
arg_ty,
|
||||
|
@ -354,13 +354,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
return Some(region_name);
|
||||
}
|
||||
|
||||
self.give_name_if_we_cannot_match_hir_ty(infcx, mir, fr, arg_ty, counter)
|
||||
self.give_name_if_we_cannot_match_hir_ty(infcx, body, fr, arg_ty, counter)
|
||||
}
|
||||
|
||||
fn give_name_if_we_can_match_hir_ty_from_argument(
|
||||
&self,
|
||||
infcx: &InferCtxt<'_, '_, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
mir_def_id: DefId,
|
||||
needle_fr: RegionVid,
|
||||
argument_ty: Ty<'tcx>,
|
||||
|
@ -376,7 +376,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
// must highlight the variable.
|
||||
hir::TyKind::Infer => self.give_name_if_we_cannot_match_hir_ty(
|
||||
infcx,
|
||||
mir,
|
||||
body,
|
||||
needle_fr,
|
||||
argument_ty,
|
||||
counter,
|
||||
|
@ -406,7 +406,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
fn give_name_if_we_cannot_match_hir_ty(
|
||||
&self,
|
||||
infcx: &InferCtxt<'_, '_, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
needle_fr: RegionVid,
|
||||
argument_ty: Ty<'tcx>,
|
||||
counter: &mut usize,
|
||||
|
@ -422,7 +422,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
let assigned_region_name = if type_name.find(&format!("'{}", counter)).is_some() {
|
||||
// Only add a label if we can confirm that a region was labelled.
|
||||
let argument_index = self.get_argument_index_for_region(infcx.tcx, needle_fr)?;
|
||||
let (_, span) = self.get_argument_name_and_span_for_region(mir, argument_index);
|
||||
let (_, span) = self.get_argument_name_and_span_for_region(body, argument_index);
|
||||
|
||||
Some(RegionName {
|
||||
// This counter value will already have been used, so this function will increment
|
||||
|
@ -676,7 +676,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
fn give_name_if_anonymous_region_appears_in_output(
|
||||
&self,
|
||||
infcx: &InferCtxt<'_, '_, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
mir_def_id: DefId,
|
||||
fr: RegionVid,
|
||||
counter: &mut usize,
|
||||
|
@ -717,7 +717,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
node: hir::ImplItemKind::Method(method_sig, _),
|
||||
..
|
||||
}) => (method_sig.decl.output.span(), ""),
|
||||
_ => (mir.span, ""),
|
||||
_ => (body.span, ""),
|
||||
};
|
||||
|
||||
Some(RegionName {
|
||||
|
@ -736,7 +736,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
fn give_name_if_anonymous_region_appears_in_yield_ty(
|
||||
&self,
|
||||
infcx: &InferCtxt<'_, '_, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
mir_def_id: DefId,
|
||||
fr: RegionVid,
|
||||
counter: &mut usize,
|
||||
|
@ -768,7 +768,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
}) => (
|
||||
tcx.sess.source_map().end_point(*span)
|
||||
),
|
||||
_ => mir.span,
|
||||
_ => body.span,
|
||||
};
|
||||
|
||||
debug!(
|
||||
|
|
|
@ -11,7 +11,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
crate fn get_var_name_and_span_for_region(
|
||||
&self,
|
||||
tcx: TyCtxt<'_, '_, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
upvars: &[Upvar],
|
||||
fr: RegionVid,
|
||||
) -> Option<(Option<Symbol>, Span)> {
|
||||
|
@ -28,7 +28,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
.or_else(|| {
|
||||
debug!("get_var_name_and_span_for_region: attempting argument");
|
||||
self.get_argument_index_for_region(tcx, fr)
|
||||
.map(|index| self.get_argument_name_and_span_for_region(mir, index))
|
||||
.map(|index| self.get_argument_name_and_span_for_region(body, index))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -120,15 +120,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
/// declared.
|
||||
crate fn get_argument_name_and_span_for_region(
|
||||
&self,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
argument_index: usize,
|
||||
) -> (Option<Symbol>, Span) {
|
||||
let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
|
||||
let argument_local = Local::new(implicit_inputs + argument_index + 1);
|
||||
debug!("get_argument_name_and_span_for_region: argument_local={:?}", argument_local);
|
||||
|
||||
let argument_name = mir.local_decls[argument_local].name;
|
||||
let argument_span = mir.local_decls[argument_local].source_info.span;
|
||||
let argument_name = body.local_decls[argument_local].name;
|
||||
let argument_span = body.local_decls[argument_local].source_info.span;
|
||||
debug!("get_argument_name_and_span_for_region: argument_name={:?} argument_span={:?}",
|
||||
argument_name, argument_span);
|
||||
|
||||
|
|
|
@ -185,7 +185,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
universal_regions: Rc<UniversalRegions<'tcx>>,
|
||||
placeholder_indices: Rc<PlaceholderIndices>,
|
||||
universal_region_relations: Rc<UniversalRegionRelations<'tcx>>,
|
||||
_mir: &Body<'tcx>,
|
||||
_body: &Body<'tcx>,
|
||||
outlives_constraints: ConstraintSet,
|
||||
closure_bounds_mapping: FxHashMap<
|
||||
Location,
|
||||
|
@ -400,7 +400,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
pub(super) fn solve<'gcx>(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
upvars: &[Upvar],
|
||||
mir_def_id: DefId,
|
||||
errors_buffer: &mut Vec<Diagnostic>,
|
||||
|
@ -409,19 +409,19 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
infcx.tcx.sess.time_extended(),
|
||||
Some(infcx.tcx.sess),
|
||||
&format!("solve_nll_region_constraints({:?})", mir_def_id),
|
||||
|| self.solve_inner(infcx, mir, upvars, mir_def_id, errors_buffer),
|
||||
|| self.solve_inner(infcx, body, upvars, mir_def_id, errors_buffer),
|
||||
)
|
||||
}
|
||||
|
||||
fn solve_inner<'gcx>(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
upvars: &[Upvar],
|
||||
mir_def_id: DefId,
|
||||
errors_buffer: &mut Vec<Diagnostic>,
|
||||
) -> Option<ClosureRegionRequirements<'gcx>> {
|
||||
self.propagate_constraints(mir);
|
||||
self.propagate_constraints(body);
|
||||
|
||||
// If this is a closure, we can propagate unsatisfied
|
||||
// `outlives_requirements` to our creator, so create a vector
|
||||
|
@ -436,7 +436,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
|
||||
self.check_type_tests(
|
||||
infcx,
|
||||
mir,
|
||||
body,
|
||||
mir_def_id,
|
||||
outlives_requirements.as_mut(),
|
||||
errors_buffer,
|
||||
|
@ -444,7 +444,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
|
||||
self.check_universal_regions(
|
||||
infcx,
|
||||
mir,
|
||||
body,
|
||||
upvars,
|
||||
mir_def_id,
|
||||
outlives_requirements.as_mut(),
|
||||
|
@ -468,7 +468,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
/// for each region variable until all the constraints are
|
||||
/// satisfied. Note that some values may grow **too** large to be
|
||||
/// feasible, but we check this later.
|
||||
fn propagate_constraints(&mut self, _mir: &Body<'tcx>) {
|
||||
fn propagate_constraints(&mut self, _body: &Body<'tcx>) {
|
||||
debug!("propagate_constraints()");
|
||||
|
||||
debug!("propagate_constraints: constraints={:#?}", {
|
||||
|
@ -581,7 +581,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
fn check_type_tests<'gcx>(
|
||||
&self,
|
||||
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
mir_def_id: DefId,
|
||||
mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'gcx>>>,
|
||||
errors_buffer: &mut Vec<Diagnostic>,
|
||||
|
@ -599,7 +599,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
let generic_ty = type_test.generic_kind.to_ty(tcx);
|
||||
if self.eval_verify_bound(
|
||||
tcx,
|
||||
mir,
|
||||
body,
|
||||
generic_ty,
|
||||
type_test.lower_bound,
|
||||
&type_test.verify_bound,
|
||||
|
@ -610,7 +610,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
if let Some(propagated_outlives_requirements) = &mut propagated_outlives_requirements {
|
||||
if self.try_promote_type_test(
|
||||
infcx,
|
||||
mir,
|
||||
body,
|
||||
type_test,
|
||||
propagated_outlives_requirements,
|
||||
) {
|
||||
|
@ -624,7 +624,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
let lower_bound_region = self.to_error_region(type_test.lower_bound);
|
||||
|
||||
// Skip duplicate-ish errors.
|
||||
let type_test_span = type_test.locations.span(mir);
|
||||
let type_test_span = type_test.locations.span(body);
|
||||
let erased_generic_kind = tcx.erase_regions(&type_test.generic_kind);
|
||||
if !deduplicate_errors.insert((
|
||||
erased_generic_kind,
|
||||
|
@ -725,7 +725,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
fn try_promote_type_test<'gcx>(
|
||||
&self,
|
||||
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
type_test: &TypeTest<'tcx>,
|
||||
propagated_outlives_requirements: &mut Vec<ClosureOutlivesRequirement<'gcx>>,
|
||||
) -> bool {
|
||||
|
@ -762,7 +762,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
// where `ur` is a local bound -- we are sometimes in a
|
||||
// position to prove things that our caller cannot. See
|
||||
// #53570 for an example.
|
||||
if self.eval_verify_bound(tcx, mir, generic_ty, ur, &type_test.verify_bound) {
|
||||
if self.eval_verify_bound(tcx, body, generic_ty, ur, &type_test.verify_bound) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -782,7 +782,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
let requirement = ClosureOutlivesRequirement {
|
||||
subject,
|
||||
outlived_free_region: upper_bound,
|
||||
blame_span: locations.span(mir),
|
||||
blame_span: locations.span(body),
|
||||
category: ConstraintCategory::Boring,
|
||||
};
|
||||
debug!("try_promote_type_test: pushing {:#?}", requirement);
|
||||
|
@ -944,7 +944,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
fn eval_verify_bound(
|
||||
&self,
|
||||
tcx: TyCtxt<'_, '_, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
generic_ty: Ty<'tcx>,
|
||||
lower_bound: RegionVid,
|
||||
verify_bound: &VerifyBound<'tcx>,
|
||||
|
@ -956,20 +956,20 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
|
||||
match verify_bound {
|
||||
VerifyBound::IfEq(test_ty, verify_bound1) => {
|
||||
self.eval_if_eq(tcx, mir, generic_ty, lower_bound, test_ty, verify_bound1)
|
||||
self.eval_if_eq(tcx, body, generic_ty, lower_bound, test_ty, verify_bound1)
|
||||
}
|
||||
|
||||
VerifyBound::OutlivedBy(r) => {
|
||||
let r_vid = self.to_region_vid(r);
|
||||
self.eval_outlives(mir, r_vid, lower_bound)
|
||||
self.eval_outlives(body, r_vid, lower_bound)
|
||||
}
|
||||
|
||||
VerifyBound::AnyBound(verify_bounds) => verify_bounds.iter().any(|verify_bound| {
|
||||
self.eval_verify_bound(tcx, mir, generic_ty, lower_bound, verify_bound)
|
||||
self.eval_verify_bound(tcx, body, generic_ty, lower_bound, verify_bound)
|
||||
}),
|
||||
|
||||
VerifyBound::AllBounds(verify_bounds) => verify_bounds.iter().all(|verify_bound| {
|
||||
self.eval_verify_bound(tcx, mir, generic_ty, lower_bound, verify_bound)
|
||||
self.eval_verify_bound(tcx, body, generic_ty, lower_bound, verify_bound)
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
@ -977,7 +977,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
fn eval_if_eq(
|
||||
&self,
|
||||
tcx: TyCtxt<'_, '_, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
generic_ty: Ty<'tcx>,
|
||||
lower_bound: RegionVid,
|
||||
test_ty: Ty<'tcx>,
|
||||
|
@ -986,7 +986,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
let generic_ty_normalized = self.normalize_to_scc_representatives(tcx, generic_ty);
|
||||
let test_ty_normalized = self.normalize_to_scc_representatives(tcx, test_ty);
|
||||
if generic_ty_normalized == test_ty_normalized {
|
||||
self.eval_verify_bound(tcx, mir, generic_ty, lower_bound, verify_bound)
|
||||
self.eval_verify_bound(tcx, body, generic_ty, lower_bound, verify_bound)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
@ -1037,7 +1037,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
// Evaluate whether `sup_region: sub_region @ point`.
|
||||
fn eval_outlives(
|
||||
&self,
|
||||
_mir: &Body<'tcx>,
|
||||
_body: &Body<'tcx>,
|
||||
sup_region: RegionVid,
|
||||
sub_region: RegionVid,
|
||||
) -> bool {
|
||||
|
@ -1105,7 +1105,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
fn check_universal_regions<'gcx>(
|
||||
&self,
|
||||
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
upvars: &[Upvar],
|
||||
mir_def_id: DefId,
|
||||
mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'gcx>>>,
|
||||
|
@ -1119,7 +1119,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
// for our caller into the `outlives_requirements` vector.
|
||||
self.check_universal_region(
|
||||
infcx,
|
||||
mir,
|
||||
body,
|
||||
upvars,
|
||||
mir_def_id,
|
||||
fr,
|
||||
|
@ -1129,7 +1129,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
}
|
||||
|
||||
NLLRegionVariableOrigin::Placeholder(placeholder) => {
|
||||
self.check_bound_universal_region(infcx, mir, mir_def_id, fr, placeholder);
|
||||
self.check_bound_universal_region(infcx, body, mir_def_id, fr, placeholder);
|
||||
}
|
||||
|
||||
NLLRegionVariableOrigin::Existential => {
|
||||
|
@ -1150,7 +1150,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
fn check_universal_region<'gcx>(
|
||||
&self,
|
||||
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
upvars: &[Upvar],
|
||||
mir_def_id: DefId,
|
||||
longer_fr: RegionVid,
|
||||
|
@ -1183,7 +1183,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
longer_fr,
|
||||
representative,
|
||||
infcx,
|
||||
mir,
|
||||
body,
|
||||
upvars,
|
||||
mir_def_id,
|
||||
propagated_outlives_requirements,
|
||||
|
@ -1199,7 +1199,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
longer_fr,
|
||||
shorter_fr,
|
||||
infcx,
|
||||
mir,
|
||||
body,
|
||||
upvars,
|
||||
mir_def_id,
|
||||
propagated_outlives_requirements,
|
||||
|
@ -1216,7 +1216,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
longer_fr: RegionVid,
|
||||
shorter_fr: RegionVid,
|
||||
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
upvars: &[Upvar],
|
||||
mir_def_id: DefId,
|
||||
propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'gcx>>>,
|
||||
|
@ -1245,7 +1245,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
{
|
||||
debug!("check_universal_region: fr_minus={:?}", fr_minus);
|
||||
|
||||
let blame_span_category = self.find_outlives_blame_span(mir, longer_fr, shorter_fr);
|
||||
let blame_span_category =
|
||||
self.find_outlives_blame_span(body, longer_fr, shorter_fr);
|
||||
|
||||
// Grow `shorter_fr` until we find some non-local regions. (We
|
||||
// always will.) We'll call them `shorter_fr+` -- they're ever
|
||||
|
@ -1275,14 +1276,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
//
|
||||
// Note: in this case, we use the unapproximated regions to report the
|
||||
// error. This gives better error messages in some cases.
|
||||
self.report_error(mir, upvars, infcx, mir_def_id, longer_fr, shorter_fr, errors_buffer);
|
||||
self.report_error(body, upvars, infcx, mir_def_id, longer_fr, shorter_fr, errors_buffer);
|
||||
Some(ErrorReported)
|
||||
}
|
||||
|
||||
fn check_bound_universal_region<'gcx>(
|
||||
&self,
|
||||
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
_mir_def_id: DefId,
|
||||
longer_fr: RegionVid,
|
||||
placeholder: ty::PlaceholderRegion,
|
||||
|
@ -1330,7 +1331,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
|||
};
|
||||
|
||||
// Find the code to blame for the fact that `longer_fr` outlives `error_fr`.
|
||||
let (_, span) = self.find_outlives_blame_span(mir, longer_fr, error_region);
|
||||
let (_, span) = self.find_outlives_blame_span(body, longer_fr, error_region);
|
||||
|
||||
// Obviously, this error message is far from satisfactory.
|
||||
// At present, though, it only appears in unit tests --
|
||||
|
|
|
@ -20,9 +20,9 @@ crate struct RegionValueElements {
|
|||
}
|
||||
|
||||
impl RegionValueElements {
|
||||
crate fn new(mir: &Body<'_>) -> Self {
|
||||
crate fn new(body: &Body<'_>) -> Self {
|
||||
let mut num_points = 0;
|
||||
let statements_before_block: IndexVec<BasicBlock, usize> = mir.basic_blocks()
|
||||
let statements_before_block: IndexVec<BasicBlock, usize> = body.basic_blocks()
|
||||
.iter()
|
||||
.map(|block_data| {
|
||||
let v = num_points;
|
||||
|
@ -37,7 +37,7 @@ impl RegionValueElements {
|
|||
debug!("RegionValueElements: num_points={:#?}", num_points);
|
||||
|
||||
let mut basic_blocks = IndexVec::with_capacity(num_points);
|
||||
for (bb, bb_data) in mir.basic_blocks().iter_enumerated() {
|
||||
for (bb, bb_data) in body.basic_blocks().iter_enumerated() {
|
||||
basic_blocks.extend((0..=bb_data.statements.len()).map(|_| bb));
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ impl RegionValueElements {
|
|||
/// Pushes all predecessors of `index` onto `stack`.
|
||||
crate fn push_predecessors(
|
||||
&self,
|
||||
mir: &Body<'_>,
|
||||
body: &Body<'_>,
|
||||
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(
|
||||
mir.predecessors_for(block)
|
||||
body.predecessors_for(block)
|
||||
.iter()
|
||||
.map(|&pred_bb| mir.terminator_loc(pred_bb))
|
||||
.map(|&pred_bb| body.terminator_loc(pred_bb))
|
||||
.map(|pred_loc| self.point_from_location(pred_loc)),
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -6,12 +6,12 @@ use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
|
|||
|
||||
/// Replaces all free regions appearing in the MIR with fresh
|
||||
/// inference variables, returning the number of variables created.
|
||||
pub fn renumber_mir<'tcx>(infcx: &InferCtxt<'_, '_, 'tcx>, mir: &mut Body<'tcx>) {
|
||||
pub fn renumber_mir<'tcx>(infcx: &InferCtxt<'_, '_, 'tcx>, body: &mut Body<'tcx>) {
|
||||
debug!("renumber_mir()");
|
||||
debug!("renumber_mir: mir.arg_count={:?}", mir.arg_count);
|
||||
debug!("renumber_mir: body.arg_count={:?}", body.arg_count);
|
||||
|
||||
let mut visitor = NLLVisitor { infcx };
|
||||
visitor.visit_body(mir);
|
||||
visitor.visit_body(body);
|
||||
}
|
||||
|
||||
/// Replaces all regions appearing in `value` with fresh inference
|
||||
|
@ -47,12 +47,12 @@ impl<'a, 'gcx, 'tcx> NLLVisitor<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> {
|
||||
fn visit_body(&mut self, mir: &mut Body<'tcx>) {
|
||||
for promoted in mir.promoted.iter_mut() {
|
||||
fn visit_body(&mut self, body: &mut Body<'tcx>) {
|
||||
for promoted in body.promoted.iter_mut() {
|
||||
self.visit_body(promoted);
|
||||
}
|
||||
|
||||
self.super_body(mir);
|
||||
self.super_body(body);
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, ty: &mut Ty<'tcx>, ty_context: TyContext) {
|
||||
|
|
|
@ -20,7 +20,7 @@ use super::{Locations, TypeChecker};
|
|||
impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
pub(super) fn equate_inputs_and_outputs(
|
||||
&mut self,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
universal_regions: &UniversalRegions<'tcx>,
|
||||
normalized_inputs_and_output: &[Ty<'tcx>],
|
||||
) {
|
||||
|
@ -43,7 +43,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
// user-provided signature (e.g., the `_` in the code
|
||||
// above) with fresh variables.
|
||||
let (poly_sig, _) = self.infcx.instantiate_canonical_with_fresh_inference_vars(
|
||||
mir.span,
|
||||
body.span,
|
||||
&user_provided_poly_sig,
|
||||
);
|
||||
|
||||
|
@ -53,7 +53,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
Some(
|
||||
self.infcx
|
||||
.replace_bound_vars_with_fresh_vars(
|
||||
mir.span,
|
||||
body.span,
|
||||
LateBoundRegionConversionTime::FnCall,
|
||||
&poly_sig,
|
||||
)
|
||||
|
@ -73,8 +73,8 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
normalized_input_ty
|
||||
);
|
||||
|
||||
let mir_input_ty = mir.local_decls[local].ty;
|
||||
let mir_input_span = mir.local_decls[local].source_info.span;
|
||||
let mir_input_ty = body.local_decls[local].ty;
|
||||
let mir_input_span = body.local_decls[local].source_info.span;
|
||||
self.equate_normalized_input_or_output(
|
||||
normalized_input_ty,
|
||||
mir_input_ty,
|
||||
|
@ -89,8 +89,8 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
// In MIR, closures begin an implicit `self`, so
|
||||
// argument N is stored in local N+2.
|
||||
let local = Local::new(argument_index + 2);
|
||||
let mir_input_ty = mir.local_decls[local].ty;
|
||||
let mir_input_span = mir.local_decls[local].source_info.span;
|
||||
let mir_input_ty = body.local_decls[local].ty;
|
||||
let mir_input_span = body.local_decls[local].source_info.span;
|
||||
|
||||
// If the user explicitly annotated the input types, enforce those.
|
||||
let user_provided_input_ty =
|
||||
|
@ -104,19 +104,19 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
assert!(
|
||||
mir.yield_ty.is_some() && universal_regions.yield_ty.is_some()
|
||||
|| mir.yield_ty.is_none() && universal_regions.yield_ty.is_none()
|
||||
body.yield_ty.is_some() && universal_regions.yield_ty.is_some()
|
||||
|| body.yield_ty.is_none() && universal_regions.yield_ty.is_none()
|
||||
);
|
||||
if let Some(mir_yield_ty) = mir.yield_ty {
|
||||
if let Some(mir_yield_ty) = body.yield_ty {
|
||||
let ur_yield_ty = universal_regions.yield_ty.unwrap();
|
||||
let yield_span = mir.local_decls[RETURN_PLACE].source_info.span;
|
||||
let yield_span = body.local_decls[RETURN_PLACE].source_info.span;
|
||||
self.equate_normalized_input_or_output(ur_yield_ty, mir_yield_ty, yield_span);
|
||||
}
|
||||
|
||||
// Return types are a bit more complex. They may contain existential `impl Trait`
|
||||
// types.
|
||||
let mir_output_ty = mir.local_decls[RETURN_PLACE].ty;
|
||||
let output_span = mir.local_decls[RETURN_PLACE].source_info.span;
|
||||
let mir_output_ty = body.local_decls[RETURN_PLACE].ty;
|
||||
let output_span = body.local_decls[RETURN_PLACE].source_info.span;
|
||||
if let Err(terr) = self.eq_opaque_type_and_type(
|
||||
mir_output_ty,
|
||||
normalized_output_ty,
|
||||
|
|
|
@ -60,9 +60,9 @@ impl LocalUseMap {
|
|||
crate fn build(
|
||||
live_locals: &Vec<Local>,
|
||||
elements: &RegionValueElements,
|
||||
mir: &Body<'_>,
|
||||
body: &Body<'_>,
|
||||
) -> Self {
|
||||
let nones = IndexVec::from_elem_n(None, mir.local_decls.len());
|
||||
let nones = IndexVec::from_elem_n(None, body.local_decls.len());
|
||||
let mut local_use_map = LocalUseMap {
|
||||
first_def_at: nones.clone(),
|
||||
first_use_at: nones.clone(),
|
||||
|
@ -71,7 +71,7 @@ impl LocalUseMap {
|
|||
};
|
||||
|
||||
let mut locals_with_use_data: IndexVec<Local, bool> =
|
||||
IndexVec::from_elem_n(false, mir.local_decls.len());
|
||||
IndexVec::from_elem_n(false, body.local_decls.len());
|
||||
live_locals
|
||||
.iter()
|
||||
.for_each(|&local| locals_with_use_data[local] = true);
|
||||
|
@ -81,7 +81,7 @@ impl LocalUseMap {
|
|||
elements,
|
||||
locals_with_use_data,
|
||||
}
|
||||
.visit_body(mir);
|
||||
.visit_body(body);
|
||||
|
||||
local_use_map
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ mod trace;
|
|||
/// performed before
|
||||
pub(super) fn generate<'gcx, 'tcx>(
|
||||
typeck: &mut TypeChecker<'_, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
elements: &Rc<RegionValueElements>,
|
||||
flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
|
@ -44,7 +44,7 @@ pub(super) fn generate<'gcx, 'tcx>(
|
|||
// of the `live_locals`.
|
||||
// FIXME: Review "live" terminology past this point, we should
|
||||
// not be naming the `Local`s as live.
|
||||
mir.local_decls.indices().collect()
|
||||
body.local_decls.indices().collect()
|
||||
} else {
|
||||
let free_regions = {
|
||||
regions_that_outlive_free_regions(
|
||||
|
@ -53,13 +53,13 @@ pub(super) fn generate<'gcx, 'tcx>(
|
|||
&typeck.borrowck_context.constraints.outlives_constraints,
|
||||
)
|
||||
};
|
||||
compute_live_locals(typeck.tcx(), &free_regions, mir)
|
||||
compute_live_locals(typeck.tcx(), &free_regions, body)
|
||||
};
|
||||
|
||||
if !live_locals.is_empty() {
|
||||
trace::trace(
|
||||
typeck,
|
||||
mir,
|
||||
body,
|
||||
elements,
|
||||
flow_inits,
|
||||
move_data,
|
||||
|
@ -77,9 +77,9 @@ pub(super) fn generate<'gcx, 'tcx>(
|
|||
fn compute_live_locals(
|
||||
tcx: TyCtxt<'_, '_, 'tcx>,
|
||||
free_regions: &FxHashSet<RegionVid>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
) -> Vec<Local> {
|
||||
let live_locals: Vec<Local> = mir
|
||||
let live_locals: Vec<Local> = body
|
||||
.local_decls
|
||||
.iter_enumerated()
|
||||
.filter_map(|(local, local_decl)| {
|
||||
|
@ -93,7 +93,7 @@ fn compute_live_locals(
|
|||
})
|
||||
.collect();
|
||||
|
||||
debug!("{} total variables", mir.local_decls.len());
|
||||
debug!("{} total variables", body.local_decls.len());
|
||||
debug!("{} variables need liveness", live_locals.len());
|
||||
debug!("{} regions outlive free regions", free_regions.len());
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ use std::rc::Rc;
|
|||
/// this respects `#[may_dangle]` annotations).
|
||||
pub(super) fn trace(
|
||||
typeck: &mut TypeChecker<'_, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
elements: &Rc<RegionValueElements>,
|
||||
flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
|
@ -41,11 +41,11 @@ pub(super) fn trace(
|
|||
) {
|
||||
debug!("trace()");
|
||||
|
||||
let local_use_map = &LocalUseMap::build(&live_locals, elements, mir);
|
||||
let local_use_map = &LocalUseMap::build(&live_locals, elements, body);
|
||||
|
||||
let cx = LivenessContext {
|
||||
typeck,
|
||||
mir,
|
||||
body,
|
||||
flow_inits,
|
||||
elements,
|
||||
local_use_map,
|
||||
|
@ -72,7 +72,7 @@ where
|
|||
elements: &'me RegionValueElements,
|
||||
|
||||
/// MIR we are analyzing.
|
||||
mir: &'me Body<'tcx>,
|
||||
body: &'me Body<'tcx>,
|
||||
|
||||
/// Mapping to/from the various indices used for initialization tracking.
|
||||
move_data: &'me MoveData<'tcx>,
|
||||
|
@ -145,7 +145,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'gcx, 'tcx> {
|
|||
self.compute_use_live_points_for(local);
|
||||
self.compute_drop_live_points_for(local);
|
||||
|
||||
let local_ty = self.cx.mir.local_decls[local].ty;
|
||||
let local_ty = self.cx.body.local_decls[local].ty;
|
||||
|
||||
if !self.use_live_at.is_empty() {
|
||||
self.cx.add_use_live_facts_for(local_ty, &self.use_live_at);
|
||||
|
@ -197,7 +197,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'gcx, 'tcx> {
|
|||
if self.use_live_at.insert(p) {
|
||||
self.cx
|
||||
.elements
|
||||
.push_predecessors(self.cx.mir, p, &mut self.stack)
|
||||
.push_predecessors(self.cx.body, p, &mut self.stack)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'gcx, 'tcx> {
|
|||
// Find the drops where `local` is initialized.
|
||||
for drop_point in self.cx.local_use_map.drops(local) {
|
||||
let location = self.cx.elements.to_location(drop_point);
|
||||
debug_assert_eq!(self.cx.mir.terminator_loc(location.block), location,);
|
||||
debug_assert_eq!(self.cx.body.terminator_loc(location.block), location,);
|
||||
|
||||
if self.cx.initialized_at_terminator(location.block, mpi) {
|
||||
if self.drop_live_at.insert(drop_point) {
|
||||
|
@ -270,7 +270,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'gcx, 'tcx> {
|
|||
// live point.
|
||||
let term_location = self.cx.elements.to_location(term_point);
|
||||
debug_assert_eq!(
|
||||
self.cx.mir.terminator_loc(term_location.block),
|
||||
self.cx.body.terminator_loc(term_location.block),
|
||||
term_location,
|
||||
);
|
||||
let block = term_location.block;
|
||||
|
@ -297,7 +297,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
for &pred_block in self.cx.mir.predecessors_for(block).iter() {
|
||||
for &pred_block in self.cx.body.predecessors_for(block).iter() {
|
||||
debug!(
|
||||
"compute_drop_live_points_for_block: pred_block = {:?}",
|
||||
pred_block,
|
||||
|
@ -326,7 +326,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'gcx, 'tcx> {
|
|||
continue;
|
||||
}
|
||||
|
||||
let pred_term_loc = self.cx.mir.terminator_loc(pred_block);
|
||||
let pred_term_loc = self.cx.body.terminator_loc(pred_block);
|
||||
let pred_term_point = self.cx.elements.point_from_location(pred_term_loc);
|
||||
|
||||
// If the terminator of this predecessor either *assigns*
|
||||
|
@ -403,7 +403,7 @@ impl LivenessContext<'_, '_, '_, '_, 'tcx> {
|
|||
// the effects of all statements. This is the only way to get
|
||||
// "just ahead" of a terminator.
|
||||
self.flow_inits.reset_to_entry_of(block);
|
||||
for statement_index in 0..self.mir[block].statements.len() {
|
||||
for statement_index in 0..self.body[block].statements.len() {
|
||||
let location = Location {
|
||||
block,
|
||||
statement_index,
|
||||
|
@ -485,7 +485,7 @@ impl LivenessContext<'_, '_, '_, '_, 'tcx> {
|
|||
|
||||
drop_data.dropck_result.report_overflows(
|
||||
self.typeck.infcx.tcx,
|
||||
self.mir.source_info(*drop_locations.first().unwrap()).span,
|
||||
self.body.source_info(*drop_locations.first().unwrap()).span,
|
||||
dropped_ty,
|
||||
);
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ mod relate_tys;
|
|||
pub(crate) fn type_check<'gcx, 'tcx>(
|
||||
infcx: &InferCtxt<'_, 'gcx, 'tcx>,
|
||||
param_env: ty::ParamEnv<'gcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
mir_def_id: DefId,
|
||||
universal_regions: &Rc<UniversalRegions<'tcx>>,
|
||||
location_table: &LocationTable,
|
||||
|
@ -156,14 +156,14 @@ pub(crate) fn type_check<'gcx, 'tcx>(
|
|||
infcx,
|
||||
mir_def_id,
|
||||
param_env,
|
||||
mir,
|
||||
body,
|
||||
®ion_bound_pairs,
|
||||
implicit_region_bound,
|
||||
&mut borrowck_context,
|
||||
&universal_region_relations,
|
||||
|mut cx| {
|
||||
cx.equate_inputs_and_outputs(mir, universal_regions, &normalized_inputs_and_output);
|
||||
liveness::generate(&mut cx, mir, elements, flow_inits, move_data, location_table);
|
||||
cx.equate_inputs_and_outputs(body, universal_regions, &normalized_inputs_and_output);
|
||||
liveness::generate(&mut cx, body, elements, flow_inits, move_data, location_table);
|
||||
|
||||
translate_outlives_facts(cx.borrowck_context);
|
||||
},
|
||||
|
@ -179,7 +179,7 @@ fn type_check_internal<'a, 'gcx, 'tcx, R>(
|
|||
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
|
||||
mir_def_id: DefId,
|
||||
param_env: ty::ParamEnv<'gcx>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
|
||||
implicit_region_bound: ty::Region<'tcx>,
|
||||
borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
|
||||
|
@ -188,7 +188,7 @@ fn type_check_internal<'a, 'gcx, 'tcx, R>(
|
|||
) -> R where {
|
||||
let mut checker = TypeChecker::new(
|
||||
infcx,
|
||||
mir,
|
||||
body,
|
||||
mir_def_id,
|
||||
param_env,
|
||||
region_bound_pairs,
|
||||
|
@ -197,14 +197,14 @@ fn type_check_internal<'a, 'gcx, 'tcx, R>(
|
|||
universal_region_relations,
|
||||
);
|
||||
let errors_reported = {
|
||||
let mut verifier = TypeVerifier::new(&mut checker, mir);
|
||||
verifier.visit_body(mir);
|
||||
let mut verifier = TypeVerifier::new(&mut checker, body);
|
||||
verifier.visit_body(body);
|
||||
verifier.errors_reported
|
||||
};
|
||||
|
||||
if !errors_reported {
|
||||
// if verifier failed, don't do further checks to avoid ICEs
|
||||
checker.typeck_mir(mir);
|
||||
checker.typeck_mir(body);
|
||||
}
|
||||
|
||||
extra(&mut checker)
|
||||
|
@ -253,7 +253,7 @@ enum FieldAccessError {
|
|||
/// is a problem.
|
||||
struct TypeVerifier<'a, 'b: 'a, 'gcx: 'tcx, 'tcx: 'b> {
|
||||
cx: &'a mut TypeChecker<'b, 'gcx, 'tcx>,
|
||||
mir: &'b Body<'tcx>,
|
||||
body: &'b Body<'tcx>,
|
||||
last_span: Span,
|
||||
mir_def_id: DefId,
|
||||
errors_reported: bool,
|
||||
|
@ -327,7 +327,7 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
|||
|
||||
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
self.super_rvalue(rvalue, location);
|
||||
let rval_ty = rvalue.ty(self.mir, self.tcx());
|
||||
let rval_ty = rvalue.ty(self.body, self.tcx());
|
||||
self.sanitize_type(rvalue, rval_ty);
|
||||
}
|
||||
|
||||
|
@ -368,25 +368,25 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_body(&mut self, mir: &Body<'tcx>) {
|
||||
self.sanitize_type(&"return type", mir.return_ty());
|
||||
for local_decl in &mir.local_decls {
|
||||
fn visit_body(&mut self, body: &Body<'tcx>) {
|
||||
self.sanitize_type(&"return type", body.return_ty());
|
||||
for local_decl in &body.local_decls {
|
||||
self.sanitize_type(local_decl, local_decl.ty);
|
||||
}
|
||||
if self.errors_reported {
|
||||
return;
|
||||
}
|
||||
self.super_body(mir);
|
||||
self.super_body(body);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
||||
fn new(cx: &'a mut TypeChecker<'b, 'gcx, 'tcx>, mir: &'b Body<'tcx>) -> Self {
|
||||
fn new(cx: &'a mut TypeChecker<'b, 'gcx, 'tcx>, body: &'b Body<'tcx>) -> Self {
|
||||
TypeVerifier {
|
||||
mir,
|
||||
body,
|
||||
mir_def_id: cx.mir_def_id,
|
||||
cx,
|
||||
last_span: mir.span,
|
||||
last_span: body.span,
|
||||
errors_reported: false,
|
||||
}
|
||||
}
|
||||
|
@ -451,7 +451,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
|||
place.iterate(|place_base, place_projection| {
|
||||
let mut place_ty = match place_base {
|
||||
PlaceBase::Local(index) =>
|
||||
PlaceTy::from_ty(self.mir.local_decls[*index].ty),
|
||||
PlaceTy::from_ty(self.body.local_decls[*index].ty),
|
||||
PlaceBase::Static(box Static { kind, ty: sty }) => {
|
||||
let sty = self.sanitize_type(place, sty);
|
||||
let check_err =
|
||||
|
@ -478,10 +478,10 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
|||
match kind {
|
||||
StaticKind::Promoted(promoted) => {
|
||||
if !self.errors_reported {
|
||||
let promoted_mir = &self.mir.promoted[*promoted];
|
||||
self.sanitize_promoted(promoted_mir, location);
|
||||
let promoted_body = &self.body.promoted[*promoted];
|
||||
self.sanitize_promoted(promoted_body, location);
|
||||
|
||||
let promoted_ty = promoted_mir.return_ty();
|
||||
let promoted_ty = promoted_body.return_ty();
|
||||
check_err(self, place, promoted_ty, sty);
|
||||
}
|
||||
}
|
||||
|
@ -538,12 +538,12 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
fn sanitize_promoted(&mut self, promoted_mir: &'b Body<'tcx>, location: Location) {
|
||||
fn sanitize_promoted(&mut self, promoted_body: &'b Body<'tcx>, location: Location) {
|
||||
// Determine the constraints from the promoted MIR by running the type
|
||||
// checker on the promoted MIR, then transfer the constraints back to
|
||||
// the main MIR, changing the locations to the provided location.
|
||||
|
||||
let parent_mir = mem::replace(&mut self.mir, promoted_mir);
|
||||
let parent_body = mem::replace(&mut self.body, promoted_body);
|
||||
|
||||
let all_facts = &mut None;
|
||||
let mut constraints = Default::default();
|
||||
|
@ -562,14 +562,14 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
|||
&mut closure_bounds
|
||||
);
|
||||
|
||||
self.visit_body(promoted_mir);
|
||||
self.visit_body(promoted_body);
|
||||
|
||||
if !self.errors_reported {
|
||||
// if verifier failed, don't do further checks to avoid ICEs
|
||||
self.cx.typeck_mir(promoted_mir);
|
||||
self.cx.typeck_mir(promoted_body);
|
||||
}
|
||||
|
||||
self.mir = parent_mir;
|
||||
self.body = parent_body;
|
||||
// Merge the outlives constraints back in, at the given location.
|
||||
mem::swap(self.cx.borrowck_context.all_facts, all_facts);
|
||||
mem::swap(
|
||||
|
@ -632,7 +632,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
|||
)
|
||||
}
|
||||
ProjectionElem::Index(i) => {
|
||||
let index_ty = Place::Base(PlaceBase::Local(i)).ty(self.mir, tcx).ty;
|
||||
let index_ty = Place::Base(PlaceBase::Local(i)).ty(self.body, tcx).ty;
|
||||
if index_ty != tcx.types.usize {
|
||||
PlaceTy::from_ty(
|
||||
span_mirbug_and_err!(self, i, "index by non-usize {:?}", i),
|
||||
|
@ -969,10 +969,10 @@ impl Locations {
|
|||
}
|
||||
|
||||
/// Gets a span representing the location.
|
||||
pub fn span(&self, mir: &Body<'_>) -> Span {
|
||||
pub fn span(&self, body: &Body<'_>) -> Span {
|
||||
match self {
|
||||
Locations::All(span) => *span,
|
||||
Locations::Single(l) => mir.source_info(*l).span,
|
||||
Locations::Single(l) => body.source_info(*l).span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -980,7 +980,7 @@ impl Locations {
|
|||
impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||
fn new(
|
||||
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
mir_def_id: DefId,
|
||||
param_env: ty::ParamEnv<'gcx>,
|
||||
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
|
||||
|
@ -992,7 +992,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
infcx,
|
||||
last_span: DUMMY_SP,
|
||||
mir_def_id,
|
||||
user_type_annotations: &mir.user_type_annotations,
|
||||
user_type_annotations: &body.user_type_annotations,
|
||||
param_env,
|
||||
region_bound_pairs,
|
||||
implicit_region_bound,
|
||||
|
@ -1317,7 +1317,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn check_stmt(&mut self, mir: &Body<'tcx>, stmt: &Statement<'tcx>, location: Location) {
|
||||
fn check_stmt(&mut self, body: &Body<'tcx>, stmt: &Statement<'tcx>, location: Location) {
|
||||
debug!("check_stmt: {:?}", stmt);
|
||||
let tcx = self.tcx();
|
||||
match stmt.kind {
|
||||
|
@ -1345,14 +1345,14 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
ConstraintCategory::Return
|
||||
},
|
||||
Place::Base(PlaceBase::Local(l))
|
||||
if !mir.local_decls[l].is_user_variable.is_some() => {
|
||||
if !body.local_decls[l].is_user_variable.is_some() => {
|
||||
ConstraintCategory::Boring
|
||||
}
|
||||
_ => ConstraintCategory::Assignment,
|
||||
};
|
||||
|
||||
let place_ty = place.ty(mir, tcx).ty;
|
||||
let rv_ty = rv.ty(mir, tcx);
|
||||
let place_ty = place.ty(body, tcx).ty;
|
||||
let rv_ty = rv.ty(body, tcx);
|
||||
if let Err(terr) =
|
||||
self.sub_types_or_anon(rv_ty, place_ty, location.to_locations(), category)
|
||||
{
|
||||
|
@ -1386,7 +1386,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
self.check_rvalue(mir, rv, location);
|
||||
self.check_rvalue(body, rv, location);
|
||||
if !self.tcx().features().unsized_locals {
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: tcx.lang_items().sized_trait().unwrap(),
|
||||
|
@ -1403,7 +1403,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
ref place,
|
||||
variant_index,
|
||||
} => {
|
||||
let place_type = place.ty(mir, tcx).ty;
|
||||
let place_type = place.ty(body, tcx).ty;
|
||||
let adt = match place_type.sty {
|
||||
ty::Adt(adt, _) if adt.is_enum() => adt,
|
||||
_ => {
|
||||
|
@ -1425,7 +1425,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
};
|
||||
}
|
||||
StatementKind::AscribeUserType(ref place, variance, box ref projection) => {
|
||||
let place_ty = place.ty(mir, tcx).ty;
|
||||
let place_ty = place.ty(body, tcx).ty;
|
||||
if let Err(terr) = self.relate_type_and_user_type(
|
||||
place_ty,
|
||||
variance,
|
||||
|
@ -1456,7 +1456,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
|
||||
fn check_terminator(
|
||||
&mut self,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
term: &Terminator<'tcx>,
|
||||
term_location: Location,
|
||||
) {
|
||||
|
@ -1481,8 +1481,8 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
target: _,
|
||||
unwind: _,
|
||||
} => {
|
||||
let place_ty = location.ty(mir, tcx).ty;
|
||||
let rv_ty = value.ty(mir, tcx);
|
||||
let place_ty = location.ty(body, tcx).ty;
|
||||
let rv_ty = value.ty(body, tcx);
|
||||
|
||||
let locations = term_location.to_locations();
|
||||
if let Err(terr) =
|
||||
|
@ -1503,7 +1503,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
switch_ty,
|
||||
..
|
||||
} => {
|
||||
let discr_ty = discr.ty(mir, tcx);
|
||||
let discr_ty = discr.ty(body, tcx);
|
||||
if let Err(terr) = self.sub_types(
|
||||
discr_ty,
|
||||
switch_ty,
|
||||
|
@ -1531,7 +1531,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
from_hir_call,
|
||||
..
|
||||
} => {
|
||||
let func_ty = func.ty(mir, tcx);
|
||||
let func_ty = func.ty(body, tcx);
|
||||
debug!("check_terminator: call, func_ty={:?}", func_ty);
|
||||
let sig = match func_ty.sty {
|
||||
ty::FnDef(..) | ty::FnPtr(_) => func_ty.fn_sig(tcx),
|
||||
|
@ -1546,7 +1546,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
&sig,
|
||||
);
|
||||
let sig = self.normalize(sig, term_location);
|
||||
self.check_call_dest(mir, term, &sig, destination, term_location);
|
||||
self.check_call_dest(body, term, &sig, destination, term_location);
|
||||
|
||||
self.prove_predicates(
|
||||
sig.inputs_and_output.iter().map(|ty| ty::Predicate::WellFormed(ty)),
|
||||
|
@ -1571,28 +1571,28 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
.add_element(region_vid, term_location);
|
||||
}
|
||||
|
||||
self.check_call_inputs(mir, term, &sig, args, term_location, from_hir_call);
|
||||
self.check_call_inputs(body, term, &sig, args, term_location, from_hir_call);
|
||||
}
|
||||
TerminatorKind::Assert {
|
||||
ref cond, ref msg, ..
|
||||
} => {
|
||||
let cond_ty = cond.ty(mir, tcx);
|
||||
let cond_ty = cond.ty(body, tcx);
|
||||
if cond_ty != tcx.types.bool {
|
||||
span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty);
|
||||
}
|
||||
|
||||
if let BoundsCheck { ref len, ref index } = *msg {
|
||||
if len.ty(mir, tcx) != tcx.types.usize {
|
||||
if len.ty(body, tcx) != tcx.types.usize {
|
||||
span_mirbug!(self, len, "bounds-check length non-usize {:?}", len)
|
||||
}
|
||||
if index.ty(mir, tcx) != tcx.types.usize {
|
||||
if index.ty(body, tcx) != tcx.types.usize {
|
||||
span_mirbug!(self, index, "bounds-check index non-usize {:?}", index)
|
||||
}
|
||||
}
|
||||
}
|
||||
TerminatorKind::Yield { ref value, .. } => {
|
||||
let value_ty = value.ty(mir, tcx);
|
||||
match mir.yield_ty {
|
||||
let value_ty = value.ty(body, tcx);
|
||||
match body.yield_ty {
|
||||
None => span_mirbug!(self, term, "yield in non-generator"),
|
||||
Some(ty) => {
|
||||
if let Err(terr) = self.sub_types(
|
||||
|
@ -1618,7 +1618,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
|
||||
fn check_call_dest(
|
||||
&mut self,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
term: &Terminator<'tcx>,
|
||||
sig: &ty::FnSig<'tcx>,
|
||||
destination: &Option<(Place<'tcx>, BasicBlock)>,
|
||||
|
@ -1627,7 +1627,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
let tcx = self.tcx();
|
||||
match *destination {
|
||||
Some((ref dest, _target_block)) => {
|
||||
let dest_ty = dest.ty(mir, tcx).ty;
|
||||
let dest_ty = dest.ty(body, tcx).ty;
|
||||
let category = match *dest {
|
||||
Place::Base(PlaceBase::Local(RETURN_PLACE)) => {
|
||||
if let BorrowCheckContext {
|
||||
|
@ -1649,7 +1649,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
Place::Base(PlaceBase::Local(l))
|
||||
if !mir.local_decls[l].is_user_variable.is_some() => {
|
||||
if !body.local_decls[l].is_user_variable.is_some() => {
|
||||
ConstraintCategory::Boring
|
||||
}
|
||||
_ => ConstraintCategory::Assignment,
|
||||
|
@ -1687,7 +1687,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
|
||||
fn check_call_inputs(
|
||||
&mut self,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
term: &Terminator<'tcx>,
|
||||
sig: &ty::FnSig<'tcx>,
|
||||
args: &[Operand<'tcx>],
|
||||
|
@ -1706,7 +1706,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
span_mirbug!(self, term, "call to {:?} with wrong # of args", sig);
|
||||
}
|
||||
for (n, (fn_arg, op_arg)) in inputs.iter().zip(args).enumerate() {
|
||||
let op_arg_ty = op_arg.ty(mir, self.tcx());
|
||||
let op_arg_ty = op_arg.ty(body, self.tcx());
|
||||
let category = if from_hir_call {
|
||||
ConstraintCategory::CallArgument
|
||||
} else {
|
||||
|
@ -1728,15 +1728,15 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_iscleanup(&mut self, mir: &Body<'tcx>, block_data: &BasicBlockData<'tcx>) {
|
||||
fn check_iscleanup(&mut self, body: &Body<'tcx>, block_data: &BasicBlockData<'tcx>) {
|
||||
let is_cleanup = block_data.is_cleanup;
|
||||
self.last_span = block_data.terminator().source_info.span;
|
||||
match block_data.terminator().kind {
|
||||
TerminatorKind::Goto { target } => {
|
||||
self.assert_iscleanup(mir, block_data, target, is_cleanup)
|
||||
self.assert_iscleanup(body, block_data, target, is_cleanup)
|
||||
}
|
||||
TerminatorKind::SwitchInt { ref targets, .. } => for target in targets {
|
||||
self.assert_iscleanup(mir, block_data, *target, is_cleanup);
|
||||
self.assert_iscleanup(body, block_data, *target, is_cleanup);
|
||||
},
|
||||
TerminatorKind::Resume => if !is_cleanup {
|
||||
span_mirbug!(self, block_data, "resume on non-cleanup block!")
|
||||
|
@ -1754,9 +1754,9 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
if is_cleanup {
|
||||
span_mirbug!(self, block_data, "yield in cleanup block")
|
||||
}
|
||||
self.assert_iscleanup(mir, block_data, resume, is_cleanup);
|
||||
self.assert_iscleanup(body, block_data, resume, is_cleanup);
|
||||
if let Some(drop) = drop {
|
||||
self.assert_iscleanup(mir, block_data, drop, is_cleanup);
|
||||
self.assert_iscleanup(body, block_data, drop, is_cleanup);
|
||||
}
|
||||
}
|
||||
TerminatorKind::Unreachable => {}
|
||||
|
@ -1767,12 +1767,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
cleanup: unwind,
|
||||
..
|
||||
} => {
|
||||
self.assert_iscleanup(mir, block_data, target, is_cleanup);
|
||||
self.assert_iscleanup(body, block_data, target, is_cleanup);
|
||||
if let Some(unwind) = unwind {
|
||||
if is_cleanup {
|
||||
span_mirbug!(self, block_data, "unwind on cleanup block")
|
||||
}
|
||||
self.assert_iscleanup(mir, block_data, unwind, true);
|
||||
self.assert_iscleanup(body, block_data, unwind, true);
|
||||
}
|
||||
}
|
||||
TerminatorKind::Call {
|
||||
|
@ -1781,29 +1781,29 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
..
|
||||
} => {
|
||||
if let &Some((_, target)) = destination {
|
||||
self.assert_iscleanup(mir, block_data, target, is_cleanup);
|
||||
self.assert_iscleanup(body, block_data, target, is_cleanup);
|
||||
}
|
||||
if let Some(cleanup) = cleanup {
|
||||
if is_cleanup {
|
||||
span_mirbug!(self, block_data, "cleanup on cleanup block")
|
||||
}
|
||||
self.assert_iscleanup(mir, block_data, cleanup, true);
|
||||
self.assert_iscleanup(body, block_data, cleanup, true);
|
||||
}
|
||||
}
|
||||
TerminatorKind::FalseEdges {
|
||||
real_target,
|
||||
ref imaginary_targets,
|
||||
} => {
|
||||
self.assert_iscleanup(mir, block_data, real_target, is_cleanup);
|
||||
self.assert_iscleanup(body, block_data, real_target, is_cleanup);
|
||||
for target in imaginary_targets {
|
||||
self.assert_iscleanup(mir, block_data, *target, is_cleanup);
|
||||
self.assert_iscleanup(body, block_data, *target, is_cleanup);
|
||||
}
|
||||
}
|
||||
TerminatorKind::FalseUnwind {
|
||||
real_target,
|
||||
unwind,
|
||||
} => {
|
||||
self.assert_iscleanup(mir, block_data, real_target, is_cleanup);
|
||||
self.assert_iscleanup(body, block_data, real_target, is_cleanup);
|
||||
if let Some(unwind) = unwind {
|
||||
if is_cleanup {
|
||||
span_mirbug!(
|
||||
|
@ -1812,7 +1812,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
"cleanup in cleanup block via false unwind"
|
||||
);
|
||||
}
|
||||
self.assert_iscleanup(mir, block_data, unwind, true);
|
||||
self.assert_iscleanup(body, block_data, unwind, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1820,12 +1820,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
|
||||
fn assert_iscleanup(
|
||||
&mut self,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
ctxt: &dyn fmt::Debug,
|
||||
bb: BasicBlock,
|
||||
iscleanuppad: bool,
|
||||
) {
|
||||
if mir[bb].is_cleanup != iscleanuppad {
|
||||
if body[bb].is_cleanup != iscleanuppad {
|
||||
span_mirbug!(
|
||||
self,
|
||||
ctxt,
|
||||
|
@ -1836,8 +1836,8 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_local(&mut self, mir: &Body<'tcx>, local: Local, local_decl: &LocalDecl<'tcx>) {
|
||||
match mir.local_kind(local) {
|
||||
fn check_local(&mut self, body: &Body<'tcx>, local: Local, local_decl: &LocalDecl<'tcx>) {
|
||||
match body.local_kind(local) {
|
||||
LocalKind::ReturnPointer | LocalKind::Arg => {
|
||||
// return values of normal functions are required to be
|
||||
// sized by typeck, but return values of ADT constructors are
|
||||
|
@ -1938,16 +1938,16 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_rvalue(&mut self, mir: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
let tcx = self.tcx();
|
||||
|
||||
match rvalue {
|
||||
Rvalue::Aggregate(ak, ops) => {
|
||||
self.check_aggregate_rvalue(mir, rvalue, ak, ops, location)
|
||||
self.check_aggregate_rvalue(body, rvalue, ak, ops, location)
|
||||
}
|
||||
|
||||
Rvalue::Repeat(operand, len) => if *len > 1 {
|
||||
let operand_ty = operand.ty(mir, tcx);
|
||||
let operand_ty = operand.ty(body, tcx);
|
||||
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: tcx.lang_items().copy_trait().unwrap(),
|
||||
|
@ -1964,7 +1964,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
Rvalue::NullaryOp(_, ty) => {
|
||||
// Even with unsized locals cannot box an unsized value.
|
||||
if self.tcx().features().unsized_locals {
|
||||
let span = mir.source_info(location).span;
|
||||
let span = body.source_info(location).span;
|
||||
self.ensure_place_sized(ty, span);
|
||||
}
|
||||
|
||||
|
@ -1983,7 +1983,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
Rvalue::Cast(cast_kind, op, ty) => {
|
||||
match cast_kind {
|
||||
CastKind::Pointer(PointerCast::ReifyFnPointer) => {
|
||||
let fn_sig = op.ty(mir, tcx).fn_sig(tcx);
|
||||
let fn_sig = op.ty(body, tcx).fn_sig(tcx);
|
||||
|
||||
// The type that we see in the fcx is like
|
||||
// `foo::<'a, 'b>`, where `foo` is the path to a
|
||||
|
@ -2012,7 +2012,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
CastKind::Pointer(PointerCast::ClosureFnPointer(unsafety)) => {
|
||||
let sig = match op.ty(mir, tcx).sty {
|
||||
let sig = match op.ty(body, tcx).sty {
|
||||
ty::Closure(def_id, substs) => {
|
||||
substs.closure_sig_ty(def_id, tcx).fn_sig(tcx)
|
||||
}
|
||||
|
@ -2038,7 +2038,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
CastKind::Pointer(PointerCast::UnsafeFnPointer) => {
|
||||
let fn_sig = op.ty(mir, tcx).fn_sig(tcx);
|
||||
let fn_sig = op.ty(body, tcx).fn_sig(tcx);
|
||||
|
||||
// The type that we see in the fcx is like
|
||||
// `foo::<'a, 'b>`, where `foo` is the path to a
|
||||
|
@ -2070,7 +2070,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
let &ty = ty;
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: tcx.lang_items().coerce_unsized_trait().unwrap(),
|
||||
substs: tcx.mk_substs_trait(op.ty(mir, tcx), &[ty.into()]),
|
||||
substs: tcx.mk_substs_trait(op.ty(body, tcx), &[ty.into()]),
|
||||
};
|
||||
|
||||
self.prove_trait_ref(
|
||||
|
@ -2081,7 +2081,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
CastKind::Pointer(PointerCast::MutToConstPointer) => {
|
||||
let ty_from = match op.ty(mir, tcx).sty {
|
||||
let ty_from = match op.ty(body, tcx).sty {
|
||||
ty::RawPtr(ty::TypeAndMut {
|
||||
ty: ty_from,
|
||||
mutbl: hir::MutMutable,
|
||||
|
@ -2129,7 +2129,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
CastKind::Misc => {
|
||||
if let ty::Ref(_, mut ty_from, _) = op.ty(mir, tcx).sty {
|
||||
if let ty::Ref(_, mut ty_from, _) = op.ty(body, tcx).sty {
|
||||
let (mut ty_to, mutability) = if let ty::RawPtr(ty::TypeAndMut {
|
||||
ty: ty_to,
|
||||
mutbl,
|
||||
|
@ -2140,7 +2140,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
self,
|
||||
rvalue,
|
||||
"invalid cast types {:?} -> {:?}",
|
||||
op.ty(mir, tcx),
|
||||
op.ty(body, tcx),
|
||||
ty,
|
||||
);
|
||||
return;
|
||||
|
@ -2196,7 +2196,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
Rvalue::Ref(region, _borrow_kind, borrowed_place) => {
|
||||
self.add_reborrow_constraint(mir, location, region, borrowed_place);
|
||||
self.add_reborrow_constraint(body, location, region, borrowed_place);
|
||||
}
|
||||
|
||||
Rvalue::BinaryOp(BinOp::Eq, left, right)
|
||||
|
@ -2205,13 +2205,13 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
| Rvalue::BinaryOp(BinOp::Le, left, right)
|
||||
| Rvalue::BinaryOp(BinOp::Gt, left, right)
|
||||
| Rvalue::BinaryOp(BinOp::Ge, left, right) => {
|
||||
let ty_left = left.ty(mir, tcx);
|
||||
let ty_left = left.ty(body, tcx);
|
||||
if let ty::RawPtr(_) | ty::FnPtr(_) = ty_left.sty {
|
||||
let ty_right = right.ty(mir, tcx);
|
||||
let ty_right = right.ty(body, tcx);
|
||||
let common_ty = self.infcx.next_ty_var(
|
||||
TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::MiscVariable,
|
||||
span: mir.source_info(location).span,
|
||||
span: body.source_info(location).span,
|
||||
}
|
||||
);
|
||||
self.sub_types(
|
||||
|
@ -2277,7 +2277,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
|
||||
fn check_aggregate_rvalue(
|
||||
&mut self,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
rvalue: &Rvalue<'tcx>,
|
||||
aggregate_kind: &AggregateKind<'tcx>,
|
||||
operands: &[Operand<'tcx>],
|
||||
|
@ -2306,7 +2306,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
continue;
|
||||
}
|
||||
};
|
||||
let operand_ty = operand.ty(mir, tcx);
|
||||
let operand_ty = operand.ty(body, tcx);
|
||||
|
||||
if let Err(terr) = self.sub_types(
|
||||
operand_ty,
|
||||
|
@ -2335,7 +2335,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
/// - `borrowed_place`: the place `P` being borrowed
|
||||
fn add_reborrow_constraint(
|
||||
&mut self,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
location: Location,
|
||||
borrow_region: ty::Region<'tcx>,
|
||||
borrowed_place: &Place<'tcx>,
|
||||
|
@ -2382,7 +2382,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
match *elem {
|
||||
ProjectionElem::Deref => {
|
||||
let tcx = self.infcx.tcx;
|
||||
let base_ty = base.ty(mir, tcx).ty;
|
||||
let base_ty = base.ty(body, tcx).ty;
|
||||
|
||||
debug!("add_reborrow_constraint - base_ty = {:?}", base_ty);
|
||||
match base_ty.sty {
|
||||
|
@ -2624,15 +2624,15 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
fn typeck_mir(&mut self, mir: &Body<'tcx>) {
|
||||
self.last_span = mir.span;
|
||||
debug!("run_on_mir: {:?}", mir.span);
|
||||
fn typeck_mir(&mut self, body: &Body<'tcx>) {
|
||||
self.last_span = body.span;
|
||||
debug!("run_on_mir: {:?}", body.span);
|
||||
|
||||
for (local, local_decl) in mir.local_decls.iter_enumerated() {
|
||||
self.check_local(mir, local, local_decl);
|
||||
for (local, local_decl) in body.local_decls.iter_enumerated() {
|
||||
self.check_local(body, local, local_decl);
|
||||
}
|
||||
|
||||
for (block, block_data) in mir.basic_blocks().iter_enumerated() {
|
||||
for (block, block_data) in body.basic_blocks().iter_enumerated() {
|
||||
let mut location = Location {
|
||||
block,
|
||||
statement_index: 0,
|
||||
|
@ -2641,12 +2641,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
if !stmt.source_info.span.is_dummy() {
|
||||
self.last_span = stmt.source_info.span;
|
||||
}
|
||||
self.check_stmt(mir, stmt, location);
|
||||
self.check_stmt(body, stmt, location);
|
||||
location.statement_index += 1;
|
||||
}
|
||||
|
||||
self.check_terminator(mir, block_data.terminator(), location);
|
||||
self.check_iscleanup(mir, block_data);
|
||||
self.check_terminator(body, block_data.terminator(), location);
|
||||
self.check_iscleanup(body, block_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ pub(super) enum Control {
|
|||
pub(super) fn each_borrow_involving_path<'a, 'tcx, 'gcx: 'tcx, F, I, S> (
|
||||
s: &mut S,
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
_location: Location,
|
||||
access_place: (AccessDepth, &Place<'tcx>),
|
||||
borrow_set: &BorrowSet<'tcx>,
|
||||
|
@ -47,7 +47,7 @@ pub(super) fn each_borrow_involving_path<'a, 'tcx, 'gcx: 'tcx, F, I, S> (
|
|||
|
||||
if places_conflict::borrow_conflicts_with_place(
|
||||
tcx,
|
||||
mir,
|
||||
body,
|
||||
&borrowed.borrowed_place,
|
||||
borrowed.kind,
|
||||
place,
|
||||
|
|
|
@ -13,7 +13,7 @@ crate trait PlaceExt<'tcx> {
|
|||
fn ignore_borrow(
|
||||
&self,
|
||||
tcx: TyCtxt<'_, '_, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
locals_state_at_exit: &LocalsStateAtExit,
|
||||
) -> bool;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
|
|||
fn ignore_borrow(
|
||||
&self,
|
||||
tcx: TyCtxt<'_, '_, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
locals_state_at_exit: &LocalsStateAtExit,
|
||||
) -> bool {
|
||||
self.iterate(|place_base, place_projection| {
|
||||
|
@ -40,7 +40,7 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
|
|||
LocalsStateAtExit::AllAreInvalidated => false,
|
||||
LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => {
|
||||
let ignore = !has_storage_dead_or_moved.contains(*index) &&
|
||||
mir.local_decls[*index].mutability == Mutability::Not;
|
||||
body.local_decls[*index].mutability == Mutability::Not;
|
||||
debug!("ignore_borrow: local {:?} => {:?}", index, ignore);
|
||||
ignore
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
|
|||
|
||||
for proj in place_projection {
|
||||
if proj.elem == ProjectionElem::Deref {
|
||||
let ty = proj.base.ty(mir, tcx).ty;
|
||||
let ty = proj.base.ty(body, tcx).ty;
|
||||
match ty.sty {
|
||||
// For both derefs of raw pointers and `&T`
|
||||
// references, the original path is `Copy` and
|
||||
|
|
|
@ -26,14 +26,14 @@ crate enum PlaceConflictBias {
|
|||
/// dataflow).
|
||||
crate fn places_conflict<'gcx, 'tcx>(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
borrow_place: &Place<'tcx>,
|
||||
access_place: &Place<'tcx>,
|
||||
bias: PlaceConflictBias,
|
||||
) -> bool {
|
||||
borrow_conflicts_with_place(
|
||||
tcx,
|
||||
mir,
|
||||
body,
|
||||
borrow_place,
|
||||
BorrowKind::Mut { allow_two_phase_borrow: true },
|
||||
access_place,
|
||||
|
@ -48,7 +48,7 @@ crate fn places_conflict<'gcx, 'tcx>(
|
|||
/// order to make the conservative choice and preserve soundness.
|
||||
pub(super) fn borrow_conflicts_with_place<'gcx, 'tcx>(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
borrow_place: &Place<'tcx>,
|
||||
borrow_kind: BorrowKind,
|
||||
access_place: &Place<'tcx>,
|
||||
|
@ -72,7 +72,7 @@ pub(super) fn borrow_conflicts_with_place<'gcx, 'tcx>(
|
|||
access_place.iterate(|access_base, access_projections| {
|
||||
place_components_conflict(
|
||||
tcx,
|
||||
mir,
|
||||
body,
|
||||
(borrow_base, borrow_projections),
|
||||
borrow_kind,
|
||||
(access_base, access_projections),
|
||||
|
@ -85,7 +85,7 @@ pub(super) fn borrow_conflicts_with_place<'gcx, 'tcx>(
|
|||
|
||||
fn place_components_conflict<'gcx, 'tcx>(
|
||||
tcx: TyCtxt<'_, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
borrow_projections: (&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>),
|
||||
borrow_kind: BorrowKind,
|
||||
access_projections: (&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>),
|
||||
|
@ -175,7 +175,7 @@ fn place_components_conflict<'gcx, 'tcx>(
|
|||
// check whether the components being borrowed vs
|
||||
// accessed are disjoint (as in the second example,
|
||||
// but not the first).
|
||||
match place_projection_conflict(tcx, mir, borrow_c, access_c, bias) {
|
||||
match place_projection_conflict(tcx, body, borrow_c, access_c, bias) {
|
||||
Overlap::Arbitrary => {
|
||||
// We have encountered different fields of potentially
|
||||
// the same union - the borrow now partially overlaps.
|
||||
|
@ -214,7 +214,7 @@ fn place_components_conflict<'gcx, 'tcx>(
|
|||
|
||||
let base = &borrow_c.base;
|
||||
let elem = &borrow_c.elem;
|
||||
let base_ty = base.ty(mir, tcx).ty;
|
||||
let base_ty = base.ty(body, tcx).ty;
|
||||
|
||||
match (elem, &base_ty.sty, access) {
|
||||
(_, _, Shallow(Some(ArtificialField::ArrayLength)))
|
||||
|
@ -367,7 +367,7 @@ fn place_base_conflict<'a, 'gcx: 'tcx, 'tcx>(
|
|||
// between `elem1` and `elem2`.
|
||||
fn place_projection_conflict<'a, 'gcx: 'tcx, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
pi1: &Projection<'tcx>,
|
||||
pi2: &Projection<'tcx>,
|
||||
bias: PlaceConflictBias,
|
||||
|
@ -384,7 +384,7 @@ fn place_projection_conflict<'a, 'gcx: 'tcx, 'tcx>(
|
|||
debug!("place_element_conflict: DISJOINT-OR-EQ-FIELD");
|
||||
Overlap::EqualOrDisjoint
|
||||
} else {
|
||||
let ty = pi1.base.ty(mir, tcx).ty;
|
||||
let ty = pi1.base.ty(body, tcx).ty;
|
||||
match ty.sty {
|
||||
ty::Adt(def, _) if def.is_union() => {
|
||||
// Different fields of a union, we are basically stuck.
|
||||
|
|
|
@ -38,7 +38,7 @@ impl<'tcx> IsPrefixOf<'tcx> for Place<'tcx> {
|
|||
|
||||
|
||||
pub(super) struct Prefixes<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
|
||||
mir: &'cx Body<'tcx>,
|
||||
body: &'cx Body<'tcx>,
|
||||
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||
kind: PrefixSet,
|
||||
next: Option<&'cx Place<'tcx>>,
|
||||
|
@ -68,7 +68,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
Prefixes {
|
||||
next: Some(place),
|
||||
kind,
|
||||
mir: self.mir,
|
||||
body: self.body,
|
||||
tcx: self.infcx.tcx,
|
||||
}
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ impl<'cx, 'gcx, 'tcx> Iterator for Prefixes<'cx, 'gcx, 'tcx> {
|
|||
// derefs, except we stop at the deref of a shared
|
||||
// reference.
|
||||
|
||||
let ty = proj.base.ty(self.mir, self.tcx).ty;
|
||||
let ty = proj.base.ty(self.body, self.tcx).ty;
|
||||
match ty.sty {
|
||||
ty::RawPtr(_) |
|
||||
ty::Ref(
|
||||
|
|
|
@ -34,7 +34,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
never_initialized_mut_locals: &mut never_initialized_mut_locals,
|
||||
mbcx: self,
|
||||
};
|
||||
visitor.visit_body(visitor.mbcx.mir);
|
||||
visitor.visit_body(visitor.mbcx.body);
|
||||
}
|
||||
|
||||
// Take the union of the existed `used_mut` set with those variables we've found were
|
||||
|
|
|
@ -66,7 +66,7 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Body<'
|
|||
|
||||
tcx.infer_ctxt().enter(|infcx| {
|
||||
let cx = Cx::new(&infcx, id);
|
||||
let mut mir = if cx.tables().tainted_by_errors {
|
||||
let mut body = if cx.tables().tainted_by_errors {
|
||||
build::construct_error(cx, body_id)
|
||||
} else if cx.body_owner_kind.is_fn_or_closure() {
|
||||
// fetch the fully liberated fn signature (that is, all bound
|
||||
|
@ -165,19 +165,19 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Body<'
|
|||
// Convert the `mir::Body` to global types.
|
||||
let mut globalizer = GlobalizeMir {
|
||||
tcx,
|
||||
span: mir.span
|
||||
span: body.span
|
||||
};
|
||||
globalizer.visit_body(&mut mir);
|
||||
let mir = unsafe {
|
||||
mem::transmute::<Body<'_>, Body<'tcx>>(mir)
|
||||
globalizer.visit_body(&mut body);
|
||||
let body = unsafe {
|
||||
mem::transmute::<Body<'_>, Body<'tcx>>(body)
|
||||
};
|
||||
|
||||
mir_util::dump_mir(tcx, None, "mir_map", &0,
|
||||
MirSource::item(def_id), &mir, |_, _| Ok(()) );
|
||||
MirSource::item(def_id), &body, |_, _| Ok(()) );
|
||||
|
||||
lints::check(tcx, &mir, def_id);
|
||||
lints::check(tcx, &body, def_id);
|
||||
|
||||
mir
|
||||
body
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -700,9 +700,9 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
|
|||
info!("fn_id {:?} has attrs {:?}", fn_def_id,
|
||||
tcx.get_attrs(fn_def_id));
|
||||
|
||||
let mut mir = builder.finish(yield_ty);
|
||||
mir.spread_arg = spread_arg;
|
||||
mir
|
||||
let mut body = builder.finish(yield_ty);
|
||||
body.spread_arg = spread_arg;
|
||||
body
|
||||
}
|
||||
|
||||
fn construct_const<'a, 'gcx, 'tcx>(
|
||||
|
|
|
@ -55,12 +55,12 @@ pub(crate) fn mk_eval_cx<'a, 'mir, 'tcx>(
|
|||
pub(crate) fn eval_promoted<'a, 'mir, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
cid: GlobalId<'tcx>,
|
||||
mir: &'mir mir::Body<'tcx>,
|
||||
body: &'mir mir::Body<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
|
||||
let span = tcx.def_span(cid.instance.def_id());
|
||||
let mut ecx = mk_eval_cx(tcx, span, param_env);
|
||||
eval_body_using_ecx(&mut ecx, cid, mir, param_env)
|
||||
eval_body_using_ecx(&mut ecx, cid, body, param_env)
|
||||
}
|
||||
|
||||
fn mplace_to_const<'tcx>(
|
||||
|
@ -139,23 +139,23 @@ fn op_to_const<'tcx>(
|
|||
fn eval_body_using_ecx<'mir, 'tcx>(
|
||||
ecx: &mut CompileTimeEvalContext<'_, 'mir, 'tcx>,
|
||||
cid: GlobalId<'tcx>,
|
||||
mir: &'mir mir::Body<'tcx>,
|
||||
body: &'mir mir::Body<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
|
||||
debug!("eval_body_using_ecx: {:?}, {:?}", cid, param_env);
|
||||
let tcx = ecx.tcx.tcx;
|
||||
let layout = ecx.layout_of(mir.return_ty().subst(tcx, cid.instance.substs))?;
|
||||
let layout = ecx.layout_of(body.return_ty().subst(tcx, cid.instance.substs))?;
|
||||
assert!(!layout.is_unsized());
|
||||
let ret = ecx.allocate(layout, MemoryKind::Stack);
|
||||
|
||||
let name = ty::tls::with(|tcx| tcx.def_path_str(cid.instance.def_id()));
|
||||
let prom = cid.promoted.map_or(String::new(), |p| format!("::promoted[{:?}]", p));
|
||||
trace!("eval_body_using_ecx: pushing stack frame for global: {}{}", name, prom);
|
||||
assert!(mir.arg_count == 0);
|
||||
assert!(body.arg_count == 0);
|
||||
ecx.push_stack_frame(
|
||||
cid.instance,
|
||||
mir.span,
|
||||
mir,
|
||||
body.span,
|
||||
body,
|
||||
Some(ret.into()),
|
||||
StackPopCleanup::None { cleanup: false },
|
||||
)?;
|
||||
|
@ -165,7 +165,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
|
|||
|
||||
// Intern the result
|
||||
let mutability = if tcx.is_mutable_static(cid.instance.def_id()) ||
|
||||
!layout.ty.is_freeze(tcx, param_env, mir.span) {
|
||||
!layout.ty.is_freeze(tcx, param_env, body.span) {
|
||||
Mutability::Mutable
|
||||
} else {
|
||||
Mutability::Immutable
|
||||
|
@ -354,7 +354,7 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
|
|||
}
|
||||
// This is a const fn. Call it.
|
||||
Ok(Some(match ecx.load_mir(instance.def) {
|
||||
Ok(mir) => mir,
|
||||
Ok(body) => body,
|
||||
Err(err) => {
|
||||
if let InterpError::NoMirFor(ref path) = err.kind {
|
||||
return Err(
|
||||
|
@ -628,14 +628,14 @@ pub fn const_eval_raw_provider<'a, 'tcx>(
|
|||
let mut ecx = InterpretCx::new(tcx.at(span), key.param_env, CompileTimeInterpreter::new());
|
||||
|
||||
let res = ecx.load_mir(cid.instance.def);
|
||||
res.map(|mir| {
|
||||
res.map(|body| {
|
||||
if let Some(index) = cid.promoted {
|
||||
&mir.promoted[index]
|
||||
&body.promoted[index]
|
||||
} else {
|
||||
mir
|
||||
body
|
||||
}
|
||||
}).and_then(
|
||||
|mir| eval_body_using_ecx(&mut ecx, cid, mir, key.param_env)
|
||||
|body| eval_body_using_ecx(&mut ecx, cid, body, key.param_env)
|
||||
).and_then(|place| {
|
||||
Ok(RawConst {
|
||||
alloc_id: place.to_ptr().expect("we allocated this ptr!").alloc_id,
|
||||
|
|
|
@ -47,9 +47,9 @@ pub fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
|
|||
//
|
||||
// FIXME: we have to do something for moving slice patterns.
|
||||
fn place_contents_drop_state_cannot_differ<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
place: &mir::Place<'tcx>) -> bool {
|
||||
let ty = place.ty(mir, tcx).ty;
|
||||
let ty = place.ty(body, tcx).ty;
|
||||
match ty.sty {
|
||||
ty::Array(..) => {
|
||||
debug!("place_contents_drop_state_cannot_differ place: {:?} ty: {:?} => false",
|
||||
|
@ -74,7 +74,7 @@ fn place_contents_drop_state_cannot_differ<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx,
|
|||
|
||||
pub(crate) fn on_lookup_result_bits<'a, 'gcx, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
lookup_result: LookupResult,
|
||||
each_child: F)
|
||||
|
@ -85,14 +85,14 @@ pub(crate) fn on_lookup_result_bits<'a, 'gcx, 'tcx, F>(
|
|||
// access to untracked value - do not touch children
|
||||
}
|
||||
LookupResult::Exact(e) => {
|
||||
on_all_children_bits(tcx, mir, move_data, e, each_child)
|
||||
on_all_children_bits(tcx, body, move_data, e, each_child)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn on_all_children_bits<'a, 'gcx, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
move_path_index: MovePathIndex,
|
||||
mut each_child: F)
|
||||
|
@ -100,17 +100,17 @@ pub(crate) fn on_all_children_bits<'a, 'gcx, 'tcx, F>(
|
|||
{
|
||||
fn is_terminal_path<'a, 'gcx, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
path: MovePathIndex) -> bool
|
||||
{
|
||||
place_contents_drop_state_cannot_differ(
|
||||
tcx, mir, &move_data.move_paths[path].place)
|
||||
tcx, body, &move_data.move_paths[path].place)
|
||||
}
|
||||
|
||||
fn on_all_children_bits<'a, 'gcx, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
move_path_index: MovePathIndex,
|
||||
each_child: &mut F)
|
||||
|
@ -118,30 +118,30 @@ pub(crate) fn on_all_children_bits<'a, 'gcx, 'tcx, F>(
|
|||
{
|
||||
each_child(move_path_index);
|
||||
|
||||
if is_terminal_path(tcx, mir, move_data, move_path_index) {
|
||||
if is_terminal_path(tcx, body, move_data, move_path_index) {
|
||||
return
|
||||
}
|
||||
|
||||
let mut next_child_index = move_data.move_paths[move_path_index].first_child;
|
||||
while let Some(child_index) = next_child_index {
|
||||
on_all_children_bits(tcx, mir, move_data, child_index, each_child);
|
||||
on_all_children_bits(tcx, body, move_data, child_index, each_child);
|
||||
next_child_index = move_data.move_paths[child_index].next_sibling;
|
||||
}
|
||||
}
|
||||
on_all_children_bits(tcx, mir, move_data, move_path_index, &mut each_child);
|
||||
on_all_children_bits(tcx, body, move_data, move_path_index, &mut each_child);
|
||||
}
|
||||
|
||||
pub(crate) fn on_all_drop_children_bits<'a, 'gcx, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
ctxt: &MoveDataParamEnv<'gcx, 'tcx>,
|
||||
path: MovePathIndex,
|
||||
mut each_child: F)
|
||||
where F: FnMut(MovePathIndex)
|
||||
{
|
||||
on_all_children_bits(tcx, mir, &ctxt.move_data, path, |child| {
|
||||
on_all_children_bits(tcx, body, &ctxt.move_data, path, |child| {
|
||||
let place = &ctxt.move_data.move_paths[path].place;
|
||||
let ty = place.ty(mir, tcx).ty;
|
||||
let ty = place.ty(body, tcx).ty;
|
||||
debug!("on_all_drop_children_bits({:?}, {:?} : {:?})", path, place, ty);
|
||||
|
||||
let gcx = tcx.global_tcx();
|
||||
|
@ -156,16 +156,16 @@ pub(crate) fn on_all_drop_children_bits<'a, 'gcx, 'tcx, F>(
|
|||
|
||||
pub(crate) fn drop_flag_effects_for_function_entry<'a, 'gcx, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
ctxt: &MoveDataParamEnv<'gcx, 'tcx>,
|
||||
mut callback: F)
|
||||
where F: FnMut(MovePathIndex, DropFlagState)
|
||||
{
|
||||
let move_data = &ctxt.move_data;
|
||||
for arg in mir.args_iter() {
|
||||
for arg in body.args_iter() {
|
||||
let place = mir::Place::Base(mir::PlaceBase::Local(arg));
|
||||
let lookup_result = move_data.rev_lookup.find(&place);
|
||||
on_lookup_result_bits(tcx, mir, move_data,
|
||||
on_lookup_result_bits(tcx, body, move_data,
|
||||
lookup_result,
|
||||
|mpi| callback(mpi, DropFlagState::Present));
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ pub(crate) fn drop_flag_effects_for_function_entry<'a, 'gcx, 'tcx, F>(
|
|||
|
||||
pub(crate) fn drop_flag_effects_for_location<'a, 'gcx, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
ctxt: &MoveDataParamEnv<'gcx, 'tcx>,
|
||||
loc: Location,
|
||||
mut callback: F)
|
||||
|
@ -187,7 +187,7 @@ pub(crate) fn drop_flag_effects_for_location<'a, 'gcx, 'tcx, F>(
|
|||
let path = mi.move_path_index(move_data);
|
||||
debug!("moving out of path {:?}", move_data.move_paths[path]);
|
||||
|
||||
on_all_children_bits(tcx, mir, move_data,
|
||||
on_all_children_bits(tcx, body, move_data,
|
||||
path,
|
||||
|mpi| callback(mpi, DropFlagState::Absent))
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ pub(crate) fn drop_flag_effects_for_location<'a, 'gcx, 'tcx, F>(
|
|||
|
||||
for_location_inits(
|
||||
tcx,
|
||||
mir,
|
||||
body,
|
||||
move_data,
|
||||
loc,
|
||||
|mpi| callback(mpi, DropFlagState::Present)
|
||||
|
@ -205,7 +205,7 @@ pub(crate) fn drop_flag_effects_for_location<'a, 'gcx, 'tcx, F>(
|
|||
|
||||
pub(crate) fn for_location_inits<'a, 'gcx, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
loc: Location,
|
||||
mut callback: F)
|
||||
|
@ -217,7 +217,7 @@ pub(crate) fn for_location_inits<'a, 'gcx, 'tcx, F>(
|
|||
InitKind::Deep => {
|
||||
let path = init.path;
|
||||
|
||||
on_all_children_bits(tcx, mir, move_data,
|
||||
on_all_children_bits(tcx, body, move_data,
|
||||
path,
|
||||
&mut callback)
|
||||
},
|
||||
|
|
|
@ -17,7 +17,7 @@ use super::DebugFormatted;
|
|||
pub trait MirWithFlowState<'tcx> {
|
||||
type BD: BitDenotation<'tcx>;
|
||||
fn def_id(&self) -> DefId;
|
||||
fn mir(&self) -> &Body<'tcx>;
|
||||
fn body(&self) -> &Body<'tcx>;
|
||||
fn flow_state(&self) -> &DataflowState<'tcx, Self::BD>;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ impl<'a, 'tcx, BD> MirWithFlowState<'tcx> for DataflowBuilder<'a, 'tcx, BD>
|
|||
{
|
||||
type BD = BD;
|
||||
fn def_id(&self) -> DefId { self.def_id }
|
||||
fn mir(&self) -> &Body<'tcx> { self.flow_state.mir() }
|
||||
fn body(&self) -> &Body<'tcx> { self.flow_state.body() }
|
||||
fn flow_state(&self) -> &DataflowState<'tcx, Self::BD> { &self.flow_state.flow_state }
|
||||
}
|
||||
|
||||
|
@ -59,8 +59,8 @@ pub type Node = BasicBlock;
|
|||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Edge { source: BasicBlock, index: usize }
|
||||
|
||||
fn outgoing(mir: &Body<'_>, bb: BasicBlock) -> Vec<Edge> {
|
||||
(0..mir[bb].terminator().successors().count())
|
||||
fn outgoing(body: &Body<'_>, bb: BasicBlock) -> Vec<Edge> {
|
||||
(0..body[bb].terminator().successors().count())
|
||||
.map(|index| Edge { source: bb, index: index}).collect()
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P>
|
|||
// | [00-00] | _7 = const Foo::twiddle(move _8) | [0c-00] | [f3-0f] |
|
||||
// +---------+----------------------------------+------------------+------------------+
|
||||
let mut v = Vec::new();
|
||||
self.node_label_internal(n, &mut v, *n, self.mbcx.mir()).unwrap();
|
||||
self.node_label_internal(n, &mut v, *n, self.mbcx.body()).unwrap();
|
||||
dot::LabelText::html(String::from_utf8(v).unwrap())
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P>
|
|||
}
|
||||
|
||||
fn edge_label(&'a self, e: &Edge) -> dot::LabelText<'a> {
|
||||
let term = self.mbcx.mir()[e.source].terminator();
|
||||
let term = self.mbcx.body()[e.source].terminator();
|
||||
let label = &term.kind.fmt_successor_labels()[e.index];
|
||||
dot::LabelText::label(label.clone())
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ where MWF: MirWithFlowState<'tcx>,
|
|||
n: &Node,
|
||||
w: &mut W,
|
||||
block: BasicBlock,
|
||||
mir: &Body<'_>) -> io::Result<()> {
|
||||
body: &Body<'_>) -> io::Result<()> {
|
||||
// Header rows
|
||||
const HDRS: [&str; 4] = ["ENTRY", "MIR", "BLOCK GENS", "BLOCK KILLS"];
|
||||
const HDR_FMT: &str = "bgcolor=\"grey\"";
|
||||
|
@ -137,8 +137,8 @@ where MWF: MirWithFlowState<'tcx>,
|
|||
write!(w, "</tr>")?;
|
||||
|
||||
// Data row
|
||||
self.node_label_verbose_row(n, w, block, mir)?;
|
||||
self.node_label_final_row(n, w, block, mir)?;
|
||||
self.node_label_verbose_row(n, w, block, body)?;
|
||||
self.node_label_final_row(n, w, block, body)?;
|
||||
write!(w, "</table>")?;
|
||||
|
||||
Ok(())
|
||||
|
@ -149,7 +149,7 @@ where MWF: MirWithFlowState<'tcx>,
|
|||
n: &Node,
|
||||
w: &mut W,
|
||||
block: BasicBlock,
|
||||
mir: &Body<'_>)
|
||||
body: &Body<'_>)
|
||||
-> io::Result<()> {
|
||||
let i = n.index();
|
||||
|
||||
|
@ -175,7 +175,7 @@ where MWF: MirWithFlowState<'tcx>,
|
|||
// MIR statements
|
||||
write!(w, "<td>")?;
|
||||
{
|
||||
let data = &mir[block];
|
||||
let data = &body[block];
|
||||
for (i, statement) in data.statements.iter().enumerate() {
|
||||
write!(w, "{}<br align=\"left\"/>",
|
||||
dot::escape_html(&format!("{:3}: {:?}", i, statement)))?;
|
||||
|
@ -199,7 +199,7 @@ where MWF: MirWithFlowState<'tcx>,
|
|||
n: &Node,
|
||||
w: &mut W,
|
||||
block: BasicBlock,
|
||||
mir: &Body<'_>)
|
||||
body: &Body<'_>)
|
||||
-> io::Result<()> {
|
||||
let i = n.index();
|
||||
|
||||
|
@ -214,7 +214,7 @@ where MWF: MirWithFlowState<'tcx>,
|
|||
// Terminator
|
||||
write!(w, "<td>")?;
|
||||
{
|
||||
let data = &mir[block];
|
||||
let data = &body[block];
|
||||
let mut terminator_head = String::new();
|
||||
data.terminator().kind.fmt_head(&mut terminator_head).unwrap();
|
||||
write!(w, "{}", dot::escape_html(&terminator_head))?;
|
||||
|
@ -241,7 +241,7 @@ impl<'a, 'tcx, MWF, P> dot::GraphWalk<'a> for Graph<'a, 'tcx, MWF, P>
|
|||
type Node = Node;
|
||||
type Edge = Edge;
|
||||
fn nodes(&self) -> dot::Nodes<'_, Node> {
|
||||
self.mbcx.mir()
|
||||
self.mbcx.body()
|
||||
.basic_blocks()
|
||||
.indices()
|
||||
.collect::<Vec<_>>()
|
||||
|
@ -249,11 +249,11 @@ impl<'a, 'tcx, MWF, P> dot::GraphWalk<'a> for Graph<'a, 'tcx, MWF, P>
|
|||
}
|
||||
|
||||
fn edges(&self) -> dot::Edges<'_, Edge> {
|
||||
let mir = self.mbcx.mir();
|
||||
let body = self.mbcx.body();
|
||||
|
||||
mir.basic_blocks()
|
||||
body.basic_blocks()
|
||||
.indices()
|
||||
.flat_map(|bb| outgoing(mir, bb))
|
||||
.flat_map(|bb| outgoing(body, bb))
|
||||
.collect::<Vec<_>>()
|
||||
.into()
|
||||
}
|
||||
|
@ -263,7 +263,7 @@ impl<'a, 'tcx, MWF, P> dot::GraphWalk<'a> for Graph<'a, 'tcx, MWF, P>
|
|||
}
|
||||
|
||||
fn target(&self, edge: &Edge) -> Node {
|
||||
let mir = self.mbcx.mir();
|
||||
*mir[edge.source].terminator().successors().nth(edge.index).unwrap()
|
||||
let body = self.mbcx.body();
|
||||
*body[edge.source].terminator().successors().nth(edge.index).unwrap()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,17 +12,17 @@ use crate::dataflow::BitDenotation;
|
|||
/// immovable generators.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct HaveBeenBorrowedLocals<'a, 'tcx: 'a> {
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx: 'a> HaveBeenBorrowedLocals<'a, 'tcx> {
|
||||
pub fn new(mir: &'a Body<'tcx>)
|
||||
pub fn new(body: &'a Body<'tcx>)
|
||||
-> Self {
|
||||
HaveBeenBorrowedLocals { mir }
|
||||
HaveBeenBorrowedLocals { body }
|
||||
}
|
||||
|
||||
pub fn mir(&self) -> &Body<'tcx> {
|
||||
self.mir
|
||||
pub fn body(&self) -> &Body<'tcx> {
|
||||
self.body
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for HaveBeenBorrowedLocals<'a, 'tcx> {
|
|||
type Idx = Local;
|
||||
fn name() -> &'static str { "has_been_borrowed_locals" }
|
||||
fn bits_per_block(&self) -> usize {
|
||||
self.mir.local_decls.len()
|
||||
self.body.local_decls.len()
|
||||
}
|
||||
|
||||
fn start_block_effect(&self, _sets: &mut BitSet<Local>) {
|
||||
|
@ -40,7 +40,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for HaveBeenBorrowedLocals<'a, 'tcx> {
|
|||
fn statement_effect(&self,
|
||||
sets: &mut BlockSets<'_, Local>,
|
||||
loc: Location) {
|
||||
let stmt = &self.mir[loc.block].statements[loc.statement_index];
|
||||
let stmt = &self.body[loc.block].statements[loc.statement_index];
|
||||
|
||||
BorrowedLocalsVisitor {
|
||||
sets,
|
||||
|
@ -56,7 +56,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for HaveBeenBorrowedLocals<'a, 'tcx> {
|
|||
fn terminator_effect(&self,
|
||||
sets: &mut BlockSets<'_, Local>,
|
||||
loc: Location) {
|
||||
let terminator = self.mir[loc.block].terminator();
|
||||
let terminator = self.body[loc.block].terminator();
|
||||
BorrowedLocalsVisitor {
|
||||
sets,
|
||||
}.visit_terminator(terminator, loc);
|
||||
|
|
|
@ -31,7 +31,7 @@ newtype_index! {
|
|||
/// borrows in compact bitvectors.
|
||||
pub struct Borrows<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
|
||||
borrow_set: Rc<BorrowSet<'tcx>>,
|
||||
borrows_out_of_scope_at_location: FxHashMap<Location, Vec<BorrowIndex>>,
|
||||
|
@ -48,7 +48,7 @@ struct StackEntry {
|
|||
}
|
||||
|
||||
fn precompute_borrows_out_of_scope<'tcx>(
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
regioncx: &Rc<RegionInferenceContext<'tcx>>,
|
||||
borrows_out_of_scope_at_location: &mut FxHashMap<Location, Vec<BorrowIndex>>,
|
||||
borrow_index: BorrowIndex,
|
||||
|
@ -72,7 +72,7 @@ fn precompute_borrows_out_of_scope<'tcx>(
|
|||
stack.push(StackEntry {
|
||||
bb: location.block,
|
||||
lo: location.statement_index,
|
||||
hi: mir[location.block].statements.len(),
|
||||
hi: body[location.block].statements.len(),
|
||||
first_part_only: false,
|
||||
});
|
||||
|
||||
|
@ -95,7 +95,7 @@ fn precompute_borrows_out_of_scope<'tcx>(
|
|||
|
||||
if !finished_early {
|
||||
// Add successor BBs to the work list, if necessary.
|
||||
let bb_data = &mir[bb];
|
||||
let bb_data = &body[bb];
|
||||
assert!(hi == bb_data.statements.len());
|
||||
for &succ_bb in bb_data.terminator.as_ref().unwrap().successors() {
|
||||
visited.entry(succ_bb)
|
||||
|
@ -121,7 +121,7 @@ fn precompute_borrows_out_of_scope<'tcx>(
|
|||
stack.push(StackEntry {
|
||||
bb: succ_bb,
|
||||
lo: 0,
|
||||
hi: mir[succ_bb].statements.len(),
|
||||
hi: body[succ_bb].statements.len(),
|
||||
first_part_only: false,
|
||||
});
|
||||
// Insert 0 for this BB, to represent the whole BB
|
||||
|
@ -136,7 +136,7 @@ fn precompute_borrows_out_of_scope<'tcx>(
|
|||
impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
|
||||
crate fn new(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
nonlexical_regioncx: Rc<RegionInferenceContext<'tcx>>,
|
||||
borrow_set: &Rc<BorrowSet<'tcx>>,
|
||||
) -> Self {
|
||||
|
@ -145,14 +145,14 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
|
|||
let borrow_region = borrow_data.region.to_region_vid();
|
||||
let location = borrow_set.borrows[borrow_index].reserve_location;
|
||||
|
||||
precompute_borrows_out_of_scope(mir, &nonlexical_regioncx,
|
||||
precompute_borrows_out_of_scope(body, &nonlexical_regioncx,
|
||||
&mut borrows_out_of_scope_at_location,
|
||||
borrow_index, borrow_region, location);
|
||||
}
|
||||
|
||||
Borrows {
|
||||
tcx: tcx,
|
||||
mir: mir,
|
||||
body: body,
|
||||
borrow_set: borrow_set.clone(),
|
||||
borrows_out_of_scope_at_location,
|
||||
_nonlexical_regioncx: nonlexical_regioncx,
|
||||
|
@ -219,7 +219,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
|
|||
// locations.
|
||||
if places_conflict::places_conflict(
|
||||
self.tcx,
|
||||
self.mir,
|
||||
self.body,
|
||||
&borrow_data.borrowed_place,
|
||||
place,
|
||||
places_conflict::PlaceConflictBias::NoOverlap,
|
||||
|
@ -257,7 +257,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for Borrows<'a, 'gcx, 'tcx> {
|
|||
fn statement_effect(&self, sets: &mut BlockSets<'_, BorrowIndex>, location: Location) {
|
||||
debug!("Borrows::statement_effect: sets={:?} location={:?}", sets, location);
|
||||
|
||||
let block = &self.mir.basic_blocks().get(location.block).unwrap_or_else(|| {
|
||||
let block = &self.body.basic_blocks().get(location.block).unwrap_or_else(|| {
|
||||
panic!("could not find block at location {:?}", location);
|
||||
});
|
||||
let stmt = block.statements.get(location.statement_index).unwrap_or_else(|| {
|
||||
|
@ -274,7 +274,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for Borrows<'a, 'gcx, 'tcx> {
|
|||
if let mir::Rvalue::Ref(_, _, ref place) = **rhs {
|
||||
if place.ignore_borrow(
|
||||
self.tcx,
|
||||
self.mir,
|
||||
self.body,
|
||||
&self.borrow_set.locals_state_at_exit,
|
||||
) {
|
||||
return;
|
||||
|
|
|
@ -65,17 +65,17 @@ pub(super) mod borrows;
|
|||
/// places that would require a dynamic drop-flag at that statement.
|
||||
pub struct MaybeInitializedPlaces<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx: 'tcx, 'tcx> MaybeInitializedPlaces<'a, 'gcx, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>)
|
||||
-> Self
|
||||
{
|
||||
MaybeInitializedPlaces { tcx: tcx, mir: mir, mdpe: mdpe }
|
||||
MaybeInitializedPlaces { tcx: tcx, body: body, mdpe: mdpe }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,17 +120,17 @@ impl<'a, 'gcx, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'gcx, 'tcx
|
|||
/// places that would require a dynamic drop-flag at that statement.
|
||||
pub struct MaybeUninitializedPlaces<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> MaybeUninitializedPlaces<'a, 'gcx, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>)
|
||||
-> Self
|
||||
{
|
||||
MaybeUninitializedPlaces { tcx: tcx, mir: mir, mdpe: mdpe }
|
||||
MaybeUninitializedPlaces { tcx: tcx, body: body, mdpe: mdpe }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,17 +174,17 @@ impl<'a, 'gcx, 'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'a, 'gcx, 't
|
|||
/// that would require a dynamic drop-flag at that statement.
|
||||
pub struct DefinitelyInitializedPlaces<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx: 'a> DefinitelyInitializedPlaces<'a, 'gcx, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>)
|
||||
-> Self
|
||||
{
|
||||
DefinitelyInitializedPlaces { tcx: tcx, mir: mir, mdpe: mdpe }
|
||||
DefinitelyInitializedPlaces { tcx: tcx, body: body, mdpe: mdpe }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,17 +223,17 @@ impl<'a, 'gcx, 'tcx: 'a> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, '
|
|||
/// ```
|
||||
pub struct EverInitializedPlaces<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx: 'tcx, 'tcx: 'a> EverInitializedPlaces<'a, 'gcx, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'gcx, 'tcx>)
|
||||
-> Self
|
||||
{
|
||||
EverInitializedPlaces { tcx: tcx, mir: mir, mdpe: mdpe }
|
||||
EverInitializedPlaces { tcx: tcx, body: body, mdpe: mdpe }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -284,7 +284,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for MaybeInitializedPlaces<'a, 'gcx, 't
|
|||
|
||||
fn start_block_effect(&self, entry_set: &mut BitSet<MovePathIndex>) {
|
||||
drop_flag_effects_for_function_entry(
|
||||
self.tcx, self.mir, self.mdpe,
|
||||
self.tcx, self.body, self.mdpe,
|
||||
|path, s| {
|
||||
assert!(s == DropFlagState::Present);
|
||||
entry_set.insert(path);
|
||||
|
@ -296,7 +296,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for MaybeInitializedPlaces<'a, 'gcx, 't
|
|||
location: Location)
|
||||
{
|
||||
drop_flag_effects_for_location(
|
||||
self.tcx, self.mir, self.mdpe,
|
||||
self.tcx, self.body, self.mdpe,
|
||||
location,
|
||||
|path, s| Self::update_bits(sets, path, s)
|
||||
)
|
||||
|
@ -307,7 +307,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for MaybeInitializedPlaces<'a, 'gcx, 't
|
|||
location: Location)
|
||||
{
|
||||
drop_flag_effects_for_location(
|
||||
self.tcx, self.mir, self.mdpe,
|
||||
self.tcx, self.body, self.mdpe,
|
||||
location,
|
||||
|path, s| Self::update_bits(sets, path, s)
|
||||
)
|
||||
|
@ -322,7 +322,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for MaybeInitializedPlaces<'a, 'gcx, 't
|
|||
) {
|
||||
// when a call returns successfully, that means we need to set
|
||||
// the bits for that dest_place to 1 (initialized).
|
||||
on_lookup_result_bits(self.tcx, self.mir, self.move_data(),
|
||||
on_lookup_result_bits(self.tcx, self.body, self.move_data(),
|
||||
self.move_data().rev_lookup.find(dest_place),
|
||||
|mpi| { in_out.insert(mpi); });
|
||||
}
|
||||
|
@ -342,7 +342,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for MaybeUninitializedPlaces<'a, 'gcx,
|
|||
entry_set.insert_all();
|
||||
|
||||
drop_flag_effects_for_function_entry(
|
||||
self.tcx, self.mir, self.mdpe,
|
||||
self.tcx, self.body, self.mdpe,
|
||||
|path, s| {
|
||||
assert!(s == DropFlagState::Present);
|
||||
entry_set.remove(path);
|
||||
|
@ -354,7 +354,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for MaybeUninitializedPlaces<'a, 'gcx,
|
|||
location: Location)
|
||||
{
|
||||
drop_flag_effects_for_location(
|
||||
self.tcx, self.mir, self.mdpe,
|
||||
self.tcx, self.body, self.mdpe,
|
||||
location,
|
||||
|path, s| Self::update_bits(sets, path, s)
|
||||
)
|
||||
|
@ -365,7 +365,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for MaybeUninitializedPlaces<'a, 'gcx,
|
|||
location: Location)
|
||||
{
|
||||
drop_flag_effects_for_location(
|
||||
self.tcx, self.mir, self.mdpe,
|
||||
self.tcx, self.body, self.mdpe,
|
||||
location,
|
||||
|path, s| Self::update_bits(sets, path, s)
|
||||
)
|
||||
|
@ -380,7 +380,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for MaybeUninitializedPlaces<'a, 'gcx,
|
|||
) {
|
||||
// when a call returns successfully, that means we need to set
|
||||
// the bits for that dest_place to 0 (initialized).
|
||||
on_lookup_result_bits(self.tcx, self.mir, self.move_data(),
|
||||
on_lookup_result_bits(self.tcx, self.body, self.move_data(),
|
||||
self.move_data().rev_lookup.find(dest_place),
|
||||
|mpi| { in_out.remove(mpi); });
|
||||
}
|
||||
|
@ -398,7 +398,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for DefinitelyInitializedPlaces<'a, 'gc
|
|||
entry_set.clear();
|
||||
|
||||
drop_flag_effects_for_function_entry(
|
||||
self.tcx, self.mir, self.mdpe,
|
||||
self.tcx, self.body, self.mdpe,
|
||||
|path, s| {
|
||||
assert!(s == DropFlagState::Present);
|
||||
entry_set.insert(path);
|
||||
|
@ -410,7 +410,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for DefinitelyInitializedPlaces<'a, 'gc
|
|||
location: Location)
|
||||
{
|
||||
drop_flag_effects_for_location(
|
||||
self.tcx, self.mir, self.mdpe,
|
||||
self.tcx, self.body, self.mdpe,
|
||||
location,
|
||||
|path, s| Self::update_bits(sets, path, s)
|
||||
)
|
||||
|
@ -421,7 +421,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for DefinitelyInitializedPlaces<'a, 'gc
|
|||
location: Location)
|
||||
{
|
||||
drop_flag_effects_for_location(
|
||||
self.tcx, self.mir, self.mdpe,
|
||||
self.tcx, self.body, self.mdpe,
|
||||
location,
|
||||
|path, s| Self::update_bits(sets, path, s)
|
||||
)
|
||||
|
@ -436,7 +436,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for DefinitelyInitializedPlaces<'a, 'gc
|
|||
) {
|
||||
// when a call returns successfully, that means we need to set
|
||||
// the bits for that dest_place to 1 (initialized).
|
||||
on_lookup_result_bits(self.tcx, self.mir, self.move_data(),
|
||||
on_lookup_result_bits(self.tcx, self.body, self.move_data(),
|
||||
self.move_data().rev_lookup.find(dest_place),
|
||||
|mpi| { in_out.insert(mpi); });
|
||||
}
|
||||
|
@ -450,7 +450,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for EverInitializedPlaces<'a, 'gcx, 'tc
|
|||
}
|
||||
|
||||
fn start_block_effect(&self, entry_set: &mut BitSet<InitIndex>) {
|
||||
for arg_init in 0..self.mir.arg_count {
|
||||
for arg_init in 0..self.body.arg_count {
|
||||
entry_set.insert(InitIndex::new(arg_init));
|
||||
}
|
||||
}
|
||||
|
@ -458,8 +458,8 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for EverInitializedPlaces<'a, 'gcx, 'tc
|
|||
fn statement_effect(&self,
|
||||
sets: &mut BlockSets<'_, InitIndex>,
|
||||
location: Location) {
|
||||
let (_, mir, move_data) = (self.tcx, self.mir, self.move_data());
|
||||
let stmt = &mir[location.block].statements[location.statement_index];
|
||||
let (_, body, move_data) = (self.tcx, self.body, self.move_data());
|
||||
let stmt = &body[location.block].statements[location.statement_index];
|
||||
let init_path_map = &move_data.init_path_map;
|
||||
let init_loc_map = &move_data.init_loc_map;
|
||||
let rev_lookup = &move_data.rev_lookup;
|
||||
|
@ -485,8 +485,8 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for EverInitializedPlaces<'a, 'gcx, 'tc
|
|||
sets: &mut BlockSets<'_, InitIndex>,
|
||||
location: Location)
|
||||
{
|
||||
let (mir, move_data) = (self.mir, self.move_data());
|
||||
let term = mir[location.block].terminator();
|
||||
let (body, move_data) = (self.body, self.move_data());
|
||||
let term = body[location.block].terminator();
|
||||
let init_loc_map = &move_data.init_loc_map;
|
||||
debug!("terminator {:?} at loc {:?} initializes move_indexes {:?}",
|
||||
term, location, &init_loc_map[location]);
|
||||
|
@ -510,7 +510,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for EverInitializedPlaces<'a, 'gcx, 'tc
|
|||
|
||||
let call_loc = Location {
|
||||
block: call_bb,
|
||||
statement_index: self.mir[call_bb].statements.len(),
|
||||
statement_index: self.body[call_bb].statements.len(),
|
||||
};
|
||||
for init_index in &init_loc_map[call_loc] {
|
||||
assert!(init_index.index() < bits_per_block);
|
||||
|
|
|
@ -5,17 +5,17 @@ use crate::dataflow::BitDenotation;
|
|||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct MaybeStorageLive<'a, 'tcx: 'a> {
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx: 'a> MaybeStorageLive<'a, 'tcx> {
|
||||
pub fn new(mir: &'a Body<'tcx>)
|
||||
pub fn new(body: &'a Body<'tcx>)
|
||||
-> Self {
|
||||
MaybeStorageLive { mir }
|
||||
MaybeStorageLive { body }
|
||||
}
|
||||
|
||||
pub fn mir(&self) -> &Body<'tcx> {
|
||||
self.mir
|
||||
pub fn body(&self) -> &Body<'tcx> {
|
||||
self.body
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeStorageLive<'a, 'tcx> {
|
|||
type Idx = Local;
|
||||
fn name() -> &'static str { "maybe_storage_live" }
|
||||
fn bits_per_block(&self) -> usize {
|
||||
self.mir.local_decls.len()
|
||||
self.body.local_decls.len()
|
||||
}
|
||||
|
||||
fn start_block_effect(&self, _sets: &mut BitSet<Local>) {
|
||||
|
@ -33,7 +33,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeStorageLive<'a, 'tcx> {
|
|||
fn statement_effect(&self,
|
||||
sets: &mut BlockSets<'_, Local>,
|
||||
loc: Location) {
|
||||
let stmt = &self.mir[loc.block].statements[loc.statement_index];
|
||||
let stmt = &self.body[loc.block].statements[loc.statement_index];
|
||||
|
||||
match stmt.kind {
|
||||
StatementKind::StorageLive(l) => sets.gen(l),
|
||||
|
|
|
@ -122,7 +122,7 @@ pub struct MoveDataParamEnv<'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
pub(crate) fn do_dataflow<'a, 'gcx, 'tcx, BD, P>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
def_id: DefId,
|
||||
attributes: &[ast::Attribute],
|
||||
dead_unwinds: &BitSet<BasicBlock>,
|
||||
|
@ -132,7 +132,7 @@ pub(crate) fn do_dataflow<'a, 'gcx, 'tcx, BD, P>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
|||
where BD: BitDenotation<'tcx> + InitialFlow,
|
||||
P: Fn(&BD, BD::Idx) -> DebugFormatted
|
||||
{
|
||||
let flow_state = DataflowAnalysis::new(mir, dead_unwinds, bd);
|
||||
let flow_state = DataflowAnalysis::new(body, dead_unwinds, bd);
|
||||
flow_state.run(tcx, def_id, attributes, p)
|
||||
}
|
||||
|
||||
|
@ -195,7 +195,7 @@ impl<'a, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation<'t
|
|||
self.flow_state.operator.start_block_effect(&mut sets.on_entry);
|
||||
}
|
||||
|
||||
for (bb, data) in self.mir.basic_blocks().iter_enumerated() {
|
||||
for (bb, data) in self.body.basic_blocks().iter_enumerated() {
|
||||
let &mir::BasicBlockData { ref statements, ref terminator, is_cleanup: _ } = data;
|
||||
|
||||
let mut interim_state;
|
||||
|
@ -231,10 +231,10 @@ impl<'b, 'a: 'b, 'tcx: 'a, BD> PropagationContext<'b, 'a, 'tcx, BD> where BD: Bi
|
|||
{
|
||||
fn walk_cfg(&mut self, in_out: &mut BitSet<BD::Idx>) {
|
||||
let mut dirty_queue: WorkQueue<mir::BasicBlock> =
|
||||
WorkQueue::with_all(self.builder.mir.basic_blocks().len());
|
||||
let mir = self.builder.mir;
|
||||
WorkQueue::with_all(self.builder.body.basic_blocks().len());
|
||||
let body = self.builder.body;
|
||||
while let Some(bb) = dirty_queue.pop() {
|
||||
let bb_data = &mir[bb];
|
||||
let bb_data = &body[bb];
|
||||
{
|
||||
let sets = self.builder.flow_state.sets.for_block(bb.index());
|
||||
debug_assert!(in_out.words().len() == sets.on_entry.words().len());
|
||||
|
@ -312,7 +312,7 @@ pub(crate) trait DataflowResultsConsumer<'a, 'tcx: 'a> {
|
|||
|
||||
fn analyze_results(&mut self, flow_uninit: &mut Self::FlowState) {
|
||||
let flow = flow_uninit;
|
||||
for (bb, _) in traversal::reverse_postorder(self.mir()) {
|
||||
for (bb, _) in traversal::reverse_postorder(self.body()) {
|
||||
flow.reset_to_entry_of(bb);
|
||||
self.process_basic_block(bb, flow);
|
||||
}
|
||||
|
@ -320,7 +320,7 @@ pub(crate) trait DataflowResultsConsumer<'a, 'tcx: 'a> {
|
|||
|
||||
fn process_basic_block(&mut self, bb: BasicBlock, flow_state: &mut Self::FlowState) {
|
||||
let BasicBlockData { ref statements, ref terminator, is_cleanup: _ } =
|
||||
self.mir()[bb];
|
||||
self.body()[bb];
|
||||
let mut location = Location { block: bb, statement_index: 0 };
|
||||
for stmt in statements.iter() {
|
||||
flow_state.reconstruct_statement_effect(location);
|
||||
|
@ -343,13 +343,13 @@ pub(crate) trait DataflowResultsConsumer<'a, 'tcx: 'a> {
|
|||
|
||||
// Delegated Hooks: Provide access to the MIR and process the flow state.
|
||||
|
||||
fn mir(&self) -> &'a Body<'tcx>;
|
||||
fn body(&self) -> &'a Body<'tcx>;
|
||||
}
|
||||
|
||||
pub fn state_for_location<'tcx, T: BitDenotation<'tcx>>(loc: Location,
|
||||
analysis: &T,
|
||||
result: &DataflowResults<'tcx, T>,
|
||||
mir: &Body<'tcx>)
|
||||
body: &Body<'tcx>)
|
||||
-> BitSet<T::Idx> {
|
||||
let mut on_entry = result.sets().on_entry_set_for(loc.block.index()).to_owned();
|
||||
let mut kill_set = on_entry.to_hybrid();
|
||||
|
@ -370,7 +370,7 @@ pub fn state_for_location<'tcx, T: BitDenotation<'tcx>>(loc: Location,
|
|||
}
|
||||
|
||||
// Apply the pre-statement effect of the statement we're evaluating.
|
||||
if loc.statement_index == mir[loc.block].statements.len() {
|
||||
if loc.statement_index == body[loc.block].statements.len() {
|
||||
analysis.before_terminator_effect(&mut sets, loc);
|
||||
} else {
|
||||
analysis.before_statement_effect(&mut sets, loc);
|
||||
|
@ -384,7 +384,7 @@ pub struct DataflowAnalysis<'a, 'tcx: 'a, O> where O: BitDenotation<'tcx>
|
|||
{
|
||||
flow_state: DataflowState<'tcx, O>,
|
||||
dead_unwinds: &'a BitSet<mir::BasicBlock>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx: 'a, O> DataflowAnalysis<'a, 'tcx, O> where O: BitDenotation<'tcx>
|
||||
|
@ -393,7 +393,7 @@ impl<'a, 'tcx: 'a, O> DataflowAnalysis<'a, 'tcx, O> where O: BitDenotation<'tcx>
|
|||
DataflowResults(self.flow_state)
|
||||
}
|
||||
|
||||
pub fn mir(&self) -> &'a Body<'tcx> { self.mir }
|
||||
pub fn body(&self) -> &'a Body<'tcx> { self.body }
|
||||
}
|
||||
|
||||
pub struct DataflowResults<'tcx, O>(pub(crate) DataflowState<'tcx, O>) where O: BitDenotation<'tcx>;
|
||||
|
@ -697,11 +697,11 @@ pub trait BitDenotation<'tcx>: BitSetOperator {
|
|||
|
||||
impl<'a, 'tcx, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation<'tcx>
|
||||
{
|
||||
pub fn new(mir: &'a Body<'tcx>,
|
||||
pub fn new(body: &'a Body<'tcx>,
|
||||
dead_unwinds: &'a BitSet<mir::BasicBlock>,
|
||||
denotation: D) -> Self where D: InitialFlow {
|
||||
let bits_per_block = denotation.bits_per_block();
|
||||
let num_blocks = mir.basic_blocks().len();
|
||||
let num_blocks = body.basic_blocks().len();
|
||||
|
||||
let on_entry_sets = if D::bottom_value() {
|
||||
vec![BitSet::new_filled(bits_per_block); num_blocks]
|
||||
|
@ -712,7 +712,7 @@ impl<'a, 'tcx, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation<'tcx>
|
|||
let kill_sets = gen_sets.clone();
|
||||
|
||||
DataflowAnalysis {
|
||||
mir,
|
||||
body,
|
||||
dead_unwinds,
|
||||
flow_state: DataflowState {
|
||||
sets: AllSets {
|
||||
|
|
|
@ -13,27 +13,27 @@ use super::{MoveError, InitIndex, Init, InitLocation, LookupResult, InitKind};
|
|||
use super::IllegalMoveOriginKind::*;
|
||||
|
||||
struct MoveDataBuilder<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
data: MoveData<'tcx>,
|
||||
errors: Vec<(Place<'tcx>, MoveError<'tcx>)>,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> {
|
||||
fn new(mir: &'a Body<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Self {
|
||||
fn new(body: &'a Body<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Self {
|
||||
let mut move_paths = IndexVec::new();
|
||||
let mut path_map = IndexVec::new();
|
||||
let mut init_path_map = IndexVec::new();
|
||||
|
||||
MoveDataBuilder {
|
||||
mir,
|
||||
body,
|
||||
tcx,
|
||||
errors: Vec::new(),
|
||||
data: MoveData {
|
||||
moves: IndexVec::new(),
|
||||
loc_map: LocationMap::new(mir),
|
||||
loc_map: LocationMap::new(body),
|
||||
rev_lookup: MovePathLookup {
|
||||
locals: mir.local_decls.indices().map(PlaceBase::Local).map(|v| {
|
||||
locals: body.local_decls.indices().map(PlaceBase::Local).map(|v| {
|
||||
Self::new_move_path(
|
||||
&mut move_paths,
|
||||
&mut path_map,
|
||||
|
@ -47,7 +47,7 @@ impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> {
|
|||
move_paths,
|
||||
path_map,
|
||||
inits: IndexVec::new(),
|
||||
init_loc_map: LocationMap::new(mir),
|
||||
init_loc_map: LocationMap::new(body),
|
||||
init_path_map,
|
||||
}
|
||||
}
|
||||
|
@ -104,9 +104,9 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
|
|||
};
|
||||
|
||||
for proj in place_projection {
|
||||
let mir = self.builder.mir;
|
||||
let body = self.builder.body;
|
||||
let tcx = self.builder.tcx;
|
||||
let place_ty = proj.base.ty(mir, tcx).ty;
|
||||
let place_ty = proj.base.ty(body, tcx).ty;
|
||||
match place_ty.sty {
|
||||
ty::Ref(..) | ty::RawPtr(..) =>
|
||||
return Err(MoveError::cannot_move_out_of(
|
||||
|
@ -183,11 +183,11 @@ impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> {
|
|||
self
|
||||
) -> Result<MoveData<'tcx>, (MoveData<'tcx>, Vec<(Place<'tcx>, MoveError<'tcx>)>)> {
|
||||
debug!("{}", {
|
||||
debug!("moves for {:?}:", self.mir.span);
|
||||
debug!("moves for {:?}:", self.body.span);
|
||||
for (j, mo) in self.data.moves.iter_enumerated() {
|
||||
debug!(" {:?} = {:?}", j, mo);
|
||||
}
|
||||
debug!("move paths for {:?}:", self.mir.span);
|
||||
debug!("move paths for {:?}:", self.body.span);
|
||||
for (j, path) in self.data.move_paths.iter_enumerated() {
|
||||
debug!(" {:?} = {:?}", j, path);
|
||||
}
|
||||
|
@ -203,14 +203,14 @@ impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
pub(super) fn gather_moves<'a, 'gcx, 'tcx>(
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>
|
||||
) -> Result<MoveData<'tcx>, (MoveData<'tcx>, Vec<(Place<'tcx>, MoveError<'tcx>)>)> {
|
||||
let mut builder = MoveDataBuilder::new(mir, tcx);
|
||||
let mut builder = MoveDataBuilder::new(body, tcx);
|
||||
|
||||
builder.gather_args();
|
||||
|
||||
for (bb, block) in mir.basic_blocks().iter_enumerated() {
|
||||
for (bb, block) in body.basic_blocks().iter_enumerated() {
|
||||
for (i, stmt) in block.statements.iter().enumerate() {
|
||||
let source = Location { block: bb, statement_index: i };
|
||||
builder.gather_statement(source, stmt);
|
||||
|
@ -228,7 +228,7 @@ pub(super) fn gather_moves<'a, 'gcx, 'tcx>(
|
|||
|
||||
impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> {
|
||||
fn gather_args(&mut self) {
|
||||
for arg in self.mir.args_iter() {
|
||||
for arg in self.body.args_iter() {
|
||||
let path = self.data.rev_lookup.locals[arg];
|
||||
|
||||
let init = self.data.inits.push(Init {
|
||||
|
@ -429,7 +429,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
|
|||
Place::Projection(box Projection {
|
||||
base,
|
||||
elem: ProjectionElem::Field(_, _),
|
||||
}) if match base.ty(self.builder.mir, self.builder.tcx).ty.sty {
|
||||
}) if match base.ty(self.builder.body, self.builder.tcx).ty.sty {
|
||||
ty::Adt(def, _) if def.is_union() => true,
|
||||
_ => false,
|
||||
} => base,
|
||||
|
|
|
@ -138,9 +138,9 @@ impl<T> IndexMut<Location> for LocationMap<T> {
|
|||
}
|
||||
|
||||
impl<T> LocationMap<T> where T: Default + Clone {
|
||||
fn new(mir: &Body<'_>) -> Self {
|
||||
fn new(body: &Body<'_>) -> Self {
|
||||
LocationMap {
|
||||
map: mir.basic_blocks().iter().map(|block| {
|
||||
map: body.basic_blocks().iter().map(|block| {
|
||||
vec![T::default(); block.statements.len()+1]
|
||||
}).collect()
|
||||
}
|
||||
|
@ -205,10 +205,10 @@ impl fmt::Debug for Init {
|
|||
}
|
||||
|
||||
impl Init {
|
||||
crate fn span<'gcx>(&self, mir: &Body<'gcx>) -> Span {
|
||||
crate fn span<'gcx>(&self, body: &Body<'gcx>) -> Span {
|
||||
match self.location {
|
||||
InitLocation::Argument(local) => mir.local_decls[local].source_info.span,
|
||||
InitLocation::Statement(location) => mir.source_info(location).span,
|
||||
InitLocation::Argument(local) => body.local_decls[local].source_info.span,
|
||||
InitLocation::Statement(location) => body.source_info(location).span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -306,9 +306,9 @@ impl<'tcx> MoveError<'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> MoveData<'tcx> {
|
||||
pub fn gather_moves(mir: &Body<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>)
|
||||
pub fn gather_moves(body: &Body<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>)
|
||||
-> Result<Self, (Self, Vec<(Place<'tcx>, MoveError<'tcx>)>)> {
|
||||
builder::gather_moves(mir, tcx)
|
||||
builder::gather_moves(body, tcx)
|
||||
}
|
||||
|
||||
/// For the move path `mpi`, returns the root local variable (if any) that starts the path.
|
||||
|
|
|
@ -56,7 +56,7 @@ pub struct Frame<'mir, 'tcx: 'mir, Tag=(), Extra=()> {
|
|||
// Function and callsite information
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// The MIR for the function called on this frame.
|
||||
pub mir: &'mir mir::Body<'tcx>,
|
||||
pub body: &'mir mir::Body<'tcx>,
|
||||
|
||||
/// The def_id and substs of the current function.
|
||||
pub instance: ty::Instance<'tcx>,
|
||||
|
@ -252,8 +252,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(super) fn mir(&self) -> &'mir mir::Body<'tcx> {
|
||||
self.frame().mir
|
||||
pub(super) fn body(&self) -> &'mir mir::Body<'tcx> {
|
||||
self.frame().body
|
||||
}
|
||||
|
||||
pub(super) fn subst_and_normalize_erasing_regions<T: TypeFoldable<'tcx>>(
|
||||
|
@ -356,7 +356,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
|
|||
match frame.locals[local].layout.get() {
|
||||
None => {
|
||||
let layout = crate::interpret::operand::from_known_layout(layout, || {
|
||||
let local_ty = frame.mir.local_decls[local].ty;
|
||||
let local_ty = frame.body.local_decls[local].ty;
|
||||
let local_ty = self.monomorphize_with_substs(local_ty, frame.instance.substs);
|
||||
self.layout_of(local_ty)
|
||||
})?;
|
||||
|
@ -475,7 +475,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
|
|||
&mut self,
|
||||
instance: ty::Instance<'tcx>,
|
||||
span: source_map::Span,
|
||||
mir: &'mir mir::Body<'tcx>,
|
||||
body: &'mir mir::Body<'tcx>,
|
||||
return_place: Option<PlaceTy<'tcx, M::PointerTag>>,
|
||||
return_to_block: StackPopCleanup,
|
||||
) -> InterpResult<'tcx> {
|
||||
|
@ -487,7 +487,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
|
|||
// first push a stack frame so we have access to the local substs
|
||||
let extra = M::stack_push(self)?;
|
||||
self.stack.push(Frame {
|
||||
mir,
|
||||
body,
|
||||
block: mir::START_BLOCK,
|
||||
return_to_block,
|
||||
return_place,
|
||||
|
@ -501,13 +501,13 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
|
|||
});
|
||||
|
||||
// don't allocate at all for trivial constants
|
||||
if mir.local_decls.len() > 1 {
|
||||
if body.local_decls.len() > 1 {
|
||||
// Locals are initially uninitialized.
|
||||
let dummy = LocalState {
|
||||
value: LocalValue::Uninitialized,
|
||||
layout: Cell::new(None),
|
||||
};
|
||||
let mut locals = IndexVec::from_elem(dummy, &mir.local_decls);
|
||||
let mut locals = IndexVec::from_elem(dummy, &body.local_decls);
|
||||
// Return place is handled specially by the `eval_place` functions, and the
|
||||
// entry in `locals` should never be used. Make it dead, to be sure.
|
||||
locals[mir::RETURN_PLACE].value = LocalValue::Dead;
|
||||
|
@ -518,8 +518,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
|
|||
| Some(DefKind::Const)
|
||||
| Some(DefKind::AssocConst) => {},
|
||||
_ => {
|
||||
trace!("push_stack_frame: {:?}: num_bbs: {}", span, mir.basic_blocks().len());
|
||||
for block in mir.basic_blocks() {
|
||||
trace!("push_stack_frame: {:?}: num_bbs: {}", span, body.basic_blocks().len());
|
||||
for block in body.basic_blocks() {
|
||||
for stmt in block.statements.iter() {
|
||||
use rustc::mir::StatementKind::{StorageDead, StorageLive};
|
||||
match stmt.kind {
|
||||
|
@ -734,7 +734,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
|
|||
pub fn generate_stacktrace(&self, explicit_span: Option<Span>) -> Vec<FrameInfo<'tcx>> {
|
||||
let mut last_span = None;
|
||||
let mut frames = Vec::new();
|
||||
for &Frame { instance, span, mir, block, stmt, .. } in self.stack().iter().rev() {
|
||||
for &Frame { instance, span, body, block, stmt, .. } in self.stack().iter().rev() {
|
||||
// make sure we don't emit frames that are duplicates of the previous
|
||||
if explicit_span == Some(span) {
|
||||
last_span = Some(span);
|
||||
|
@ -747,13 +747,13 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
|
|||
} else {
|
||||
last_span = Some(span);
|
||||
}
|
||||
let block = &mir.basic_blocks()[block];
|
||||
let block = &body.basic_blocks()[block];
|
||||
let source_info = if stmt < block.statements.len() {
|
||||
block.statements[stmt].source_info
|
||||
} else {
|
||||
block.terminator().source_info
|
||||
};
|
||||
let lint_root = match mir.source_scope_local_data {
|
||||
let lint_root = match body.source_scope_local_data {
|
||||
mir::ClearCrossCrate::Set(ref ivs) => Some(ivs[source_info.scope].lint_root),
|
||||
mir::ClearCrossCrate::Clear => None,
|
||||
};
|
||||
|
|
|
@ -612,7 +612,7 @@ where
|
|||
PlaceTy {
|
||||
place: *return_place,
|
||||
layout: self
|
||||
.layout_of(self.monomorphize(self.frame().mir.return_ty())?)?,
|
||||
.layout_of(self.monomorphize(self.frame().body.return_ty())?)?,
|
||||
}
|
||||
}
|
||||
None => return err!(InvalidNullPointerUsage),
|
||||
|
|
|
@ -316,7 +316,7 @@ struct FrameSnapshot<'a, 'tcx: 'a> {
|
|||
}
|
||||
|
||||
impl_stable_hash_for!(impl<'mir, 'tcx: 'mir> for struct Frame<'mir, 'tcx> {
|
||||
mir,
|
||||
body,
|
||||
instance,
|
||||
span,
|
||||
return_to_block,
|
||||
|
@ -334,7 +334,7 @@ impl<'a, 'mir, 'tcx, Ctx> Snapshot<'a, Ctx> for &'a Frame<'mir, 'tcx>
|
|||
|
||||
fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
|
||||
let Frame {
|
||||
mir: _,
|
||||
body: _,
|
||||
instance,
|
||||
span,
|
||||
return_to_block,
|
||||
|
|
|
@ -51,8 +51,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
|
|||
|
||||
let block = self.frame().block;
|
||||
let stmt_id = self.frame().stmt;
|
||||
let mir = self.mir();
|
||||
let basic_block = &mir.basic_blocks()[block];
|
||||
let body = self.body();
|
||||
let basic_block = &body.basic_blocks()[block];
|
||||
|
||||
let old_frames = self.cur_frame();
|
||||
|
||||
|
|
|
@ -281,15 +281,15 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
|
|||
}
|
||||
|
||||
// We need MIR for this fn
|
||||
let mir = match M::find_fn(self, instance, args, dest, ret)? {
|
||||
Some(mir) => mir,
|
||||
let body = match M::find_fn(self, instance, args, dest, ret)? {
|
||||
Some(body) => body,
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
||||
self.push_stack_frame(
|
||||
instance,
|
||||
span,
|
||||
mir,
|
||||
body,
|
||||
dest,
|
||||
StackPopCleanup::Goto(ret),
|
||||
)?;
|
||||
|
@ -307,8 +307,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
|
|||
);
|
||||
trace!(
|
||||
"spread_arg: {:?}, locals: {:#?}",
|
||||
mir.spread_arg,
|
||||
mir.args_iter()
|
||||
body.spread_arg,
|
||||
body.args_iter()
|
||||
.map(|local|
|
||||
(local, self.layout_of_local(self.frame(), local, None).unwrap().ty)
|
||||
)
|
||||
|
@ -352,12 +352,12 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
|
|||
// this is a single iterator (that handles `spread_arg`), then
|
||||
// `pass_argument` would be the loop body. It takes care to
|
||||
// not advance `caller_iter` for ZSTs.
|
||||
let mut locals_iter = mir.args_iter();
|
||||
let mut locals_iter = body.args_iter();
|
||||
while let Some(local) = locals_iter.next() {
|
||||
let dest = self.eval_place(
|
||||
&mir::Place::Base(mir::PlaceBase::Local(local))
|
||||
)?;
|
||||
if Some(local) == mir.spread_arg {
|
||||
if Some(local) == body.spread_arg {
|
||||
// Must be a tuple
|
||||
for i in 0..dest.layout.fields.count() {
|
||||
let dest = self.place_field(dest, i as u64)?;
|
||||
|
|
|
@ -8,18 +8,18 @@ use rustc::ty::{self, AssocItem, AssocItemContainer, Instance, TyCtxt};
|
|||
use rustc::ty::subst::InternalSubsts;
|
||||
|
||||
pub fn check(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
def_id: DefId) {
|
||||
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
|
||||
|
||||
if let Some(fn_like_node) = FnLikeNode::from_node(tcx.hir().get_by_hir_id(hir_id)) {
|
||||
check_fn_for_unconditional_recursion(tcx, fn_like_node.kind(), mir, def_id);
|
||||
check_fn_for_unconditional_recursion(tcx, fn_like_node.kind(), body, def_id);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_fn_for_unconditional_recursion(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
fn_kind: FnKind<'_>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
def_id: DefId) {
|
||||
if let FnKind::Closure(_) = fn_kind {
|
||||
// closures can't recur, so they don't matter.
|
||||
|
@ -54,7 +54,7 @@ fn check_fn_for_unconditional_recursion(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
// to have behaviour like the above, rather than
|
||||
// e.g., accidentally recursing after an assert.
|
||||
|
||||
let basic_blocks = mir.basic_blocks();
|
||||
let basic_blocks = body.basic_blocks();
|
||||
let mut reachable_without_self_call_queue = vec![mir::START_BLOCK];
|
||||
let mut reached_exit_without_self_call = false;
|
||||
let mut self_call_locations = vec![];
|
||||
|
@ -84,7 +84,7 @@ fn check_fn_for_unconditional_recursion(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
if let Some(ref terminator) = block.terminator {
|
||||
match terminator.kind {
|
||||
TerminatorKind::Call { ref func, .. } => {
|
||||
let func_ty = func.ty(mir, tcx);
|
||||
let func_ty = func.ty(body, tcx);
|
||||
|
||||
if let ty::FnDef(fn_def_id, substs) = func_ty.sty {
|
||||
let (call_fn_id, call_substs) =
|
||||
|
|
|
@ -516,7 +516,7 @@ fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
|
||||
struct MirNeighborCollector<'a, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &'a mir::Body<'tcx>,
|
||||
body: &'a mir::Body<'tcx>,
|
||||
output: &'a mut Vec<MonoItem<'tcx>>,
|
||||
param_substs: SubstsRef<'tcx>,
|
||||
}
|
||||
|
@ -538,7 +538,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
|||
ty::ParamEnv::reveal_all(),
|
||||
&target_ty,
|
||||
);
|
||||
let source_ty = operand.ty(self.mir, self.tcx);
|
||||
let source_ty = operand.ty(self.body, self.tcx);
|
||||
let source_ty = self.tcx.subst_and_normalize_erasing_regions(
|
||||
self.param_substs,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
|
@ -560,7 +560,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
|||
mir::Rvalue::Cast(
|
||||
mir::CastKind::Pointer(PointerCast::ReifyFnPointer), ref operand, _
|
||||
) => {
|
||||
let fn_ty = operand.ty(self.mir, self.tcx);
|
||||
let fn_ty = operand.ty(self.body, self.tcx);
|
||||
let fn_ty = self.tcx.subst_and_normalize_erasing_regions(
|
||||
self.param_substs,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
|
@ -571,7 +571,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
|||
mir::Rvalue::Cast(
|
||||
mir::CastKind::Pointer(PointerCast::ClosureFnPointer(_)), ref operand, _
|
||||
) => {
|
||||
let source_ty = operand.ty(self.mir, self.tcx);
|
||||
let source_ty = operand.ty(self.body, self.tcx);
|
||||
let source_ty = self.tcx.subst_and_normalize_erasing_regions(
|
||||
self.param_substs,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
|
@ -621,7 +621,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
|||
let tcx = self.tcx;
|
||||
match *kind {
|
||||
mir::TerminatorKind::Call { ref func, .. } => {
|
||||
let callee_ty = func.ty(self.mir, tcx);
|
||||
let callee_ty = func.ty(self.body, tcx);
|
||||
let callee_ty = tcx.subst_and_normalize_erasing_regions(
|
||||
self.param_substs,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
|
@ -631,7 +631,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
|||
}
|
||||
mir::TerminatorKind::Drop { ref location, .. } |
|
||||
mir::TerminatorKind::DropAndReplace { ref location, .. } => {
|
||||
let ty = location.ty(self.mir, self.tcx).ty;
|
||||
let ty = location.ty(self.body, self.tcx).ty;
|
||||
let ty = tcx.subst_and_normalize_erasing_regions(
|
||||
self.param_substs,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
|
@ -1211,16 +1211,16 @@ fn collect_neighbours<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
instance: Instance<'tcx>,
|
||||
output: &mut Vec<MonoItem<'tcx>>)
|
||||
{
|
||||
let mir = tcx.instance_mir(instance.def);
|
||||
let body = tcx.instance_mir(instance.def);
|
||||
|
||||
MirNeighborCollector {
|
||||
tcx,
|
||||
mir: &mir,
|
||||
body: &body,
|
||||
output,
|
||||
param_substs: instance.substs,
|
||||
}.visit_body(&mir);
|
||||
}.visit_body(&body);
|
||||
let param_env = ty::ParamEnv::reveal_all();
|
||||
for i in 0..mir.promoted.len() {
|
||||
for i in 0..body.promoted.len() {
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
let i = Promoted::new(i);
|
||||
let cid = GlobalId {
|
||||
|
@ -1231,7 +1231,7 @@ fn collect_neighbours<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
Ok(val) => collect_const(tcx, val, instance.substs, output),
|
||||
Err(ErrorHandled::Reported) => {},
|
||||
Err(ErrorHandled::TooGeneric) => span_bug!(
|
||||
mir.promoted[i].span, "collection encountered polymorphic constant",
|
||||
body.promoted[i].span, "collection encountered polymorphic constant",
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,8 +175,8 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
|
||||
// Check if this is a generator, if so, return the drop glue for it
|
||||
if let Some(&ty::TyS { sty: ty::Generator(gen_def_id, substs, _), .. }) = ty {
|
||||
let mir = &**tcx.optimized_mir(gen_def_id).generator_drop.as_ref().unwrap();
|
||||
return mir.subst(tcx, substs.substs);
|
||||
let body = &**tcx.optimized_mir(gen_def_id).generator_drop.as_ref().unwrap();
|
||||
return body.subst(tcx, substs.substs);
|
||||
}
|
||||
|
||||
let substs = if let Some(ty) = ty {
|
||||
|
@ -202,7 +202,7 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
block(&mut blocks, TerminatorKind::Goto { target: return_block });
|
||||
block(&mut blocks, TerminatorKind::Return);
|
||||
|
||||
let mut mir = Body::new(
|
||||
let mut body = Body::new(
|
||||
blocks,
|
||||
IndexVec::from_elem_n(
|
||||
SourceScopeData { span: span, parent_scope: None }, 1
|
||||
|
@ -223,7 +223,7 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
let dropee_ptr = Place::Base(PlaceBase::Local(Local::new(1+0)));
|
||||
if tcx.sess.opts.debugging_opts.mir_emit_retag {
|
||||
// Function arguments should be retagged, and we make this one raw.
|
||||
mir.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
|
||||
body.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
|
||||
source_info,
|
||||
kind: StatementKind::Retag(RetagKind::Raw, dropee_ptr.clone()),
|
||||
});
|
||||
|
@ -231,8 +231,8 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
let patch = {
|
||||
let param_env = tcx.param_env(def_id).with_reveal_all();
|
||||
let mut elaborator = DropShimElaborator {
|
||||
mir: &mir,
|
||||
patch: MirPatch::new(&mir),
|
||||
body: &body,
|
||||
patch: MirPatch::new(&body),
|
||||
tcx,
|
||||
param_env
|
||||
};
|
||||
|
@ -249,14 +249,14 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
);
|
||||
elaborator.patch
|
||||
};
|
||||
patch.apply(&mut mir);
|
||||
patch.apply(&mut body);
|
||||
}
|
||||
|
||||
mir
|
||||
body
|
||||
}
|
||||
|
||||
pub struct DropShimElaborator<'a, 'tcx: 'a> {
|
||||
pub mir: &'a Body<'tcx>,
|
||||
pub body: &'a Body<'tcx>,
|
||||
pub patch: MirPatch<'tcx>,
|
||||
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pub param_env: ty::ParamEnv<'tcx>,
|
||||
|
@ -272,7 +272,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> {
|
|||
type Path = ();
|
||||
|
||||
fn patch(&mut self) -> &mut MirPatch<'tcx> { &mut self.patch }
|
||||
fn mir(&self) -> &'a Body<'tcx> { self.mir }
|
||||
fn body(&self) -> &'a Body<'tcx> { self.body }
|
||||
fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> { self.tcx }
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env }
|
||||
|
||||
|
@ -821,7 +821,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
block(&mut blocks, vec![], TerminatorKind::Resume, true);
|
||||
}
|
||||
|
||||
let mut mir = Body::new(
|
||||
let mut body = Body::new(
|
||||
blocks,
|
||||
IndexVec::from_elem_n(
|
||||
SourceScopeData { span: span, parent_scope: None }, 1
|
||||
|
@ -837,9 +837,9 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
vec![],
|
||||
);
|
||||
if let Abi::RustCall = sig.abi {
|
||||
mir.spread_arg = Some(Local::new(sig.inputs().len()));
|
||||
body.spread_arg = Some(Local::new(sig.inputs().len()));
|
||||
}
|
||||
mir
|
||||
body
|
||||
}
|
||||
|
||||
pub fn build_adt_ctor<'gcx>(tcx: TyCtxt<'_, 'gcx, 'gcx>, ctor_id: DefId) -> &'gcx Body<'gcx> {
|
||||
|
|
|
@ -34,22 +34,22 @@ impl MirPass for AddCallGuards {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_src: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
self.add_call_guards(mir);
|
||||
body: &mut Body<'tcx>) {
|
||||
self.add_call_guards(body);
|
||||
}
|
||||
}
|
||||
|
||||
impl AddCallGuards {
|
||||
pub fn add_call_guards(&self, mir: &mut Body<'_>) {
|
||||
pub fn add_call_guards(&self, body: &mut Body<'_>) {
|
||||
let pred_count: IndexVec<_, _> =
|
||||
mir.predecessors().iter().map(|ps| ps.len()).collect();
|
||||
body.predecessors().iter().map(|ps| ps.len()).collect();
|
||||
|
||||
// We need a place to store the new blocks generated
|
||||
let mut new_blocks = Vec::new();
|
||||
|
||||
let cur_len = mir.basic_blocks().len();
|
||||
let cur_len = body.basic_blocks().len();
|
||||
|
||||
for block in mir.basic_blocks_mut() {
|
||||
for block in body.basic_blocks_mut() {
|
||||
match block.terminator {
|
||||
Some(Terminator {
|
||||
kind: TerminatorKind::Call {
|
||||
|
@ -81,6 +81,6 @@ impl AddCallGuards {
|
|||
|
||||
debug!("Broke {} N edges", new_blocks.len());
|
||||
|
||||
mir.basic_blocks_mut().extend(new_blocks);
|
||||
body.basic_blocks_mut().extend(new_blocks);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,40 +43,40 @@ impl MirPass for AddMovesForPackedDrops {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>)
|
||||
body: &mut Body<'tcx>)
|
||||
{
|
||||
debug!("add_moves_for_packed_drops({:?} @ {:?})", src, mir.span);
|
||||
add_moves_for_packed_drops(tcx, mir, src.def_id());
|
||||
debug!("add_moves_for_packed_drops({:?} @ {:?})", src, body.span);
|
||||
add_moves_for_packed_drops(tcx, body, src.def_id());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_moves_for_packed_drops<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &mut Body<'tcx>,
|
||||
body: &mut Body<'tcx>,
|
||||
def_id: DefId)
|
||||
{
|
||||
let patch = add_moves_for_packed_drops_patch(tcx, mir, def_id);
|
||||
patch.apply(mir);
|
||||
let patch = add_moves_for_packed_drops_patch(tcx, body, def_id);
|
||||
patch.apply(body);
|
||||
}
|
||||
|
||||
fn add_moves_for_packed_drops_patch<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
def_id: DefId)
|
||||
-> MirPatch<'tcx>
|
||||
{
|
||||
let mut patch = MirPatch::new(mir);
|
||||
let mut patch = MirPatch::new(body);
|
||||
let param_env = tcx.param_env(def_id);
|
||||
|
||||
for (bb, data) in mir.basic_blocks().iter_enumerated() {
|
||||
for (bb, data) in body.basic_blocks().iter_enumerated() {
|
||||
let loc = Location { block: bb, statement_index: data.statements.len() };
|
||||
let terminator = data.terminator();
|
||||
|
||||
match terminator.kind {
|
||||
TerminatorKind::Drop { ref location, .. }
|
||||
if util::is_disaligned(tcx, mir, param_env, location) =>
|
||||
if util::is_disaligned(tcx, body, param_env, location) =>
|
||||
{
|
||||
add_move_for_packed_drop(tcx, mir, &mut patch, terminator,
|
||||
add_move_for_packed_drop(tcx, body, &mut patch, terminator,
|
||||
loc, data.is_cleanup);
|
||||
}
|
||||
TerminatorKind::DropAndReplace { .. } => {
|
||||
|
@ -92,7 +92,7 @@ fn add_moves_for_packed_drops_patch<'a, 'tcx>(
|
|||
|
||||
fn add_move_for_packed_drop<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
patch: &mut MirPatch<'tcx>,
|
||||
terminator: &Terminator<'tcx>,
|
||||
loc: Location,
|
||||
|
@ -106,7 +106,7 @@ fn add_move_for_packed_drop<'a, 'tcx>(
|
|||
};
|
||||
|
||||
let source_info = terminator.source_info;
|
||||
let ty = location.ty(mir, tcx).ty;
|
||||
let ty = location.ty(body, tcx).ty;
|
||||
let temp = patch.new_temp(ty, terminator.source_info.span);
|
||||
|
||||
let storage_dead_block = patch.new_block(BasicBlockData {
|
||||
|
|
|
@ -77,13 +77,13 @@ impl MirPass for AddRetag {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_src: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>)
|
||||
body: &mut Body<'tcx>)
|
||||
{
|
||||
if !tcx.sess.opts.debugging_opts.mir_emit_retag {
|
||||
return;
|
||||
}
|
||||
let (span, arg_count) = (mir.span, mir.arg_count);
|
||||
let (basic_blocks, local_decls) = mir.basic_blocks_and_local_decls_mut();
|
||||
let (span, arg_count) = (body.span, body.arg_count);
|
||||
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
|
||||
let needs_retag = |place: &Place<'tcx>| {
|
||||
// FIXME: Instead of giving up for unstable places, we should introduce
|
||||
// a temporary and retag on that.
|
||||
|
|
|
@ -19,7 +19,7 @@ use std::ops::Bound;
|
|||
use crate::util;
|
||||
|
||||
pub struct UnsafetyChecker<'a, 'tcx: 'a> {
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
const_context: bool,
|
||||
min_const_fn: bool,
|
||||
source_scope_local_data: &'a IndexVec<SourceScope, SourceScopeLocalData>,
|
||||
|
@ -36,7 +36,7 @@ impl<'a, 'gcx, 'tcx> UnsafetyChecker<'a, 'tcx> {
|
|||
fn new(
|
||||
const_context: bool,
|
||||
min_const_fn: bool,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
source_scope_local_data: &'a IndexVec<SourceScope, SourceScopeLocalData>,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
|
@ -46,13 +46,13 @@ impl<'a, 'gcx, 'tcx> UnsafetyChecker<'a, 'tcx> {
|
|||
assert!(const_context);
|
||||
}
|
||||
Self {
|
||||
mir,
|
||||
body,
|
||||
const_context,
|
||||
min_const_fn,
|
||||
source_scope_local_data,
|
||||
violations: vec![],
|
||||
source_info: SourceInfo {
|
||||
span: mir.span,
|
||||
span: body.span,
|
||||
scope: OUTERMOST_SOURCE_SCOPE
|
||||
},
|
||||
tcx,
|
||||
|
@ -87,7 +87,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
|||
}
|
||||
|
||||
TerminatorKind::Call { ref func, .. } => {
|
||||
let func_ty = func.ty(self.mir, self.tcx);
|
||||
let func_ty = func.ty(self.body, self.tcx);
|
||||
let sig = func_ty.fn_sig(self.tcx);
|
||||
if let hir::Unsafety::Unsafe = sig.unsafety() {
|
||||
self.require_unsafe("call to unsafe function",
|
||||
|
@ -159,7 +159,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
|||
// pointers during const evaluation have no integral address, only an abstract one
|
||||
Rvalue::Cast(CastKind::Misc, ref operand, cast_ty)
|
||||
if self.const_context && self.tcx.features().const_raw_ptr_to_usize_cast => {
|
||||
let operand_ty = operand.ty(self.mir, self.tcx);
|
||||
let operand_ty = operand.ty(self.body, self.tcx);
|
||||
let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
|
||||
let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
|
||||
match (cast_in, cast_out) {
|
||||
|
@ -182,7 +182,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
|||
// result of a comparison of addresses would differ between runtime and compile-time.
|
||||
Rvalue::BinaryOp(_, ref lhs, _)
|
||||
if self.const_context && self.tcx.features().const_compare_raw_pointers => {
|
||||
if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.mir, self.tcx).sty {
|
||||
if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.body, self.tcx).sty {
|
||||
self.register_violations(&[UnsafetyViolation {
|
||||
source_info: self.source_info,
|
||||
description: InternedString::intern("pointer operation"),
|
||||
|
@ -233,7 +233,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
|||
|
||||
for proj in place_projections {
|
||||
if context.is_borrow() {
|
||||
if util::is_disaligned(self.tcx, self.mir, self.param_env, place) {
|
||||
if util::is_disaligned(self.tcx, self.body, self.param_env, place) {
|
||||
let source_info = self.source_info;
|
||||
let lint_root =
|
||||
self.source_scope_local_data[source_info.scope].lint_root;
|
||||
|
@ -249,7 +249,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
let is_borrow_of_interior_mut = context.is_borrow() && !proj.base
|
||||
.ty(self.mir, self.tcx)
|
||||
.ty(self.body, self.tcx)
|
||||
.ty
|
||||
.is_freeze(self.tcx, self.param_env, self.source_info.span);
|
||||
// prevent
|
||||
|
@ -265,14 +265,14 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
|||
}
|
||||
let old_source_info = self.source_info;
|
||||
if let Place::Base(PlaceBase::Local(local)) = proj.base {
|
||||
if self.mir.local_decls[local].internal {
|
||||
if self.body.local_decls[local].internal {
|
||||
// Internal locals are used in the `move_val_init` desugaring.
|
||||
// We want to check unsafety against the source info of the
|
||||
// desugaring, rather than the source info of the RHS.
|
||||
self.source_info = self.mir.local_decls[local].source_info;
|
||||
self.source_info = self.body.local_decls[local].source_info;
|
||||
}
|
||||
}
|
||||
let base_ty = proj.base.ty(self.mir, self.tcx).ty;
|
||||
let base_ty = proj.base.ty(self.body, self.tcx).ty;
|
||||
match base_ty.sty {
|
||||
ty::RawPtr(..) => {
|
||||
self.require_unsafe("dereference of raw pointer",
|
||||
|
@ -412,7 +412,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
|
|||
}) = place {
|
||||
match *elem {
|
||||
ProjectionElem::Field(..) => {
|
||||
let ty = base.ty(&self.mir.local_decls, self.tcx).ty;
|
||||
let ty = base.ty(&self.body.local_decls, self.tcx).ty;
|
||||
match ty.sty {
|
||||
ty::Adt(def, _) => match self.tcx.layout_scalar_valid_range(def.did) {
|
||||
(Bound::Unbounded, Bound::Unbounded) => {},
|
||||
|
@ -512,9 +512,9 @@ fn unsafety_check_result<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
|
|||
|
||||
// N.B., this borrow is valid because all the consumers of
|
||||
// `mir_built` force this.
|
||||
let mir = &tcx.mir_built(def_id).borrow();
|
||||
let body = &tcx.mir_built(def_id).borrow();
|
||||
|
||||
let source_scope_local_data = match mir.source_scope_local_data {
|
||||
let source_scope_local_data = match body.source_scope_local_data {
|
||||
ClearCrossCrate::Set(ref data) => data,
|
||||
ClearCrossCrate::Clear => {
|
||||
debug!("unsafety_violations: {:?} - remote, skipping", def_id);
|
||||
|
@ -536,8 +536,8 @@ fn unsafety_check_result<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
|
|||
};
|
||||
let mut checker = UnsafetyChecker::new(
|
||||
const_context, min_const_fn,
|
||||
mir, source_scope_local_data, tcx, param_env);
|
||||
checker.visit_body(mir);
|
||||
body, source_scope_local_data, tcx, param_env);
|
||||
checker.visit_body(body);
|
||||
|
||||
check_unused_unsafe(tcx, def_id, &checker.used_unsafe, &mut checker.inherited_blocks);
|
||||
UnsafetyCheckResult {
|
||||
|
|
|
@ -30,9 +30,9 @@ impl MirPass for CleanupNonCodegenStatements {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_source: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
body: &mut Body<'tcx>) {
|
||||
let mut delete = DeleteNonCodegenStatements;
|
||||
delete.visit_body(mir);
|
||||
delete.visit_body(body);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ impl MirPass for ConstProp {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
source: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
body: &mut Body<'tcx>) {
|
||||
// will be evaluated by miri and produce its errors there
|
||||
if source.promoted.is_some() {
|
||||
return;
|
||||
|
@ -63,16 +63,16 @@ impl MirPass for ConstProp {
|
|||
// constants, instead of just checking for const-folding succeeding.
|
||||
// That would require an uniform one-def no-mutation analysis
|
||||
// and RPO (or recursing when needing the value of a local).
|
||||
let mut optimization_finder = ConstPropagator::new(mir, tcx, source);
|
||||
optimization_finder.visit_body(mir);
|
||||
let mut optimization_finder = ConstPropagator::new(body, tcx, source);
|
||||
optimization_finder.visit_body(body);
|
||||
|
||||
// put back the data we stole from `mir`
|
||||
std::mem::replace(
|
||||
&mut mir.source_scope_local_data,
|
||||
&mut body.source_scope_local_data,
|
||||
optimization_finder.source_scope_local_data
|
||||
);
|
||||
std::mem::replace(
|
||||
&mut mir.promoted,
|
||||
&mut body.promoted,
|
||||
optimization_finder.promoted
|
||||
);
|
||||
|
||||
|
@ -120,19 +120,19 @@ impl<'a, 'b, 'tcx> HasTyCtxt<'tcx> for ConstPropagator<'a, 'b, 'tcx> {
|
|||
|
||||
impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
|
||||
fn new(
|
||||
mir: &mut Body<'tcx>,
|
||||
body: &mut Body<'tcx>,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
source: MirSource<'tcx>,
|
||||
) -> ConstPropagator<'a, 'mir, 'tcx> {
|
||||
let param_env = tcx.param_env(source.def_id());
|
||||
let ecx = mk_eval_cx(tcx, tcx.def_span(source.def_id()), param_env);
|
||||
let can_const_prop = CanConstProp::check(mir);
|
||||
let can_const_prop = CanConstProp::check(body);
|
||||
let source_scope_local_data = std::mem::replace(
|
||||
&mut mir.source_scope_local_data,
|
||||
&mut body.source_scope_local_data,
|
||||
ClearCrossCrate::Clear
|
||||
);
|
||||
let promoted = std::mem::replace(
|
||||
&mut mir.promoted,
|
||||
&mut body.promoted,
|
||||
IndexVec::new()
|
||||
);
|
||||
|
||||
|
@ -142,10 +142,10 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
|
|||
source,
|
||||
param_env,
|
||||
can_const_prop,
|
||||
places: IndexVec::from_elem(None, &mir.local_decls),
|
||||
places: IndexVec::from_elem(None, &body.local_decls),
|
||||
source_scope_local_data,
|
||||
//FIXME(wesleywiser) we can't steal this because `Visitor::super_visit_body()` needs it
|
||||
local_decls: mir.local_decls.clone(),
|
||||
local_decls: body.local_decls.clone(),
|
||||
promoted,
|
||||
}
|
||||
}
|
||||
|
@ -315,8 +315,8 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
|
|||
// cannot use `const_eval` here, because that would require having the MIR
|
||||
// for the current function available, but we're producing said MIR right now
|
||||
let res = self.use_ecx(source_info, |this| {
|
||||
let mir = &this.promoted[*promoted];
|
||||
eval_promoted(this.tcx, cid, mir, this.param_env)
|
||||
let body = &this.promoted[*promoted];
|
||||
eval_promoted(this.tcx, cid, body, this.param_env)
|
||||
})?;
|
||||
trace!("evaluated promoted {:?} to {:?}", promoted, res);
|
||||
res.into()
|
||||
|
@ -613,10 +613,10 @@ struct CanConstProp {
|
|||
|
||||
impl CanConstProp {
|
||||
/// returns true if `local` can be propagated
|
||||
fn check(mir: &Body<'_>) -> IndexVec<Local, bool> {
|
||||
fn check(body: &Body<'_>) -> IndexVec<Local, bool> {
|
||||
let mut cpv = CanConstProp {
|
||||
can_const_prop: IndexVec::from_elem(true, &mir.local_decls),
|
||||
found_assignment: IndexVec::from_elem(false, &mir.local_decls),
|
||||
can_const_prop: IndexVec::from_elem(true, &body.local_decls),
|
||||
found_assignment: IndexVec::from_elem(false, &body.local_decls),
|
||||
};
|
||||
for (local, val) in cpv.can_const_prop.iter_enumerated_mut() {
|
||||
// cannot use args at all
|
||||
|
@ -624,13 +624,13 @@ impl CanConstProp {
|
|||
// lint for x != y
|
||||
// FIXME(oli-obk): lint variables until they are used in a condition
|
||||
// FIXME(oli-obk): lint if return value is constant
|
||||
*val = mir.local_kind(local) == LocalKind::Temp;
|
||||
*val = body.local_kind(local) == LocalKind::Temp;
|
||||
|
||||
if !*val {
|
||||
trace!("local {:?} can't be propagated because it's not a temporary", local);
|
||||
}
|
||||
}
|
||||
cpv.visit_body(mir);
|
||||
cpv.visit_body(body);
|
||||
cpv.can_const_prop
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,23 +33,23 @@ impl MirPass for CopyPropagation {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_source: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
body: &mut Body<'tcx>) {
|
||||
// We only run when the MIR optimization level is > 1.
|
||||
// This avoids a slow pass, and messing up debug info.
|
||||
if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut def_use_analysis = DefUseAnalysis::new(mir);
|
||||
let mut def_use_analysis = DefUseAnalysis::new(body);
|
||||
loop {
|
||||
def_use_analysis.analyze(mir);
|
||||
def_use_analysis.analyze(body);
|
||||
|
||||
if eliminate_self_assignments(mir, &def_use_analysis) {
|
||||
def_use_analysis.analyze(mir);
|
||||
if eliminate_self_assignments(body, &def_use_analysis) {
|
||||
def_use_analysis.analyze(body);
|
||||
}
|
||||
|
||||
let mut changed = false;
|
||||
for dest_local in mir.local_decls.indices() {
|
||||
for dest_local in body.local_decls.indices() {
|
||||
debug!("Considering destination local: {:?}", dest_local);
|
||||
|
||||
let action;
|
||||
|
@ -76,7 +76,7 @@ impl MirPass for CopyPropagation {
|
|||
}
|
||||
// Conservatively gives up if the dest is an argument,
|
||||
// because there may be uses of the original argument value.
|
||||
if mir.local_kind(dest_local) == LocalKind::Arg {
|
||||
if body.local_kind(dest_local) == LocalKind::Arg {
|
||||
debug!(" Can't copy-propagate local: dest {:?} (argument)",
|
||||
dest_local);
|
||||
continue;
|
||||
|
@ -84,7 +84,7 @@ impl MirPass for CopyPropagation {
|
|||
let dest_place_def = dest_use_info.defs_not_including_drop().next().unwrap();
|
||||
location = dest_place_def.location;
|
||||
|
||||
let basic_block = &mir[location.block];
|
||||
let basic_block = &body[location.block];
|
||||
let statement_index = location.statement_index;
|
||||
let statement = match basic_block.statements.get(statement_index) {
|
||||
Some(statement) => statement,
|
||||
|
@ -103,7 +103,7 @@ impl MirPass for CopyPropagation {
|
|||
let maybe_action = match *operand {
|
||||
Operand::Copy(ref src_place) |
|
||||
Operand::Move(ref src_place) => {
|
||||
Action::local_copy(&mir, &def_use_analysis, src_place)
|
||||
Action::local_copy(&body, &def_use_analysis, src_place)
|
||||
}
|
||||
Operand::Constant(ref src_constant) => {
|
||||
Action::constant(src_constant)
|
||||
|
@ -122,7 +122,7 @@ impl MirPass for CopyPropagation {
|
|||
}
|
||||
}
|
||||
|
||||
changed = action.perform(mir, &def_use_analysis, dest_local, location) || changed;
|
||||
changed = action.perform(body, &def_use_analysis, dest_local, location) || changed;
|
||||
// FIXME(pcwalton): Update the use-def chains to delete the instructions instead of
|
||||
// regenerating the chains.
|
||||
break
|
||||
|
@ -135,17 +135,17 @@ impl MirPass for CopyPropagation {
|
|||
}
|
||||
|
||||
fn eliminate_self_assignments(
|
||||
mir: &mut Body<'_>,
|
||||
body: &mut Body<'_>,
|
||||
def_use_analysis: &DefUseAnalysis,
|
||||
) -> bool {
|
||||
let mut changed = false;
|
||||
|
||||
for dest_local in mir.local_decls.indices() {
|
||||
for dest_local in body.local_decls.indices() {
|
||||
let dest_use_info = def_use_analysis.local_info(dest_local);
|
||||
|
||||
for def in dest_use_info.defs_not_including_drop() {
|
||||
let location = def.location;
|
||||
if let Some(stmt) = mir[location.block].statements.get(location.statement_index) {
|
||||
if let Some(stmt) = body[location.block].statements.get(location.statement_index) {
|
||||
match stmt.kind {
|
||||
StatementKind::Assign(
|
||||
Place::Base(PlaceBase::Local(local)),
|
||||
|
@ -163,7 +163,7 @@ fn eliminate_self_assignments(
|
|||
continue;
|
||||
}
|
||||
debug!("Deleting a self-assignment for {:?}", dest_local);
|
||||
mir.make_statement_nop(location);
|
||||
body.make_statement_nop(location);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ enum Action<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Action<'tcx> {
|
||||
fn local_copy(mir: &Body<'tcx>, def_use_analysis: &DefUseAnalysis, src_place: &Place<'tcx>)
|
||||
fn local_copy(body: &Body<'tcx>, def_use_analysis: &DefUseAnalysis, src_place: &Place<'tcx>)
|
||||
-> Option<Action<'tcx>> {
|
||||
// The source must be a local.
|
||||
let src_local = if let Place::Base(PlaceBase::Local(local)) = *src_place {
|
||||
|
@ -214,7 +214,7 @@ impl<'tcx> Action<'tcx> {
|
|||
// USE(SRC);
|
||||
let src_def_count = src_use_info.def_count_not_including_drop();
|
||||
// allow function arguments to be propagated
|
||||
let is_arg = mir.local_kind(src_local) == LocalKind::Arg;
|
||||
let is_arg = body.local_kind(src_local) == LocalKind::Arg;
|
||||
if (is_arg && src_def_count != 0) || (!is_arg && src_def_count != 1) {
|
||||
debug!(
|
||||
" Can't copy-propagate local: {} defs of src{}",
|
||||
|
@ -232,7 +232,7 @@ impl<'tcx> Action<'tcx> {
|
|||
}
|
||||
|
||||
fn perform(self,
|
||||
mir: &mut Body<'tcx>,
|
||||
body: &mut Body<'tcx>,
|
||||
def_use_analysis: &DefUseAnalysis,
|
||||
dest_local: Local,
|
||||
location: Location)
|
||||
|
@ -249,21 +249,21 @@ impl<'tcx> Action<'tcx> {
|
|||
src_local);
|
||||
for place_use in &def_use_analysis.local_info(dest_local).defs_and_uses {
|
||||
if place_use.context.is_storage_marker() {
|
||||
mir.make_statement_nop(place_use.location)
|
||||
body.make_statement_nop(place_use.location)
|
||||
}
|
||||
}
|
||||
for place_use in &def_use_analysis.local_info(src_local).defs_and_uses {
|
||||
if place_use.context.is_storage_marker() {
|
||||
mir.make_statement_nop(place_use.location)
|
||||
body.make_statement_nop(place_use.location)
|
||||
}
|
||||
}
|
||||
|
||||
// Replace all uses of the destination local with the source local.
|
||||
def_use_analysis.replace_all_defs_and_uses_with(dest_local, mir, src_local);
|
||||
def_use_analysis.replace_all_defs_and_uses_with(dest_local, body, src_local);
|
||||
|
||||
// Finally, zap the now-useless assignment instruction.
|
||||
debug!(" Deleting assignment");
|
||||
mir.make_statement_nop(location);
|
||||
body.make_statement_nop(location);
|
||||
|
||||
true
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ impl<'tcx> Action<'tcx> {
|
|||
let dest_local_info = def_use_analysis.local_info(dest_local);
|
||||
for place_use in &dest_local_info.defs_and_uses {
|
||||
if place_use.context.is_storage_marker() {
|
||||
mir.make_statement_nop(place_use.location)
|
||||
body.make_statement_nop(place_use.location)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -285,7 +285,7 @@ impl<'tcx> Action<'tcx> {
|
|||
let mut visitor = ConstantPropagationVisitor::new(dest_local,
|
||||
src_constant);
|
||||
for dest_place_use in &dest_local_info.defs_and_uses {
|
||||
visitor.visit_location(mir, dest_place_use.location)
|
||||
visitor.visit_location(body, dest_place_use.location)
|
||||
}
|
||||
|
||||
// Zap the assignment instruction if we eliminated all the uses. We won't have been
|
||||
|
@ -296,7 +296,7 @@ impl<'tcx> Action<'tcx> {
|
|||
debug!(" {} of {} use(s) replaced; deleting assignment",
|
||||
visitor.uses_replaced,
|
||||
use_count);
|
||||
mir.make_statement_nop(location);
|
||||
body.make_statement_nop(location);
|
||||
true
|
||||
} else if visitor.uses_replaced == 0 {
|
||||
debug!(" No uses replaced; not deleting assignment");
|
||||
|
|
|
@ -9,8 +9,8 @@ impl MirPass for Deaggregator {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_source: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
let (basic_blocks, local_decls) = mir.basic_blocks_and_local_decls_mut();
|
||||
body: &mut Body<'tcx>) {
|
||||
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
|
||||
let local_decls = &*local_decls;
|
||||
for bb in basic_blocks {
|
||||
bb.expand_statements(|stmt| {
|
||||
|
|
|
@ -21,7 +21,7 @@ impl MirPass for Marker {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_source: MirSource<'tcx>,
|
||||
_mir: &mut Body<'tcx>)
|
||||
_body: &mut Body<'tcx>)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ pub fn on_mir_pass<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
pass_num: &dyn fmt::Display,
|
||||
pass_name: &str,
|
||||
source: MirSource<'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
is_after: bool) {
|
||||
if mir_util::dump_enabled(tcx, pass_name, source) {
|
||||
mir_util::dump_mir(tcx,
|
||||
|
@ -50,7 +50,7 @@ pub fn on_mir_pass<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
pass_name,
|
||||
&Disambiguator { is_after },
|
||||
source,
|
||||
mir,
|
||||
body,
|
||||
|_, _| Ok(()) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,13 +24,13 @@ impl MirPass for ElaborateDrops {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>)
|
||||
body: &mut Body<'tcx>)
|
||||
{
|
||||
debug!("elaborate_drops({:?} @ {:?})", src, mir.span);
|
||||
debug!("elaborate_drops({:?} @ {:?})", src, body.span);
|
||||
|
||||
let def_id = src.def_id();
|
||||
let param_env = tcx.param_env(src.def_id()).with_reveal_all();
|
||||
let move_data = match MoveData::gather_moves(mir, tcx) {
|
||||
let move_data = match MoveData::gather_moves(body, tcx) {
|
||||
Ok(move_data) => move_data,
|
||||
Err((move_data, _move_errors)) => {
|
||||
// The only way we should be allowing any move_errors
|
||||
|
@ -45,32 +45,32 @@ impl MirPass for ElaborateDrops {
|
|||
}
|
||||
};
|
||||
let elaborate_patch = {
|
||||
let mir = &*mir;
|
||||
let body = &*body;
|
||||
let env = MoveDataParamEnv {
|
||||
move_data,
|
||||
param_env,
|
||||
};
|
||||
let dead_unwinds = find_dead_unwinds(tcx, mir, def_id, &env);
|
||||
let dead_unwinds = find_dead_unwinds(tcx, body, def_id, &env);
|
||||
let flow_inits =
|
||||
do_dataflow(tcx, mir, def_id, &[], &dead_unwinds,
|
||||
MaybeInitializedPlaces::new(tcx, mir, &env),
|
||||
do_dataflow(tcx, body, def_id, &[], &dead_unwinds,
|
||||
MaybeInitializedPlaces::new(tcx, body, &env),
|
||||
|bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]));
|
||||
let flow_uninits =
|
||||
do_dataflow(tcx, mir, def_id, &[], &dead_unwinds,
|
||||
MaybeUninitializedPlaces::new(tcx, mir, &env),
|
||||
do_dataflow(tcx, body, def_id, &[], &dead_unwinds,
|
||||
MaybeUninitializedPlaces::new(tcx, body, &env),
|
||||
|bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]));
|
||||
|
||||
ElaborateDropsCtxt {
|
||||
tcx,
|
||||
mir,
|
||||
body,
|
||||
env: &env,
|
||||
flow_inits,
|
||||
flow_uninits,
|
||||
drop_flags: Default::default(),
|
||||
patch: MirPatch::new(mir),
|
||||
patch: MirPatch::new(body),
|
||||
}.elaborate()
|
||||
};
|
||||
elaborate_patch.apply(mir);
|
||||
elaborate_patch.apply(body);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,20 +79,20 @@ impl MirPass for ElaborateDrops {
|
|||
/// that can't drop anything.
|
||||
fn find_dead_unwinds<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
def_id: hir::def_id::DefId,
|
||||
env: &MoveDataParamEnv<'tcx, 'tcx>)
|
||||
-> BitSet<BasicBlock>
|
||||
{
|
||||
debug!("find_dead_unwinds({:?})", mir.span);
|
||||
debug!("find_dead_unwinds({:?})", body.span);
|
||||
// We only need to do this pass once, because unwind edges can only
|
||||
// reach cleanup blocks, which can't have unwind edges themselves.
|
||||
let mut dead_unwinds = BitSet::new_empty(mir.basic_blocks().len());
|
||||
let mut dead_unwinds = BitSet::new_empty(body.basic_blocks().len());
|
||||
let flow_inits =
|
||||
do_dataflow(tcx, mir, def_id, &[], &dead_unwinds,
|
||||
MaybeInitializedPlaces::new(tcx, mir, &env),
|
||||
do_dataflow(tcx, body, def_id, &[], &dead_unwinds,
|
||||
MaybeInitializedPlaces::new(tcx, body, &env),
|
||||
|bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]));
|
||||
for (bb, bb_data) in mir.basic_blocks().iter_enumerated() {
|
||||
for (bb, bb_data) in body.basic_blocks().iter_enumerated() {
|
||||
let location = match bb_data.terminator().kind {
|
||||
TerminatorKind::Drop { ref location, unwind: Some(_), .. } |
|
||||
TerminatorKind::DropAndReplace { ref location, unwind: Some(_), .. } => location,
|
||||
|
@ -107,7 +107,7 @@ fn find_dead_unwinds<'a, 'tcx>(
|
|||
bb, bb_data, init_data.live);
|
||||
for stmt in 0..bb_data.statements.len() {
|
||||
let loc = Location { block: bb, statement_index: stmt };
|
||||
init_data.apply_location(tcx, mir, env, loc);
|
||||
init_data.apply_location(tcx, body, env, loc);
|
||||
}
|
||||
|
||||
let path = match env.move_data.rev_lookup.find(location) {
|
||||
|
@ -121,7 +121,7 @@ fn find_dead_unwinds<'a, 'tcx>(
|
|||
debug!("find_dead_unwinds @ {:?}: path({:?})={:?}", bb, location, path);
|
||||
|
||||
let mut maybe_live = false;
|
||||
on_all_drop_children_bits(tcx, mir, &env, path, |child| {
|
||||
on_all_drop_children_bits(tcx, body, &env, path, |child| {
|
||||
let (child_maybe_live, _) = init_data.state(child);
|
||||
maybe_live |= child_maybe_live;
|
||||
});
|
||||
|
@ -143,11 +143,11 @@ struct InitializationData {
|
|||
impl InitializationData {
|
||||
fn apply_location<'a,'tcx>(&mut self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
env: &MoveDataParamEnv<'tcx, 'tcx>,
|
||||
loc: Location)
|
||||
{
|
||||
drop_flag_effects_for_location(tcx, mir, env, loc, |path, df| {
|
||||
drop_flag_effects_for_location(tcx, body, env, loc, |path, df| {
|
||||
debug!("at location {:?}: setting {:?} to {:?}",
|
||||
loc, path, df);
|
||||
match df {
|
||||
|
@ -186,8 +186,8 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> {
|
|||
&mut self.ctxt.patch
|
||||
}
|
||||
|
||||
fn mir(&self) -> &'a Body<'tcx> {
|
||||
self.ctxt.mir
|
||||
fn body(&self) -> &'a Body<'tcx> {
|
||||
self.ctxt.body
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> {
|
||||
|
@ -206,7 +206,7 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> {
|
|||
let mut some_dead = false;
|
||||
let mut children_count = 0;
|
||||
on_all_drop_children_bits(
|
||||
self.tcx(), self.mir(), self.ctxt.env, path, |child| {
|
||||
self.tcx(), self.body(), self.ctxt.env, path, |child| {
|
||||
let (live, dead) = self.init_data.state(child);
|
||||
debug!("elaborate_drop: state({:?}) = {:?}",
|
||||
child, (live, dead));
|
||||
|
@ -232,7 +232,7 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> {
|
|||
}
|
||||
DropFlagMode::Deep => {
|
||||
on_all_children_bits(
|
||||
self.tcx(), self.mir(), self.ctxt.move_data(), path,
|
||||
self.tcx(), self.body(), self.ctxt.move_data(), path,
|
||||
|child| self.ctxt.set_drop_flag(loc, child, DropFlagState::Absent)
|
||||
);
|
||||
}
|
||||
|
@ -291,7 +291,7 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> {
|
|||
|
||||
struct ElaborateDropsCtxt<'a, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
env: &'a MoveDataParamEnv<'tcx, 'tcx>,
|
||||
flow_inits: DataflowResults<'tcx, MaybeInitializedPlaces<'a, 'tcx, 'tcx>>,
|
||||
flow_uninits: DataflowResults<'tcx, MaybeUninitializedPlaces<'a, 'tcx, 'tcx>>,
|
||||
|
@ -314,7 +314,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||
.to_owned(),
|
||||
};
|
||||
for stmt in 0..loc.statement_index {
|
||||
data.apply_location(self.tcx, self.mir, self.env,
|
||||
data.apply_location(self.tcx, self.body, self.env,
|
||||
Location { block: loc.block, statement_index: stmt });
|
||||
}
|
||||
data
|
||||
|
@ -323,7 +323,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||
fn create_drop_flag(&mut self, index: MovePathIndex, span: Span) {
|
||||
let tcx = self.tcx;
|
||||
let patch = &mut self.patch;
|
||||
debug!("create_drop_flag({:?})", self.mir.span);
|
||||
debug!("create_drop_flag({:?})", self.body.span);
|
||||
self.drop_flags.entry(index).or_insert_with(|| {
|
||||
patch.new_internal(tcx.types.bool, span)
|
||||
});
|
||||
|
@ -351,7 +351,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||
|
||||
fn collect_drop_flags(&mut self)
|
||||
{
|
||||
for (bb, data) in self.mir.basic_blocks().iter_enumerated() {
|
||||
for (bb, data) in self.body.basic_blocks().iter_enumerated() {
|
||||
let terminator = data.terminator();
|
||||
let location = match terminator.kind {
|
||||
TerminatorKind::Drop { ref location, .. } |
|
||||
|
@ -382,7 +382,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||
}
|
||||
};
|
||||
|
||||
on_all_drop_children_bits(self.tcx, self.mir, self.env, path, |child| {
|
||||
on_all_drop_children_bits(self.tcx, self.body, self.env, path, |child| {
|
||||
let (maybe_live, maybe_dead) = init_data.state(child);
|
||||
debug!("collect_drop_flags: collecting {:?} from {:?}@{:?} - {:?}",
|
||||
child, location, path, (maybe_live, maybe_dead));
|
||||
|
@ -395,7 +395,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||
|
||||
fn elaborate_drops(&mut self)
|
||||
{
|
||||
for (bb, data) in self.mir.basic_blocks().iter_enumerated() {
|
||||
for (bb, data) in self.body.basic_blocks().iter_enumerated() {
|
||||
let loc = Location { block: bb, statement_index: data.statements.len() };
|
||||
let terminator = data.terminator();
|
||||
|
||||
|
@ -464,7 +464,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||
unwind: Option<BasicBlock>)
|
||||
{
|
||||
let bb = loc.block;
|
||||
let data = &self.mir[bb];
|
||||
let data = &self.body[bb];
|
||||
let terminator = data.terminator();
|
||||
assert!(!data.is_cleanup, "DropAndReplace in unwind path not supported");
|
||||
|
||||
|
@ -508,7 +508,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||
target,
|
||||
Unwind::To(unwind),
|
||||
bb);
|
||||
on_all_children_bits(self.tcx, self.mir, self.move_data(), path, |child| {
|
||||
on_all_children_bits(self.tcx, self.body, self.move_data(), path, |child| {
|
||||
self.set_drop_flag(Location { block: target, statement_index: 0 },
|
||||
child, DropFlagState::Present);
|
||||
self.set_drop_flag(Location { block: unwind, statement_index: 0 },
|
||||
|
@ -539,7 +539,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||
|
||||
fn set_drop_flag(&mut self, loc: Location, path: MovePathIndex, val: DropFlagState) {
|
||||
if let Some(&flag) = self.drop_flags.get(&path) {
|
||||
let span = self.patch.source_info_for_location(self.mir, loc).span;
|
||||
let span = self.patch.source_info_for_location(self.body, loc).span;
|
||||
let val = self.constant_bool(span, val.value());
|
||||
self.patch.add_assign(loc, Place::Base(PlaceBase::Local(flag)), val);
|
||||
}
|
||||
|
@ -547,7 +547,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||
|
||||
fn drop_flags_on_init(&mut self) {
|
||||
let loc = Location::START;
|
||||
let span = self.patch.source_info_for_location(self.mir, loc).span;
|
||||
let span = self.patch.source_info_for_location(self.body, loc).span;
|
||||
let false_ = self.constant_bool(span, false);
|
||||
for flag in self.drop_flags.values() {
|
||||
self.patch.add_assign(loc, Place::Base(PlaceBase::Local(*flag)), false_.clone());
|
||||
|
@ -555,7 +555,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||
}
|
||||
|
||||
fn drop_flags_for_fn_rets(&mut self) {
|
||||
for (bb, data) in self.mir.basic_blocks().iter_enumerated() {
|
||||
for (bb, data) in self.body.basic_blocks().iter_enumerated() {
|
||||
if let TerminatorKind::Call {
|
||||
destination: Some((ref place, tgt)), cleanup: Some(_), ..
|
||||
} = data.terminator().kind {
|
||||
|
@ -564,7 +564,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||
let loc = Location { block: tgt, statement_index: 0 };
|
||||
let path = self.move_data().rev_lookup.find(place);
|
||||
on_lookup_result_bits(
|
||||
self.tcx, self.mir, self.move_data(), path,
|
||||
self.tcx, self.body, self.move_data(), path,
|
||||
|child| self.set_drop_flag(loc, child, DropFlagState::Present)
|
||||
);
|
||||
}
|
||||
|
@ -574,7 +574,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||
fn drop_flags_for_args(&mut self) {
|
||||
let loc = Location::START;
|
||||
dataflow::drop_flag_effects_for_function_entry(
|
||||
self.tcx, self.mir, self.env, |path, ds| {
|
||||
self.tcx, self.body, self.env, |path, ds| {
|
||||
self.set_drop_flag(loc, path, ds);
|
||||
}
|
||||
)
|
||||
|
@ -587,7 +587,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||
// drop flags by themselves, to avoid the drop flags being
|
||||
// clobbered before they are read.
|
||||
|
||||
for (bb, data) in self.mir.basic_blocks().iter_enumerated() {
|
||||
for (bb, data) in self.body.basic_blocks().iter_enumerated() {
|
||||
debug!("drop_flags_for_locs({:?})", data);
|
||||
for i in 0..(data.statements.len()+1) {
|
||||
debug!("drop_flag_for_locs: stmt {}", i);
|
||||
|
@ -619,7 +619,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||
}
|
||||
let loc = Location { block: bb, statement_index: i };
|
||||
dataflow::drop_flag_effects_for_location(
|
||||
self.tcx, self.mir, self.env, loc, |path, ds| {
|
||||
self.tcx, self.body, self.env, loc, |path, ds| {
|
||||
if ds == DropFlagState::Absent || allow_initializations {
|
||||
self.set_drop_flag(loc, path, ds)
|
||||
}
|
||||
|
@ -638,7 +638,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
|||
let loc = Location { block: bb, statement_index: data.statements.len() };
|
||||
let path = self.move_data().rev_lookup.find(place);
|
||||
on_lookup_result_bits(
|
||||
self.tcx, self.mir, self.move_data(), path,
|
||||
self.tcx, self.body, self.move_data(), path,
|
||||
|child| self.set_drop_flag(loc, child, DropFlagState::Present)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ impl MirPass for EraseRegions {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
EraseRegionsVisitor::new(tcx).visit_body(mir);
|
||||
body: &mut Body<'tcx>) {
|
||||
EraseRegionsVisitor::new(tcx).visit_body(body);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -218,14 +218,14 @@ impl<'a, 'tcx> TransformVisitor<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// Create a statement which reads the discriminant into a temporary
|
||||
fn get_discr(&self, mir: &mut Body<'tcx>) -> (Statement<'tcx>, Place<'tcx>) {
|
||||
let temp_decl = LocalDecl::new_internal(self.tcx.types.isize, mir.span);
|
||||
let local_decls_len = mir.local_decls.push(temp_decl);
|
||||
fn get_discr(&self, body: &mut Body<'tcx>) -> (Statement<'tcx>, Place<'tcx>) {
|
||||
let temp_decl = LocalDecl::new_internal(self.tcx.types.isize, body.span);
|
||||
let local_decls_len = body.local_decls.push(temp_decl);
|
||||
let temp = Place::Base(PlaceBase::Local(local_decls_len));
|
||||
|
||||
let self_place = Place::Base(PlaceBase::Local(self_arg()));
|
||||
let assign = Statement {
|
||||
source_info: source_info(mir),
|
||||
source_info: source_info(body),
|
||||
kind: StatementKind::Assign(temp.clone(), box Rvalue::Discriminant(self_place)),
|
||||
};
|
||||
(assign, temp)
|
||||
|
@ -312,8 +312,8 @@ impl<'a, 'tcx> MutVisitor<'tcx> for TransformVisitor<'a, 'tcx> {
|
|||
fn make_generator_state_argument_indirect<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
def_id: DefId,
|
||||
mir: &mut Body<'tcx>) {
|
||||
let gen_ty = mir.local_decls.raw[1].ty;
|
||||
body: &mut Body<'tcx>) {
|
||||
let gen_ty = body.local_decls.raw[1].ty;
|
||||
|
||||
let region = ty::ReFree(ty::FreeRegion {
|
||||
scope: def_id,
|
||||
|
@ -328,16 +328,16 @@ fn make_generator_state_argument_indirect<'a, 'tcx>(
|
|||
});
|
||||
|
||||
// Replace the by value generator argument
|
||||
mir.local_decls.raw[1].ty = ref_gen_ty;
|
||||
body.local_decls.raw[1].ty = ref_gen_ty;
|
||||
|
||||
// Add a deref to accesses of the generator state
|
||||
DerefArgVisitor.visit_body(mir);
|
||||
DerefArgVisitor.visit_body(body);
|
||||
}
|
||||
|
||||
fn make_generator_state_argument_pinned<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
let ref_gen_ty = mir.local_decls.raw[1].ty;
|
||||
body: &mut Body<'tcx>) {
|
||||
let ref_gen_ty = body.local_decls.raw[1].ty;
|
||||
|
||||
let pin_did = tcx.lang_items().pin_type().unwrap();
|
||||
let pin_adt_ref = tcx.adt_def(pin_did);
|
||||
|
@ -345,17 +345,17 @@ fn make_generator_state_argument_pinned<'a, 'tcx>(
|
|||
let pin_ref_gen_ty = tcx.mk_adt(pin_adt_ref, substs);
|
||||
|
||||
// Replace the by ref generator argument
|
||||
mir.local_decls.raw[1].ty = pin_ref_gen_ty;
|
||||
body.local_decls.raw[1].ty = pin_ref_gen_ty;
|
||||
|
||||
// Add the Pin field access to accesses of the generator state
|
||||
PinArgVisitor { ref_gen_ty }.visit_body(mir);
|
||||
PinArgVisitor { ref_gen_ty }.visit_body(body);
|
||||
}
|
||||
|
||||
fn replace_result_variable<'tcx>(
|
||||
ret_ty: Ty<'tcx>,
|
||||
mir: &mut Body<'tcx>,
|
||||
body: &mut Body<'tcx>,
|
||||
) -> Local {
|
||||
let source_info = source_info(mir);
|
||||
let source_info = source_info(body);
|
||||
let new_ret = LocalDecl {
|
||||
mutability: Mutability::Mut,
|
||||
ty: ret_ty,
|
||||
|
@ -367,14 +367,14 @@ fn replace_result_variable<'tcx>(
|
|||
is_block_tail: None,
|
||||
is_user_variable: None,
|
||||
};
|
||||
let new_ret_local = Local::new(mir.local_decls.len());
|
||||
mir.local_decls.push(new_ret);
|
||||
mir.local_decls.swap(RETURN_PLACE, new_ret_local);
|
||||
let new_ret_local = Local::new(body.local_decls.len());
|
||||
body.local_decls.push(new_ret);
|
||||
body.local_decls.swap(RETURN_PLACE, new_ret_local);
|
||||
|
||||
RenameLocalVisitor {
|
||||
from: RETURN_PLACE,
|
||||
to: new_ret_local,
|
||||
}.visit_body(mir);
|
||||
}.visit_body(body);
|
||||
|
||||
new_ret_local
|
||||
}
|
||||
|
@ -395,7 +395,7 @@ impl<'tcx> Visitor<'tcx> for StorageIgnored {
|
|||
|
||||
fn locals_live_across_suspend_points(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
source: MirSource<'tcx>,
|
||||
movable: bool,
|
||||
) -> (
|
||||
|
@ -403,52 +403,52 @@ fn locals_live_across_suspend_points(
|
|||
FxHashMap<BasicBlock, liveness::LiveVarSet>,
|
||||
BitSet<BasicBlock>,
|
||||
) {
|
||||
let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len());
|
||||
let dead_unwinds = BitSet::new_empty(body.basic_blocks().len());
|
||||
let def_id = source.def_id();
|
||||
|
||||
// Calculate when MIR locals have live storage. This gives us an upper bound of their
|
||||
// lifetimes.
|
||||
let storage_live_analysis = MaybeStorageLive::new(mir);
|
||||
let storage_live_analysis = MaybeStorageLive::new(body);
|
||||
let storage_live =
|
||||
do_dataflow(tcx, mir, def_id, &[], &dead_unwinds, storage_live_analysis,
|
||||
|bd, p| DebugFormatted::new(&bd.mir().local_decls[p]));
|
||||
do_dataflow(tcx, body, def_id, &[], &dead_unwinds, storage_live_analysis,
|
||||
|bd, p| DebugFormatted::new(&bd.body().local_decls[p]));
|
||||
|
||||
// Find the MIR locals which do not use StorageLive/StorageDead statements.
|
||||
// The storage of these locals are always live.
|
||||
let mut ignored = StorageIgnored(BitSet::new_filled(mir.local_decls.len()));
|
||||
ignored.visit_body(mir);
|
||||
let mut ignored = StorageIgnored(BitSet::new_filled(body.local_decls.len()));
|
||||
ignored.visit_body(body);
|
||||
|
||||
// Calculate the MIR locals which have been previously
|
||||
// borrowed (even if they are still active).
|
||||
// This is only used for immovable generators.
|
||||
let borrowed_locals = if !movable {
|
||||
let analysis = HaveBeenBorrowedLocals::new(mir);
|
||||
let analysis = HaveBeenBorrowedLocals::new(body);
|
||||
let result =
|
||||
do_dataflow(tcx, mir, def_id, &[], &dead_unwinds, analysis,
|
||||
|bd, p| DebugFormatted::new(&bd.mir().local_decls[p]));
|
||||
do_dataflow(tcx, body, def_id, &[], &dead_unwinds, analysis,
|
||||
|bd, p| DebugFormatted::new(&bd.body().local_decls[p]));
|
||||
Some((analysis, result))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Calculate the liveness of MIR locals ignoring borrows.
|
||||
let mut set = liveness::LiveVarSet::new_empty(mir.local_decls.len());
|
||||
let mut set = liveness::LiveVarSet::new_empty(body.local_decls.len());
|
||||
let mut liveness = liveness::liveness_of_locals(
|
||||
mir,
|
||||
body,
|
||||
);
|
||||
liveness::dump_mir(
|
||||
tcx,
|
||||
"generator_liveness",
|
||||
source,
|
||||
mir,
|
||||
body,
|
||||
&liveness,
|
||||
);
|
||||
|
||||
let mut storage_liveness_map = FxHashMap::default();
|
||||
|
||||
let mut suspending_blocks = BitSet::new_empty(mir.basic_blocks().len());
|
||||
let mut suspending_blocks = BitSet::new_empty(body.basic_blocks().len());
|
||||
|
||||
for (block, data) in mir.basic_blocks().iter_enumerated() {
|
||||
for (block, data) in body.basic_blocks().iter_enumerated() {
|
||||
if let TerminatorKind::Yield { .. } = data.terminator().kind {
|
||||
suspending_blocks.insert(block);
|
||||
|
||||
|
@ -461,7 +461,7 @@ fn locals_live_across_suspend_points(
|
|||
let borrowed_locals = state_for_location(loc,
|
||||
analysis,
|
||||
result,
|
||||
mir);
|
||||
body);
|
||||
// The `liveness` variable contains the liveness of MIR locals ignoring borrows.
|
||||
// This is correct for movable generators since borrows cannot live across
|
||||
// suspension points. However for immovable generators we need to account for
|
||||
|
@ -478,7 +478,7 @@ fn locals_live_across_suspend_points(
|
|||
let mut storage_liveness = state_for_location(loc,
|
||||
&storage_live_analysis,
|
||||
&storage_live,
|
||||
mir);
|
||||
body);
|
||||
|
||||
// Store the storage liveness for later use so we can restore the state
|
||||
// after a suspension point
|
||||
|
@ -511,14 +511,14 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
upvars: &Vec<Ty<'tcx>>,
|
||||
interior: Ty<'tcx>,
|
||||
movable: bool,
|
||||
mir: &mut Body<'tcx>)
|
||||
body: &mut Body<'tcx>)
|
||||
-> (FxHashMap<Local, (Ty<'tcx>, VariantIdx, usize)>,
|
||||
GeneratorLayout<'tcx>,
|
||||
FxHashMap<BasicBlock, liveness::LiveVarSet>)
|
||||
{
|
||||
// Use a liveness analysis to compute locals which are live across a suspension point
|
||||
let (live_locals, storage_liveness, suspending_blocks) =
|
||||
locals_live_across_suspend_points(tcx, mir, source, movable);
|
||||
locals_live_across_suspend_points(tcx, body, source, movable);
|
||||
|
||||
// Erase regions from the types passed in from typeck so we can compare them with
|
||||
// MIR types
|
||||
|
@ -528,7 +528,7 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
_ => bug!(),
|
||||
};
|
||||
|
||||
for (local, decl) in mir.local_decls.iter_enumerated() {
|
||||
for (local, decl) in body.local_decls.iter_enumerated() {
|
||||
// Ignore locals which are internal or not live
|
||||
if !live_locals.contains(local) || decl.internal {
|
||||
continue;
|
||||
|
@ -537,7 +537,7 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
// Sanity check that typeck knows about the type of locals which are
|
||||
// live across a suspension point
|
||||
if !allowed.contains(&decl.ty) && !allowed_upvars.contains(&decl.ty) {
|
||||
span_bug!(mir.span,
|
||||
span_bug!(body.span,
|
||||
"Broken MIR: generator contains type {} in MIR, \
|
||||
but typeck only knows about {}",
|
||||
decl.ty,
|
||||
|
@ -545,12 +545,12 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
let dummy_local = LocalDecl::new_internal(tcx.mk_unit(), mir.span);
|
||||
let dummy_local = LocalDecl::new_internal(tcx.mk_unit(), body.span);
|
||||
|
||||
// Gather live locals and their indices replacing values in mir.local_decls with a dummy
|
||||
// to avoid changing local indices
|
||||
let live_decls = live_locals.iter().map(|local| {
|
||||
let var = mem::replace(&mut mir.local_decls[local], dummy_local.clone());
|
||||
let var = mem::replace(&mut body.local_decls[local], dummy_local.clone());
|
||||
(local, var)
|
||||
});
|
||||
|
||||
|
@ -584,12 +584,12 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
(remap, layout, storage_liveness)
|
||||
}
|
||||
|
||||
fn insert_switch<'a, 'tcx>(mir: &mut Body<'tcx>,
|
||||
fn insert_switch<'a, 'tcx>(body: &mut Body<'tcx>,
|
||||
cases: Vec<(usize, BasicBlock)>,
|
||||
transform: &TransformVisitor<'a, 'tcx>,
|
||||
default: TerminatorKind<'tcx>) {
|
||||
let default_block = insert_term_block(mir, default);
|
||||
let (assign, discr) = transform.get_discr(mir);
|
||||
let default_block = insert_term_block(body, default);
|
||||
let (assign, discr) = transform.get_discr(body);
|
||||
let switch = TerminatorKind::SwitchInt {
|
||||
discr: Operand::Move(discr),
|
||||
switch_ty: transform.discr_ty,
|
||||
|
@ -597,8 +597,8 @@ fn insert_switch<'a, 'tcx>(mir: &mut Body<'tcx>,
|
|||
targets: cases.iter().map(|&(_, d)| d).chain(iter::once(default_block)).collect(),
|
||||
};
|
||||
|
||||
let source_info = source_info(mir);
|
||||
mir.basic_blocks_mut().raw.insert(0, BasicBlockData {
|
||||
let source_info = source_info(body);
|
||||
body.basic_blocks_mut().raw.insert(0, BasicBlockData {
|
||||
statements: vec![assign],
|
||||
terminator: Some(Terminator {
|
||||
source_info,
|
||||
|
@ -607,7 +607,7 @@ fn insert_switch<'a, 'tcx>(mir: &mut Body<'tcx>,
|
|||
is_cleanup: false,
|
||||
});
|
||||
|
||||
let blocks = mir.basic_blocks_mut().iter_mut();
|
||||
let blocks = body.basic_blocks_mut().iter_mut();
|
||||
|
||||
for target in blocks.flat_map(|b| b.terminator_mut().successors_mut()) {
|
||||
*target = BasicBlock::new(target.index() + 1);
|
||||
|
@ -616,7 +616,7 @@ fn insert_switch<'a, 'tcx>(mir: &mut Body<'tcx>,
|
|||
|
||||
fn elaborate_generator_drops<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
def_id: DefId,
|
||||
mir: &mut Body<'tcx>) {
|
||||
body: &mut Body<'tcx>) {
|
||||
use crate::util::elaborate_drops::{elaborate_drop, Unwind};
|
||||
use crate::util::patch::MirPatch;
|
||||
use crate::shim::DropShimElaborator;
|
||||
|
@ -629,13 +629,13 @@ fn elaborate_generator_drops<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
let gen = self_arg();
|
||||
|
||||
let mut elaborator = DropShimElaborator {
|
||||
mir: mir,
|
||||
patch: MirPatch::new(mir),
|
||||
body: body,
|
||||
patch: MirPatch::new(body),
|
||||
tcx,
|
||||
param_env
|
||||
};
|
||||
|
||||
for (block, block_data) in mir.basic_blocks().iter_enumerated() {
|
||||
for (block, block_data) in body.basic_blocks().iter_enumerated() {
|
||||
let (target, unwind, source_info) = match block_data.terminator() {
|
||||
&Terminator {
|
||||
source_info,
|
||||
|
@ -662,7 +662,7 @@ fn elaborate_generator_drops<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
block,
|
||||
);
|
||||
}
|
||||
elaborator.patch.apply(mir);
|
||||
elaborator.patch.apply(body);
|
||||
}
|
||||
|
||||
fn create_generator_drop_shim<'a, 'tcx>(
|
||||
|
@ -671,22 +671,22 @@ fn create_generator_drop_shim<'a, 'tcx>(
|
|||
def_id: DefId,
|
||||
source: MirSource<'tcx>,
|
||||
gen_ty: Ty<'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
drop_clean: BasicBlock) -> Body<'tcx> {
|
||||
let mut mir = mir.clone();
|
||||
let mut body = body.clone();
|
||||
|
||||
let source_info = source_info(&mir);
|
||||
let source_info = source_info(&body);
|
||||
|
||||
let mut cases = create_cases(&mut mir, transform, |point| point.drop);
|
||||
let mut cases = create_cases(&mut body, transform, |point| point.drop);
|
||||
|
||||
cases.insert(0, (UNRESUMED, drop_clean));
|
||||
|
||||
// The returned state and the poisoned state fall through to the default
|
||||
// case which is just to return
|
||||
|
||||
insert_switch(&mut mir, cases, &transform, TerminatorKind::Return);
|
||||
insert_switch(&mut body, cases, &transform, TerminatorKind::Return);
|
||||
|
||||
for block in mir.basic_blocks_mut() {
|
||||
for block in body.basic_blocks_mut() {
|
||||
let kind = &mut block.terminator_mut().kind;
|
||||
if let TerminatorKind::GeneratorDrop = *kind {
|
||||
*kind = TerminatorKind::Return;
|
||||
|
@ -694,7 +694,7 @@ fn create_generator_drop_shim<'a, 'tcx>(
|
|||
}
|
||||
|
||||
// Replace the return variable
|
||||
mir.local_decls[RETURN_PLACE] = LocalDecl {
|
||||
body.local_decls[RETURN_PLACE] = LocalDecl {
|
||||
mutability: Mutability::Mut,
|
||||
ty: tcx.mk_unit(),
|
||||
user_ty: UserTypeProjections::none(),
|
||||
|
@ -706,10 +706,10 @@ fn create_generator_drop_shim<'a, 'tcx>(
|
|||
is_user_variable: None,
|
||||
};
|
||||
|
||||
make_generator_state_argument_indirect(tcx, def_id, &mut mir);
|
||||
make_generator_state_argument_indirect(tcx, def_id, &mut body);
|
||||
|
||||
// Change the generator argument from &mut to *mut
|
||||
mir.local_decls[self_arg()] = LocalDecl {
|
||||
body.local_decls[self_arg()] = LocalDecl {
|
||||
mutability: Mutability::Mut,
|
||||
ty: tcx.mk_ptr(ty::TypeAndMut {
|
||||
ty: gen_ty,
|
||||
|
@ -725,27 +725,27 @@ fn create_generator_drop_shim<'a, 'tcx>(
|
|||
};
|
||||
if tcx.sess.opts.debugging_opts.mir_emit_retag {
|
||||
// Alias tracking must know we changed the type
|
||||
mir.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
|
||||
body.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
|
||||
source_info,
|
||||
kind: StatementKind::Retag(RetagKind::Raw, Place::Base(PlaceBase::Local(self_arg()))),
|
||||
})
|
||||
}
|
||||
|
||||
no_landing_pads(tcx, &mut mir);
|
||||
no_landing_pads(tcx, &mut body);
|
||||
|
||||
// Make sure we remove dead blocks to remove
|
||||
// unrelated code from the resume part of the function
|
||||
simplify::remove_dead_blocks(&mut mir);
|
||||
simplify::remove_dead_blocks(&mut body);
|
||||
|
||||
dump_mir(tcx, None, "generator_drop", &0, source, &mut mir, |_, _| Ok(()) );
|
||||
dump_mir(tcx, None, "generator_drop", &0, source, &mut body, |_, _| Ok(()) );
|
||||
|
||||
mir
|
||||
body
|
||||
}
|
||||
|
||||
fn insert_term_block<'tcx>(mir: &mut Body<'tcx>, kind: TerminatorKind<'tcx>) -> BasicBlock {
|
||||
let term_block = BasicBlock::new(mir.basic_blocks().len());
|
||||
let source_info = source_info(mir);
|
||||
mir.basic_blocks_mut().push(BasicBlockData {
|
||||
fn insert_term_block<'tcx>(body: &mut Body<'tcx>, kind: TerminatorKind<'tcx>) -> BasicBlock {
|
||||
let term_block = BasicBlock::new(body.basic_blocks().len());
|
||||
let source_info = source_info(body);
|
||||
body.basic_blocks_mut().push(BasicBlockData {
|
||||
statements: Vec::new(),
|
||||
terminator: Some(Terminator {
|
||||
source_info,
|
||||
|
@ -757,12 +757,12 @@ fn insert_term_block<'tcx>(mir: &mut Body<'tcx>, kind: TerminatorKind<'tcx>) ->
|
|||
}
|
||||
|
||||
fn insert_panic_block<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &mut Body<'tcx>,
|
||||
body: &mut Body<'tcx>,
|
||||
message: AssertMessage<'tcx>) -> BasicBlock {
|
||||
let assert_block = BasicBlock::new(mir.basic_blocks().len());
|
||||
let assert_block = BasicBlock::new(body.basic_blocks().len());
|
||||
let term = TerminatorKind::Assert {
|
||||
cond: Operand::Constant(box Constant {
|
||||
span: mir.span,
|
||||
span: body.span,
|
||||
ty: tcx.types.bool,
|
||||
user_ty: None,
|
||||
literal: ty::Const::from_bool(tcx, false),
|
||||
|
@ -773,8 +773,8 @@ fn insert_panic_block<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
cleanup: None,
|
||||
};
|
||||
|
||||
let source_info = source_info(mir);
|
||||
mir.basic_blocks_mut().push(BasicBlockData {
|
||||
let source_info = source_info(body);
|
||||
body.basic_blocks_mut().push(BasicBlockData {
|
||||
statements: Vec::new(),
|
||||
terminator: Some(Terminator {
|
||||
source_info,
|
||||
|
@ -791,9 +791,9 @@ fn create_generator_resume_function<'a, 'tcx>(
|
|||
transform: TransformVisitor<'a, 'tcx>,
|
||||
def_id: DefId,
|
||||
source: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
body: &mut Body<'tcx>) {
|
||||
// Poison the generator when it unwinds
|
||||
for block in mir.basic_blocks_mut() {
|
||||
for block in body.basic_blocks_mut() {
|
||||
let source_info = block.terminator().source_info;
|
||||
if let &TerminatorKind::Resume = &block.terminator().kind {
|
||||
block.statements.push(
|
||||
|
@ -801,7 +801,7 @@ fn create_generator_resume_function<'a, 'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
let mut cases = create_cases(mir, &transform, |point| Some(point.resume));
|
||||
let mut cases = create_cases(body, &transform, |point| Some(point.resume));
|
||||
|
||||
use rustc::mir::interpret::InterpError::{
|
||||
GeneratorResumedAfterPanic,
|
||||
|
@ -811,43 +811,43 @@ fn create_generator_resume_function<'a, 'tcx>(
|
|||
// Jump to the entry point on the unresumed
|
||||
cases.insert(0, (UNRESUMED, BasicBlock::new(0)));
|
||||
// Panic when resumed on the returned state
|
||||
cases.insert(1, (RETURNED, insert_panic_block(tcx, mir, GeneratorResumedAfterReturn)));
|
||||
cases.insert(1, (RETURNED, insert_panic_block(tcx, body, GeneratorResumedAfterReturn)));
|
||||
// Panic when resumed on the poisoned state
|
||||
cases.insert(2, (POISONED, insert_panic_block(tcx, mir, GeneratorResumedAfterPanic)));
|
||||
cases.insert(2, (POISONED, insert_panic_block(tcx, body, GeneratorResumedAfterPanic)));
|
||||
|
||||
insert_switch(mir, cases, &transform, TerminatorKind::Unreachable);
|
||||
insert_switch(body, cases, &transform, TerminatorKind::Unreachable);
|
||||
|
||||
make_generator_state_argument_indirect(tcx, def_id, mir);
|
||||
make_generator_state_argument_pinned(tcx, mir);
|
||||
make_generator_state_argument_indirect(tcx, def_id, body);
|
||||
make_generator_state_argument_pinned(tcx, body);
|
||||
|
||||
no_landing_pads(tcx, mir);
|
||||
no_landing_pads(tcx, body);
|
||||
|
||||
// Make sure we remove dead blocks to remove
|
||||
// unrelated code from the drop part of the function
|
||||
simplify::remove_dead_blocks(mir);
|
||||
simplify::remove_dead_blocks(body);
|
||||
|
||||
dump_mir(tcx, None, "generator_resume", &0, source, mir, |_, _| Ok(()) );
|
||||
dump_mir(tcx, None, "generator_resume", &0, source, body, |_, _| Ok(()) );
|
||||
}
|
||||
|
||||
fn source_info<'a, 'tcx>(mir: &Body<'tcx>) -> SourceInfo {
|
||||
fn source_info<'a, 'tcx>(body: &Body<'tcx>) -> SourceInfo {
|
||||
SourceInfo {
|
||||
span: mir.span,
|
||||
span: body.span,
|
||||
scope: OUTERMOST_SOURCE_SCOPE,
|
||||
}
|
||||
}
|
||||
|
||||
fn insert_clean_drop<'a, 'tcx>(mir: &mut Body<'tcx>) -> BasicBlock {
|
||||
let return_block = insert_term_block(mir, TerminatorKind::Return);
|
||||
fn insert_clean_drop<'a, 'tcx>(body: &mut Body<'tcx>) -> BasicBlock {
|
||||
let return_block = insert_term_block(body, TerminatorKind::Return);
|
||||
|
||||
// Create a block to destroy an unresumed generators. This can only destroy upvars.
|
||||
let drop_clean = BasicBlock::new(mir.basic_blocks().len());
|
||||
let drop_clean = BasicBlock::new(body.basic_blocks().len());
|
||||
let term = TerminatorKind::Drop {
|
||||
location: Place::Base(PlaceBase::Local(self_arg())),
|
||||
target: return_block,
|
||||
unwind: None,
|
||||
};
|
||||
let source_info = source_info(mir);
|
||||
mir.basic_blocks_mut().push(BasicBlockData {
|
||||
let source_info = source_info(body);
|
||||
body.basic_blocks_mut().push(BasicBlockData {
|
||||
statements: Vec::new(),
|
||||
terminator: Some(Terminator {
|
||||
source_info,
|
||||
|
@ -859,20 +859,20 @@ fn insert_clean_drop<'a, 'tcx>(mir: &mut Body<'tcx>) -> BasicBlock {
|
|||
drop_clean
|
||||
}
|
||||
|
||||
fn create_cases<'a, 'tcx, F>(mir: &mut Body<'tcx>,
|
||||
fn create_cases<'a, 'tcx, F>(body: &mut Body<'tcx>,
|
||||
transform: &TransformVisitor<'a, 'tcx>,
|
||||
target: F) -> Vec<(usize, BasicBlock)>
|
||||
where F: Fn(&SuspensionPoint) -> Option<BasicBlock> {
|
||||
let source_info = source_info(mir);
|
||||
let source_info = source_info(body);
|
||||
|
||||
transform.suspension_points.iter().filter_map(|point| {
|
||||
// Find the target for this suspension point, if applicable
|
||||
target(point).map(|target| {
|
||||
let block = BasicBlock::new(mir.basic_blocks().len());
|
||||
let block = BasicBlock::new(body.basic_blocks().len());
|
||||
let mut statements = Vec::new();
|
||||
|
||||
// Create StorageLive instructions for locals with live storage
|
||||
for i in 0..(mir.local_decls.len()) {
|
||||
for i in 0..(body.local_decls.len()) {
|
||||
let l = Local::new(i);
|
||||
if point.storage_liveness.contains(l) && !transform.remap.contains_key(&l) {
|
||||
statements.push(Statement {
|
||||
|
@ -883,7 +883,7 @@ fn create_cases<'a, 'tcx, F>(mir: &mut Body<'tcx>,
|
|||
}
|
||||
|
||||
// Then jump to the real target
|
||||
mir.basic_blocks_mut().push(BasicBlockData {
|
||||
body.basic_blocks_mut().push(BasicBlockData {
|
||||
statements,
|
||||
terminator: Some(Terminator {
|
||||
source_info,
|
||||
|
@ -903,20 +903,20 @@ impl MirPass for StateTransform {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
source: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
let yield_ty = if let Some(yield_ty) = mir.yield_ty {
|
||||
body: &mut Body<'tcx>) {
|
||||
let yield_ty = if let Some(yield_ty) = body.yield_ty {
|
||||
yield_ty
|
||||
} else {
|
||||
// This only applies to generators
|
||||
return
|
||||
};
|
||||
|
||||
assert!(mir.generator_drop.is_none());
|
||||
assert!(body.generator_drop.is_none());
|
||||
|
||||
let def_id = source.def_id();
|
||||
|
||||
// The first argument is the generator type passed by value
|
||||
let gen_ty = mir.local_decls.raw[1].ty;
|
||||
let gen_ty = body.local_decls.raw[1].ty;
|
||||
|
||||
// Get the interior types and substs which typeck computed
|
||||
let (upvars, interior, discr_ty, movable) = match gen_ty.sty {
|
||||
|
@ -934,13 +934,13 @@ impl MirPass for StateTransform {
|
|||
let state_adt_ref = tcx.adt_def(state_did);
|
||||
let state_substs = tcx.intern_substs(&[
|
||||
yield_ty.into(),
|
||||
mir.return_ty().into(),
|
||||
body.return_ty().into(),
|
||||
]);
|
||||
let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
|
||||
|
||||
// We rename RETURN_PLACE which has type mir.return_ty to new_ret_local
|
||||
// RETURN_PLACE then is a fresh unused local with type ret_ty.
|
||||
let new_ret_local = replace_result_variable(ret_ty, mir);
|
||||
let new_ret_local = replace_result_variable(ret_ty, body);
|
||||
|
||||
// Extract locals which are live across suspension point into `layout`
|
||||
// `remap` gives a mapping from local indices onto generator struct indices
|
||||
|
@ -951,7 +951,7 @@ impl MirPass for StateTransform {
|
|||
&upvars,
|
||||
interior,
|
||||
movable,
|
||||
mir);
|
||||
body);
|
||||
|
||||
// Run the transformation which converts Places from Local to generator struct
|
||||
// accesses for locals in `remap`.
|
||||
|
@ -967,27 +967,27 @@ impl MirPass for StateTransform {
|
|||
new_ret_local,
|
||||
discr_ty,
|
||||
};
|
||||
transform.visit_body(mir);
|
||||
transform.visit_body(body);
|
||||
|
||||
// Update our MIR struct to reflect the changed we've made
|
||||
mir.yield_ty = None;
|
||||
mir.arg_count = 1;
|
||||
mir.spread_arg = None;
|
||||
mir.generator_layout = Some(layout);
|
||||
body.yield_ty = None;
|
||||
body.arg_count = 1;
|
||||
body.spread_arg = None;
|
||||
body.generator_layout = Some(layout);
|
||||
|
||||
// Insert `drop(generator_struct)` which is used to drop upvars for generators in
|
||||
// the unresumed state.
|
||||
// This is expanded to a drop ladder in `elaborate_generator_drops`.
|
||||
let drop_clean = insert_clean_drop(mir);
|
||||
let drop_clean = insert_clean_drop(body);
|
||||
|
||||
dump_mir(tcx, None, "generator_pre-elab", &0, source, mir, |_, _| Ok(()) );
|
||||
dump_mir(tcx, None, "generator_pre-elab", &0, source, body, |_, _| Ok(()) );
|
||||
|
||||
// Expand `drop(generator_struct)` to a drop ladder which destroys upvars.
|
||||
// If any upvars are moved out of, drop elaboration will handle upvar destruction.
|
||||
// However we need to also elaborate the code generated by `insert_clean_drop`.
|
||||
elaborate_generator_drops(tcx, def_id, mir);
|
||||
elaborate_generator_drops(tcx, def_id, body);
|
||||
|
||||
dump_mir(tcx, None, "generator_post-transform", &0, source, mir, |_, _| Ok(()) );
|
||||
dump_mir(tcx, None, "generator_post-transform", &0, source, body, |_, _| Ok(()) );
|
||||
|
||||
// Create a copy of our MIR and use it to create the drop shim for the generator
|
||||
let drop_shim = create_generator_drop_shim(tcx,
|
||||
|
@ -995,12 +995,12 @@ impl MirPass for StateTransform {
|
|||
def_id,
|
||||
source,
|
||||
gen_ty,
|
||||
&mir,
|
||||
&body,
|
||||
drop_clean);
|
||||
|
||||
mir.generator_drop = Some(box drop_shim);
|
||||
body.generator_drop = Some(box drop_shim);
|
||||
|
||||
// Create the Generator::resume function
|
||||
create_generator_resume_function(tcx, transform, def_id, source, mir);
|
||||
create_generator_resume_function(tcx, transform, def_id, source, body);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,9 +41,9 @@ impl MirPass for Inline {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
source: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
body: &mut Body<'tcx>) {
|
||||
if tcx.sess.opts.debugging_opts.mir_opt_level >= 2 {
|
||||
Inliner { tcx, source }.run_pass(mir);
|
||||
Inliner { tcx, source }.run_pass(body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ struct Inliner<'a, 'tcx: 'a> {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||
fn run_pass(&self, caller_mir: &mut Body<'tcx>) {
|
||||
fn run_pass(&self, caller_body: &mut Body<'tcx>) {
|
||||
// Keep a queue of callsites to try inlining on. We take
|
||||
// advantage of the fact that queries detect cycles here to
|
||||
// allow us to try and fetch the fully optimized MIR of a
|
||||
|
@ -76,10 +76,10 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
if self.tcx.hir().body_owner_kind_by_hir_id(id).is_fn_or_closure()
|
||||
&& self.source.promoted.is_none()
|
||||
{
|
||||
for (bb, bb_data) in caller_mir.basic_blocks().iter_enumerated() {
|
||||
for (bb, bb_data) in caller_body.basic_blocks().iter_enumerated() {
|
||||
if let Some(callsite) = self.get_valid_function_call(bb,
|
||||
bb_data,
|
||||
caller_mir,
|
||||
caller_body,
|
||||
param_env) {
|
||||
callsites.push_back(callsite);
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
let self_node_id = self.tcx.hir().as_local_node_id(self.source.def_id()).unwrap();
|
||||
let callee_node_id = self.tcx.hir().as_local_node_id(callsite.callee);
|
||||
|
||||
let callee_mir = if let Some(callee_node_id) = callee_node_id {
|
||||
let callee_body = if let Some(callee_node_id) = callee_node_id {
|
||||
// Avoid a cycle here by only using `optimized_mir` only if we have
|
||||
// a lower node id than the callee. This ensures that the callee will
|
||||
// not inline us. This trick only works without incremental compilation.
|
||||
|
@ -120,29 +120,29 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
self.tcx.optimized_mir(callsite.callee)
|
||||
};
|
||||
|
||||
let callee_mir = if self.consider_optimizing(callsite, callee_mir) {
|
||||
let callee_body = if self.consider_optimizing(callsite, callee_body) {
|
||||
self.tcx.subst_and_normalize_erasing_regions(
|
||||
&callsite.substs,
|
||||
param_env,
|
||||
callee_mir,
|
||||
callee_body,
|
||||
)
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let start = caller_mir.basic_blocks().len();
|
||||
debug!("attempting to inline callsite {:?} - mir={:?}", callsite, callee_mir);
|
||||
if !self.inline_call(callsite, caller_mir, callee_mir) {
|
||||
let start = caller_body.basic_blocks().len();
|
||||
debug!("attempting to inline callsite {:?} - body={:?}", callsite, callee_body);
|
||||
if !self.inline_call(callsite, caller_body, callee_body) {
|
||||
debug!("attempting to inline callsite {:?} - failure", callsite);
|
||||
continue;
|
||||
}
|
||||
debug!("attempting to inline callsite {:?} - success", callsite);
|
||||
|
||||
// Add callsites from inlined function
|
||||
for (bb, bb_data) in caller_mir.basic_blocks().iter_enumerated().skip(start) {
|
||||
for (bb, bb_data) in caller_body.basic_blocks().iter_enumerated().skip(start) {
|
||||
if let Some(new_callsite) = self.get_valid_function_call(bb,
|
||||
bb_data,
|
||||
caller_mir,
|
||||
caller_body,
|
||||
param_env) {
|
||||
// Don't inline the same function multiple times.
|
||||
if callsite.callee != new_callsite.callee {
|
||||
|
@ -163,15 +163,15 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
// Simplify if we inlined anything.
|
||||
if changed {
|
||||
debug!("Running simplify cfg on {:?}", self.source);
|
||||
CfgSimplifier::new(caller_mir).simplify();
|
||||
remove_dead_blocks(caller_mir);
|
||||
CfgSimplifier::new(caller_body).simplify();
|
||||
remove_dead_blocks(caller_body);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_valid_function_call(&self,
|
||||
bb: BasicBlock,
|
||||
bb_data: &BasicBlockData<'tcx>,
|
||||
caller_mir: &Body<'tcx>,
|
||||
caller_body: &Body<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
) -> Option<CallSite<'tcx>> {
|
||||
// Don't inline calls that are in cleanup blocks.
|
||||
|
@ -180,7 +180,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
// Only consider direct calls to functions
|
||||
let terminator = bb_data.terminator();
|
||||
if let TerminatorKind::Call { func: ref op, .. } = terminator.kind {
|
||||
if let ty::FnDef(callee_def_id, substs) = op.ty(caller_mir, self.tcx).sty {
|
||||
if let ty::FnDef(callee_def_id, substs) = op.ty(caller_body, self.tcx).sty {
|
||||
let instance = Instance::resolve(self.tcx,
|
||||
param_env,
|
||||
callee_def_id,
|
||||
|
@ -204,19 +204,19 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
|
||||
fn consider_optimizing(&self,
|
||||
callsite: CallSite<'tcx>,
|
||||
callee_mir: &Body<'tcx>)
|
||||
callee_body: &Body<'tcx>)
|
||||
-> bool
|
||||
{
|
||||
debug!("consider_optimizing({:?})", callsite);
|
||||
self.should_inline(callsite, callee_mir)
|
||||
self.should_inline(callsite, callee_body)
|
||||
&& self.tcx.consider_optimizing(|| format!("Inline {:?} into {:?}",
|
||||
callee_mir.span,
|
||||
callee_body.span,
|
||||
callsite))
|
||||
}
|
||||
|
||||
fn should_inline(&self,
|
||||
callsite: CallSite<'tcx>,
|
||||
callee_mir: &Body<'tcx>)
|
||||
callee_body: &Body<'tcx>)
|
||||
-> bool
|
||||
{
|
||||
debug!("should_inline({:?})", callsite);
|
||||
|
@ -224,13 +224,13 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
|
||||
// Don't inline closures that have capture debuginfo
|
||||
// FIXME: Handle closures better
|
||||
if callee_mir.__upvar_debuginfo_codegen_only_do_not_use.len() > 0 {
|
||||
if callee_body.__upvar_debuginfo_codegen_only_do_not_use.len() > 0 {
|
||||
debug!(" upvar debuginfo present - not inlining");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cannot inline generators which haven't been transformed yet
|
||||
if callee_mir.yield_ty.is_some() {
|
||||
if callee_body.yield_ty.is_some() {
|
||||
debug!(" yield ty present - not inlining");
|
||||
return false;
|
||||
}
|
||||
|
@ -281,7 +281,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
// Give a bonus functions with a small number of blocks,
|
||||
// We normally have two or three blocks for even
|
||||
// very small functions.
|
||||
if callee_mir.basic_blocks().len() <= 3 {
|
||||
if callee_body.basic_blocks().len() <= 3 {
|
||||
threshold += threshold / 4;
|
||||
}
|
||||
debug!(" final inline threshold = {}", threshold);
|
||||
|
@ -296,10 +296,10 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
// Traverse the MIR manually so we can account for the effects of
|
||||
// inlining on the CFG.
|
||||
let mut work_list = vec![START_BLOCK];
|
||||
let mut visited = BitSet::new_empty(callee_mir.basic_blocks().len());
|
||||
let mut visited = BitSet::new_empty(callee_body.basic_blocks().len());
|
||||
while let Some(bb) = work_list.pop() {
|
||||
if !visited.insert(bb.index()) { continue; }
|
||||
let blk = &callee_mir.basic_blocks()[bb];
|
||||
let blk = &callee_body.basic_blocks()[bb];
|
||||
|
||||
for stmt in &blk.statements {
|
||||
// Don't count StorageLive/StorageDead in the inlining cost.
|
||||
|
@ -319,7 +319,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
work_list.push(target);
|
||||
// If the location doesn't actually need dropping, treat it like
|
||||
// a regular goto.
|
||||
let ty = location.ty(callee_mir, tcx).subst(tcx, callsite.substs).ty;
|
||||
let ty = location.ty(callee_body, tcx).subst(tcx, callsite.substs).ty;
|
||||
if ty.needs_drop(tcx, param_env) {
|
||||
cost += CALL_PENALTY;
|
||||
if let Some(unwind) = unwind {
|
||||
|
@ -366,8 +366,8 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
|
||||
let ptr_size = tcx.data_layout.pointer_size.bytes();
|
||||
|
||||
for v in callee_mir.vars_and_temps_iter() {
|
||||
let v = &callee_mir.local_decls[v];
|
||||
for v in callee_body.vars_and_temps_iter() {
|
||||
let v = &callee_body.local_decls[v];
|
||||
let ty = v.ty.subst(tcx, callsite.substs);
|
||||
// Cost of the var is the size in machine-words, if we know
|
||||
// it.
|
||||
|
@ -394,44 +394,44 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
|
||||
fn inline_call(&self,
|
||||
callsite: CallSite<'tcx>,
|
||||
caller_mir: &mut Body<'tcx>,
|
||||
mut callee_mir: Body<'tcx>) -> bool {
|
||||
let terminator = caller_mir[callsite.bb].terminator.take().unwrap();
|
||||
caller_body: &mut Body<'tcx>,
|
||||
mut callee_body: Body<'tcx>) -> bool {
|
||||
let terminator = caller_body[callsite.bb].terminator.take().unwrap();
|
||||
match terminator.kind {
|
||||
// FIXME: Handle inlining of diverging calls
|
||||
TerminatorKind::Call { args, destination: Some(destination), cleanup, .. } => {
|
||||
debug!("Inlined {:?} into {:?}", callsite.callee, self.source);
|
||||
|
||||
let mut local_map = IndexVec::with_capacity(callee_mir.local_decls.len());
|
||||
let mut scope_map = IndexVec::with_capacity(callee_mir.source_scopes.len());
|
||||
let mut promoted_map = IndexVec::with_capacity(callee_mir.promoted.len());
|
||||
let mut local_map = IndexVec::with_capacity(callee_body.local_decls.len());
|
||||
let mut scope_map = IndexVec::with_capacity(callee_body.source_scopes.len());
|
||||
let mut promoted_map = IndexVec::with_capacity(callee_body.promoted.len());
|
||||
|
||||
for mut scope in callee_mir.source_scopes.iter().cloned() {
|
||||
for mut scope in callee_body.source_scopes.iter().cloned() {
|
||||
if scope.parent_scope.is_none() {
|
||||
scope.parent_scope = Some(callsite.location.scope);
|
||||
scope.span = callee_mir.span;
|
||||
scope.span = callee_body.span;
|
||||
}
|
||||
|
||||
scope.span = callsite.location.span;
|
||||
|
||||
let idx = caller_mir.source_scopes.push(scope);
|
||||
let idx = caller_body.source_scopes.push(scope);
|
||||
scope_map.push(idx);
|
||||
}
|
||||
|
||||
for loc in callee_mir.vars_and_temps_iter() {
|
||||
let mut local = callee_mir.local_decls[loc].clone();
|
||||
for loc in callee_body.vars_and_temps_iter() {
|
||||
let mut local = callee_body.local_decls[loc].clone();
|
||||
|
||||
local.source_info.scope =
|
||||
scope_map[local.source_info.scope];
|
||||
local.source_info.span = callsite.location.span;
|
||||
local.visibility_scope = scope_map[local.visibility_scope];
|
||||
|
||||
let idx = caller_mir.local_decls.push(local);
|
||||
let idx = caller_body.local_decls.push(local);
|
||||
local_map.push(idx);
|
||||
}
|
||||
|
||||
promoted_map.extend(
|
||||
callee_mir.promoted.iter().cloned().map(|p| caller_mir.promoted.push(p))
|
||||
callee_body.promoted.iter().cloned().map(|p| caller_body.promoted.push(p))
|
||||
);
|
||||
|
||||
// If the call is something like `a[*i] = f(i)`, where
|
||||
|
@ -465,18 +465,18 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
BorrowKind::Mut { allow_two_phase_borrow: false },
|
||||
destination.0);
|
||||
|
||||
let ty = dest.ty(caller_mir, self.tcx);
|
||||
let ty = dest.ty(caller_body, self.tcx);
|
||||
|
||||
let temp = LocalDecl::new_temp(ty, callsite.location.span);
|
||||
|
||||
let tmp = caller_mir.local_decls.push(temp);
|
||||
let tmp = caller_body.local_decls.push(temp);
|
||||
let tmp = Place::Base(PlaceBase::Local(tmp));
|
||||
|
||||
let stmt = Statement {
|
||||
source_info: callsite.location,
|
||||
kind: StatementKind::Assign(tmp.clone(), box dest)
|
||||
};
|
||||
caller_mir[callsite.bb]
|
||||
caller_body[callsite.bb]
|
||||
.statements.push(stmt);
|
||||
tmp.deref()
|
||||
} else {
|
||||
|
@ -486,9 +486,9 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
let return_block = destination.1;
|
||||
|
||||
// Copy the arguments if needed.
|
||||
let args: Vec<_> = self.make_call_args(args, &callsite, caller_mir);
|
||||
let args: Vec<_> = self.make_call_args(args, &callsite, caller_body);
|
||||
|
||||
let bb_len = caller_mir.basic_blocks().len();
|
||||
let bb_len = caller_body.basic_blocks().len();
|
||||
let mut integrator = Integrator {
|
||||
block_idx: bb_len,
|
||||
args: &args,
|
||||
|
@ -503,9 +503,9 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
};
|
||||
|
||||
|
||||
for (bb, mut block) in callee_mir.basic_blocks_mut().drain_enumerated(..) {
|
||||
for (bb, mut block) in callee_body.basic_blocks_mut().drain_enumerated(..) {
|
||||
integrator.visit_basic_block_data(bb, &mut block);
|
||||
caller_mir.basic_blocks_mut().push(block);
|
||||
caller_body.basic_blocks_mut().push(block);
|
||||
}
|
||||
|
||||
let terminator = Terminator {
|
||||
|
@ -513,12 +513,12 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
kind: TerminatorKind::Goto { target: BasicBlock::new(bb_len) }
|
||||
};
|
||||
|
||||
caller_mir[callsite.bb].terminator = Some(terminator);
|
||||
caller_body[callsite.bb].terminator = Some(terminator);
|
||||
|
||||
true
|
||||
}
|
||||
kind => {
|
||||
caller_mir[callsite.bb].terminator = Some(Terminator {
|
||||
caller_body[callsite.bb].terminator = Some(Terminator {
|
||||
source_info: terminator.source_info,
|
||||
kind,
|
||||
});
|
||||
|
@ -531,7 +531,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
&self,
|
||||
args: Vec<Operand<'tcx>>,
|
||||
callsite: &CallSite<'tcx>,
|
||||
caller_mir: &mut Body<'tcx>,
|
||||
caller_body: &mut Body<'tcx>,
|
||||
) -> Vec<Local> {
|
||||
let tcx = self.tcx;
|
||||
|
||||
|
@ -560,12 +560,12 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
// and the vector is `[closure_ref, tmp0, tmp1, tmp2]`.
|
||||
if tcx.is_closure(callsite.callee) {
|
||||
let mut args = args.into_iter();
|
||||
let self_ = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_mir);
|
||||
let tuple = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_mir);
|
||||
let self_ = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_body);
|
||||
let tuple = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_body);
|
||||
assert!(args.next().is_none());
|
||||
|
||||
let tuple = Place::Base(PlaceBase::Local(tuple));
|
||||
let tuple_tys = if let ty::Tuple(s) = tuple.ty(caller_mir, tcx).ty.sty {
|
||||
let tuple_tys = if let ty::Tuple(s) = tuple.ty(caller_body, tcx).ty.sty {
|
||||
s
|
||||
} else {
|
||||
bug!("Closure arguments are not passed as a tuple");
|
||||
|
@ -584,13 +584,13 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
));
|
||||
|
||||
// Spill to a local to make e.g., `tmp0`.
|
||||
self.create_temp_if_necessary(tuple_field, callsite, caller_mir)
|
||||
self.create_temp_if_necessary(tuple_field, callsite, caller_body)
|
||||
});
|
||||
|
||||
closure_ref_arg.chain(tuple_tmp_args).collect()
|
||||
} else {
|
||||
args.into_iter()
|
||||
.map(|a| self.create_temp_if_necessary(a, callsite, caller_mir))
|
||||
.map(|a| self.create_temp_if_necessary(a, callsite, caller_body))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
@ -601,13 +601,13 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
&self,
|
||||
arg: Operand<'tcx>,
|
||||
callsite: &CallSite<'tcx>,
|
||||
caller_mir: &mut Body<'tcx>,
|
||||
caller_body: &mut Body<'tcx>,
|
||||
) -> Local {
|
||||
// FIXME: Analysis of the usage of the arguments to avoid
|
||||
// unnecessary temporaries.
|
||||
|
||||
if let Operand::Move(Place::Base(PlaceBase::Local(local))) = arg {
|
||||
if caller_mir.local_kind(local) == LocalKind::Temp {
|
||||
if caller_body.local_kind(local) == LocalKind::Temp {
|
||||
// Reuse the operand if it's a temporary already
|
||||
return local;
|
||||
}
|
||||
|
@ -617,16 +617,16 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
|||
// Otherwise, create a temporary for the arg
|
||||
let arg = Rvalue::Use(arg);
|
||||
|
||||
let ty = arg.ty(caller_mir, self.tcx);
|
||||
let ty = arg.ty(caller_body, self.tcx);
|
||||
|
||||
let arg_tmp = LocalDecl::new_temp(ty, callsite.location.span);
|
||||
let arg_tmp = caller_mir.local_decls.push(arg_tmp);
|
||||
let arg_tmp = caller_body.local_decls.push(arg_tmp);
|
||||
|
||||
let stmt = Statement {
|
||||
source_info: callsite.location,
|
||||
kind: StatementKind::Assign(Place::Base(PlaceBase::Local(arg_tmp)), box arg),
|
||||
};
|
||||
caller_mir[callsite.bb].statements.push(stmt);
|
||||
caller_body[callsite.bb].statements.push(stmt);
|
||||
arg_tmp
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ impl MirPass for InstCombine {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
body: &mut Body<'tcx>) {
|
||||
// We only run when optimizing MIR (at any level).
|
||||
if tcx.sess.opts.debugging_opts.mir_opt_level == 0 {
|
||||
return
|
||||
|
@ -25,13 +25,13 @@ impl MirPass for InstCombine {
|
|||
// read-only so that we can do global analyses on the MIR in the process (e.g.
|
||||
// `Place::ty()`).
|
||||
let optimizations = {
|
||||
let mut optimization_finder = OptimizationFinder::new(mir, tcx);
|
||||
optimization_finder.visit_body(mir);
|
||||
let mut optimization_finder = OptimizationFinder::new(body, tcx);
|
||||
optimization_finder.visit_body(body);
|
||||
optimization_finder.optimizations
|
||||
};
|
||||
|
||||
// Then carry out those optimizations.
|
||||
MutVisitor::visit_body(&mut InstCombineVisitor { optimizations }, mir);
|
||||
MutVisitor::visit_body(&mut InstCombineVisitor { optimizations }, body);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,15 +64,15 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
|
|||
|
||||
/// Finds optimization opportunities on the MIR.
|
||||
struct OptimizationFinder<'b, 'a, 'tcx:'a+'b> {
|
||||
mir: &'b Body<'tcx>,
|
||||
body: &'b Body<'tcx>,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
optimizations: OptimizationList<'tcx>,
|
||||
}
|
||||
|
||||
impl<'b, 'a, 'tcx:'b> OptimizationFinder<'b, 'a, 'tcx> {
|
||||
fn new(mir: &'b Body<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> OptimizationFinder<'b, 'a, 'tcx> {
|
||||
fn new(body: &'b Body<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> OptimizationFinder<'b, 'a, 'tcx> {
|
||||
OptimizationFinder {
|
||||
mir,
|
||||
body,
|
||||
tcx,
|
||||
optimizations: OptimizationList::default(),
|
||||
}
|
||||
|
@ -83,16 +83,16 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for OptimizationFinder<'b, 'a, 'tcx> {
|
|||
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
|
||||
if let Rvalue::Ref(_, _, Place::Projection(ref projection)) = *rvalue {
|
||||
if let ProjectionElem::Deref = projection.elem {
|
||||
if projection.base.ty(self.mir, self.tcx).ty.is_region_ptr() {
|
||||
if projection.base.ty(self.body, self.tcx).ty.is_region_ptr() {
|
||||
self.optimizations.and_stars.insert(location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Rvalue::Len(ref place) = *rvalue {
|
||||
let place_ty = place.ty(&self.mir.local_decls, self.tcx).ty;
|
||||
let place_ty = place.ty(&self.body.local_decls, self.tcx).ty;
|
||||
if let ty::Array(_, len) = place_ty.sty {
|
||||
let span = self.mir.source_info(location).span;
|
||||
let span = self.body.source_info(location).span;
|
||||
let ty = self.tcx.types.usize;
|
||||
let constant = Constant { span, ty, literal: len, user_ty: None };
|
||||
self.optimizations.arrays_lengths.insert(location, constant);
|
||||
|
|
|
@ -13,23 +13,23 @@ impl MirPass for Lower128Bit {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_src: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
body: &mut Body<'tcx>) {
|
||||
let debugging_override = tcx.sess.opts.debugging_opts.lower_128bit_ops;
|
||||
let target_default = tcx.sess.host.options.i128_lowering;
|
||||
if !debugging_override.unwrap_or(target_default) {
|
||||
return
|
||||
}
|
||||
|
||||
self.lower_128bit_ops(tcx, mir);
|
||||
self.lower_128bit_ops(tcx, body);
|
||||
}
|
||||
}
|
||||
|
||||
impl Lower128Bit {
|
||||
fn lower_128bit_ops<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &mut Body<'tcx>) {
|
||||
fn lower_128bit_ops<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, body: &mut Body<'tcx>) {
|
||||
let mut new_blocks = Vec::new();
|
||||
let cur_len = mir.basic_blocks().len();
|
||||
let cur_len = body.basic_blocks().len();
|
||||
|
||||
let (basic_blocks, local_decls) = mir.basic_blocks_and_local_decls_mut();
|
||||
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
|
||||
for block in basic_blocks.iter_mut() {
|
||||
for i in (0..block.statements.len()).rev() {
|
||||
let (lang_item, rhs_kind) =
|
||||
|
|
|
@ -145,20 +145,20 @@ pub trait MirPass {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
source: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>);
|
||||
body: &mut Body<'tcx>);
|
||||
}
|
||||
|
||||
pub fn run_passes(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &mut Body<'tcx>,
|
||||
body: &mut Body<'tcx>,
|
||||
instance: InstanceDef<'tcx>,
|
||||
mir_phase: MirPhase,
|
||||
passes: &[&dyn MirPass],
|
||||
) {
|
||||
let phase_index = mir_phase.phase_index();
|
||||
|
||||
let run_passes = |mir: &mut Body<'tcx>, promoted| {
|
||||
if mir.phase >= mir_phase {
|
||||
let run_passes = |body: &mut Body<'tcx>, promoted| {
|
||||
if body.phase >= mir_phase {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -168,13 +168,13 @@ pub fn run_passes(
|
|||
};
|
||||
let mut index = 0;
|
||||
let mut run_pass = |pass: &dyn MirPass| {
|
||||
let run_hooks = |mir: &_, index, is_after| {
|
||||
let run_hooks = |body: &_, index, is_after| {
|
||||
dump_mir::on_mir_pass(tcx, &format_args!("{:03}-{:03}", phase_index, index),
|
||||
&pass.name(), source, mir, is_after);
|
||||
&pass.name(), source, body, is_after);
|
||||
};
|
||||
run_hooks(mir, index, false);
|
||||
pass.run_pass(tcx, source, mir);
|
||||
run_hooks(mir, index, true);
|
||||
run_hooks(body, index, false);
|
||||
pass.run_pass(tcx, source, body);
|
||||
run_hooks(body, index, true);
|
||||
|
||||
index += 1;
|
||||
};
|
||||
|
@ -183,16 +183,16 @@ pub fn run_passes(
|
|||
run_pass(*pass);
|
||||
}
|
||||
|
||||
mir.phase = mir_phase;
|
||||
body.phase = mir_phase;
|
||||
};
|
||||
|
||||
run_passes(mir, None);
|
||||
run_passes(body, None);
|
||||
|
||||
for (index, promoted_mir) in mir.promoted.iter_enumerated_mut() {
|
||||
run_passes(promoted_mir, Some(index));
|
||||
for (index, promoted_body) in body.promoted.iter_enumerated_mut() {
|
||||
run_passes(promoted_body, Some(index));
|
||||
|
||||
//Let's make sure we don't miss any nested instances
|
||||
assert!(promoted_mir.promoted.is_empty())
|
||||
assert!(promoted_body.promoted.is_empty())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,14 +200,14 @@ fn mir_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Stea
|
|||
// Unsafety check uses the raw mir, so make sure it is run
|
||||
let _ = tcx.unsafety_check_result(def_id);
|
||||
|
||||
let mut mir = tcx.mir_built(def_id).steal();
|
||||
run_passes(tcx, &mut mir, InstanceDef::Item(def_id), MirPhase::Const, &[
|
||||
let mut body = tcx.mir_built(def_id).steal();
|
||||
run_passes(tcx, &mut body, InstanceDef::Item(def_id), MirPhase::Const, &[
|
||||
// What we need to do constant evaluation.
|
||||
&simplify::SimplifyCfg::new("initial"),
|
||||
&rustc_peek::SanityCheck,
|
||||
&uniform_array_move_out::UniformArrayMoveOut,
|
||||
]);
|
||||
tcx.alloc_steal_mir(mir)
|
||||
tcx.alloc_steal_mir(body)
|
||||
}
|
||||
|
||||
fn mir_validated<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Steal<Body<'tcx>> {
|
||||
|
@ -218,13 +218,13 @@ fn mir_validated<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
|
|||
let _ = tcx.mir_const_qualif(def_id);
|
||||
}
|
||||
|
||||
let mut mir = tcx.mir_const(def_id).steal();
|
||||
run_passes(tcx, &mut mir, InstanceDef::Item(def_id), MirPhase::Validated, &[
|
||||
let mut body = tcx.mir_const(def_id).steal();
|
||||
run_passes(tcx, &mut body, InstanceDef::Item(def_id), MirPhase::Validated, &[
|
||||
// What we need to run borrowck etc.
|
||||
&qualify_consts::QualifyAndPromoteConstants,
|
||||
&simplify::SimplifyCfg::new("qualify-consts"),
|
||||
]);
|
||||
tcx.alloc_steal_mir(mir)
|
||||
tcx.alloc_steal_mir(body)
|
||||
}
|
||||
|
||||
fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Body<'tcx> {
|
||||
|
@ -244,8 +244,8 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
|
|||
tcx.ensure().borrowck(def_id);
|
||||
}
|
||||
|
||||
let mut mir = tcx.mir_validated(def_id).steal();
|
||||
run_passes(tcx, &mut mir, InstanceDef::Item(def_id), MirPhase::Optimized, &[
|
||||
let mut body = tcx.mir_validated(def_id).steal();
|
||||
run_passes(tcx, &mut body, InstanceDef::Item(def_id), MirPhase::Optimized, &[
|
||||
// Remove all things only needed by analysis
|
||||
&no_landing_pads::NoLandingPads,
|
||||
&simplify_branches::SimplifyBranches::new("initial"),
|
||||
|
@ -298,5 +298,5 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
|
|||
&add_call_guards::CriticalCallEdges,
|
||||
&dump_mir::Marker("PreCodegen"),
|
||||
]);
|
||||
tcx.arena.alloc(mir)
|
||||
tcx.arena.alloc(body)
|
||||
}
|
||||
|
|
|
@ -12,14 +12,14 @@ impl MirPass for NoLandingPads {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
no_landing_pads(tcx, mir)
|
||||
body: &mut Body<'tcx>) {
|
||||
no_landing_pads(tcx, body)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn no_landing_pads<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &mut Body<'tcx>) {
|
||||
pub fn no_landing_pads<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, body: &mut Body<'tcx>) {
|
||||
if tcx.sess.no_landing_pads() {
|
||||
NoLandingPads.visit_body(mir);
|
||||
NoLandingPads.visit_body(body);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ pub enum Candidate {
|
|||
struct TempCollector<'tcx> {
|
||||
temps: IndexVec<Local, TempState>,
|
||||
span: Span,
|
||||
mir: &'tcx Body<'tcx>,
|
||||
body: &'tcx Body<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> {
|
||||
|
@ -81,7 +81,7 @@ impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> {
|
|||
location: Location) {
|
||||
debug!("visit_local: index={:?} context={:?} location={:?}", index, context, location);
|
||||
// We're only interested in temporaries and the return place
|
||||
match self.mir.local_kind(index) {
|
||||
match self.body.local_kind(index) {
|
||||
| LocalKind::Temp
|
||||
| LocalKind::ReturnPointer
|
||||
=> {},
|
||||
|
@ -134,12 +134,12 @@ impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn collect_temps(mir: &Body<'_>,
|
||||
pub fn collect_temps(body: &Body<'_>,
|
||||
rpo: &mut ReversePostorder<'_, '_>) -> IndexVec<Local, TempState> {
|
||||
let mut collector = TempCollector {
|
||||
temps: IndexVec::from_elem(TempState::Undefined, &mir.local_decls),
|
||||
span: mir.span,
|
||||
mir,
|
||||
temps: IndexVec::from_elem(TempState::Undefined, &body.local_decls),
|
||||
span: body.span,
|
||||
body,
|
||||
};
|
||||
for (bb, data) in rpo {
|
||||
collector.visit_basic_block_data(bb, data);
|
||||
|
@ -369,7 +369,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn promote_candidates<'a, 'tcx>(mir: &mut Body<'tcx>,
|
||||
pub fn promote_candidates<'a, 'tcx>(body: &mut Body<'tcx>,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mut temps: IndexVec<Local, TempState>,
|
||||
candidates: Vec<Candidate>) {
|
||||
|
@ -379,7 +379,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Body<'tcx>,
|
|||
for candidate in candidates.into_iter().rev() {
|
||||
match candidate {
|
||||
Candidate::Ref(Location { block, statement_index }) => {
|
||||
match mir[block].statements[statement_index].kind {
|
||||
match body[block].statements[statement_index].kind {
|
||||
StatementKind::Assign(Place::Base(PlaceBase::Local(local)), _) => {
|
||||
if temps[local] == TempState::PromotedOut {
|
||||
// Already promoted.
|
||||
|
@ -395,7 +395,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Body<'tcx>,
|
|||
|
||||
// Declare return place local so that `mir::Body::new` doesn't complain.
|
||||
let initial_locals = iter::once(
|
||||
LocalDecl::new_return_place(tcx.types.never, mir.span)
|
||||
LocalDecl::new_return_place(tcx.types.never, body.span)
|
||||
).collect();
|
||||
|
||||
let promoter = Promoter {
|
||||
|
@ -403,19 +403,19 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Body<'tcx>,
|
|||
IndexVec::new(),
|
||||
// FIXME: maybe try to filter this to avoid blowing up
|
||||
// memory usage?
|
||||
mir.source_scopes.clone(),
|
||||
mir.source_scope_local_data.clone(),
|
||||
body.source_scopes.clone(),
|
||||
body.source_scope_local_data.clone(),
|
||||
IndexVec::new(),
|
||||
None,
|
||||
initial_locals,
|
||||
IndexVec::new(),
|
||||
0,
|
||||
vec![],
|
||||
mir.span,
|
||||
body.span,
|
||||
vec![],
|
||||
),
|
||||
tcx,
|
||||
source: mir,
|
||||
source: body,
|
||||
temps: &mut temps,
|
||||
keep_original: false
|
||||
};
|
||||
|
@ -424,7 +424,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Body<'tcx>,
|
|||
|
||||
// Eliminate assignments to, and drops of promoted temps.
|
||||
let promoted = |index: Local| temps[index] == TempState::PromotedOut;
|
||||
for block in mir.basic_blocks_mut() {
|
||||
for block in body.basic_blocks_mut() {
|
||||
block.statements.retain(|statement| {
|
||||
match statement.kind {
|
||||
StatementKind::Assign(Place::Base(PlaceBase::Local(index)), _) |
|
||||
|
|
|
@ -113,7 +113,7 @@ struct ConstCx<'a, 'tcx> {
|
|||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
mode: Mode,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
|
||||
per_local: PerQualif<BitSet<Local>>,
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ trait Qualif {
|
|||
let base_qualif = Self::in_place(cx, &proj.base);
|
||||
let qualif = base_qualif && Self::mask_for_ty(
|
||||
cx,
|
||||
proj.base.ty(cx.mir, cx.tcx)
|
||||
proj.base.ty(cx.body, cx.tcx)
|
||||
.projection_ty(cx.tcx, &proj.elem)
|
||||
.ty,
|
||||
);
|
||||
|
@ -245,7 +245,7 @@ trait Qualif {
|
|||
// Special-case reborrows to be more like a copy of the reference.
|
||||
if let Place::Projection(ref proj) = *place {
|
||||
if let ProjectionElem::Deref = proj.elem {
|
||||
let base_ty = proj.base.ty(cx.mir, cx.tcx).ty;
|
||||
let base_ty = proj.base.ty(cx.body, cx.tcx).ty;
|
||||
if let ty::Ref(..) = base_ty.sty {
|
||||
return Self::in_place(cx, &proj.base);
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ impl Qualif for HasMutInterior {
|
|||
// allowed in constants (and the `Checker` will error), and/or it
|
||||
// won't be promoted, due to `&mut ...` or interior mutability.
|
||||
Rvalue::Ref(_, kind, ref place) => {
|
||||
let ty = place.ty(cx.mir, cx.tcx).ty;
|
||||
let ty = place.ty(cx.body, cx.tcx).ty;
|
||||
|
||||
if let BorrowKind::Mut { .. } = kind {
|
||||
// In theory, any zero-sized value could be borrowed
|
||||
|
@ -329,7 +329,7 @@ impl Qualif for HasMutInterior {
|
|||
Rvalue::Aggregate(ref kind, _) => {
|
||||
if let AggregateKind::Adt(def, ..) = **kind {
|
||||
if Some(def.did) == cx.tcx.lang_items().unsafe_cell_type() {
|
||||
let ty = rvalue.ty(cx.mir, cx.tcx);
|
||||
let ty = rvalue.ty(cx.body, cx.tcx);
|
||||
assert_eq!(Self::in_any_value_of_ty(cx, ty), Some(true));
|
||||
return true;
|
||||
}
|
||||
|
@ -399,7 +399,7 @@ impl Qualif for IsNotPromotable {
|
|||
|
||||
ProjectionElem::Field(..) => {
|
||||
if cx.mode == Mode::Fn {
|
||||
let base_ty = proj.base.ty(cx.mir, cx.tcx).ty;
|
||||
let base_ty = proj.base.ty(cx.body, cx.tcx).ty;
|
||||
if let Some(def) = base_ty.ty_adt_def() {
|
||||
if def.is_union() {
|
||||
return true;
|
||||
|
@ -415,7 +415,7 @@ impl Qualif for IsNotPromotable {
|
|||
fn in_rvalue(cx: &ConstCx<'_, 'tcx>, rvalue: &Rvalue<'tcx>) -> bool {
|
||||
match *rvalue {
|
||||
Rvalue::Cast(CastKind::Misc, ref operand, cast_ty) if cx.mode == Mode::Fn => {
|
||||
let operand_ty = operand.ty(cx.mir, cx.tcx);
|
||||
let operand_ty = operand.ty(cx.body, cx.tcx);
|
||||
let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
|
||||
let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
|
||||
match (cast_in, cast_out) {
|
||||
|
@ -429,7 +429,7 @@ impl Qualif for IsNotPromotable {
|
|||
}
|
||||
|
||||
Rvalue::BinaryOp(op, ref lhs, _) if cx.mode == Mode::Fn => {
|
||||
if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(cx.mir, cx.tcx).sty {
|
||||
if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(cx.body, cx.tcx).sty {
|
||||
assert!(op == BinOp::Eq || op == BinOp::Ne ||
|
||||
op == BinOp::Le || op == BinOp::Lt ||
|
||||
op == BinOp::Ge || op == BinOp::Gt ||
|
||||
|
@ -454,7 +454,7 @@ impl Qualif for IsNotPromotable {
|
|||
args: &[Operand<'tcx>],
|
||||
_return_ty: Ty<'tcx>,
|
||||
) -> bool {
|
||||
let fn_ty = callee.ty(cx.mir, cx.tcx);
|
||||
let fn_ty = callee.ty(cx.body, cx.tcx);
|
||||
match fn_ty.sty {
|
||||
ty::FnDef(def_id, _) => {
|
||||
match cx.tcx.fn_sig(def_id).abi() {
|
||||
|
@ -529,7 +529,7 @@ impl Qualif for IsNotImplicitlyPromotable {
|
|||
_return_ty: Ty<'tcx>,
|
||||
) -> bool {
|
||||
if cx.mode == Mode::Fn {
|
||||
if let ty::FnDef(def_id, _) = callee.ty(cx.mir, cx.tcx).sty {
|
||||
if let ty::FnDef(def_id, _) = callee.ty(cx.body, cx.tcx).sty {
|
||||
// Never promote runtime `const fn` calls of
|
||||
// functions without `#[rustc_promotable]`.
|
||||
if !cx.tcx.is_promotable_const_fn(def_id) {
|
||||
|
@ -620,12 +620,12 @@ impl Deref for Checker<'a, 'tcx> {
|
|||
impl<'a, 'tcx> Checker<'a, 'tcx> {
|
||||
fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
def_id: DefId,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
mode: Mode)
|
||||
-> Self {
|
||||
assert!(def_id.is_local());
|
||||
let mut rpo = traversal::reverse_postorder(mir);
|
||||
let temps = promote_consts::collect_temps(mir, &mut rpo);
|
||||
let mut rpo = traversal::reverse_postorder(body);
|
||||
let temps = promote_consts::collect_temps(body, &mut rpo);
|
||||
rpo.reset();
|
||||
|
||||
let param_env = tcx.param_env(def_id);
|
||||
|
@ -634,12 +634,12 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
|||
tcx,
|
||||
param_env,
|
||||
mode,
|
||||
mir,
|
||||
per_local: PerQualif::new(BitSet::new_empty(mir.local_decls.len())),
|
||||
body,
|
||||
per_local: PerQualif::new(BitSet::new_empty(body.local_decls.len())),
|
||||
};
|
||||
|
||||
for (local, decl) in mir.local_decls.iter_enumerated() {
|
||||
if let LocalKind::Arg = mir.local_kind(local) {
|
||||
for (local, decl) in body.local_decls.iter_enumerated() {
|
||||
if let LocalKind::Arg = body.local_kind(local) {
|
||||
let qualifs = cx.qualifs_in_any_value_of_ty(decl.ty);
|
||||
for (per_local, qualif) in &mut cx.per_local.as_mut().zip(qualifs).0 {
|
||||
if *qualif {
|
||||
|
@ -650,7 +650,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
|||
if !temps[local].is_promotable() {
|
||||
cx.per_local[IsNotPromotable].insert(local);
|
||||
}
|
||||
if let LocalKind::Var = mir.local_kind(local) {
|
||||
if let LocalKind::Var = body.local_kind(local) {
|
||||
// Sanity check to prevent implicit and explicit promotion of
|
||||
// named locals
|
||||
assert!(cx.per_local[IsNotPromotable].contains(local));
|
||||
|
@ -659,7 +659,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
|||
|
||||
Checker {
|
||||
cx,
|
||||
span: mir.span,
|
||||
span: body.span,
|
||||
def_id,
|
||||
rpo,
|
||||
temp_promotion_state: temps,
|
||||
|
@ -747,7 +747,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
|||
}
|
||||
debug!("qualify_consts: promotion candidate: place={:?}", place);
|
||||
if let Place::Base(PlaceBase::Local(local)) = *place {
|
||||
if self.mir.local_kind(local) == LocalKind::Temp {
|
||||
if self.body.local_kind(local) == LocalKind::Temp {
|
||||
debug!("qualify_consts: promotion candidate: local={:?}", local);
|
||||
// The borrowed place doesn't have `HasMutInterior`
|
||||
// (from `in_rvalue`), so we can safely ignore
|
||||
|
@ -799,7 +799,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
|||
}
|
||||
};
|
||||
|
||||
let kind = self.mir.local_kind(index);
|
||||
let kind = self.body.local_kind(index);
|
||||
debug!("store to {:?} {:?}", kind, index);
|
||||
|
||||
// Only handle promotable temps in non-const functions.
|
||||
|
@ -837,16 +837,16 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
|||
fn check_const(&mut self) -> (u8, &'tcx BitSet<Local>) {
|
||||
debug!("const-checking {} {:?}", self.mode, self.def_id);
|
||||
|
||||
let mir = self.mir;
|
||||
let body = self.body;
|
||||
|
||||
let mut seen_blocks = BitSet::new_empty(mir.basic_blocks().len());
|
||||
let mut seen_blocks = BitSet::new_empty(body.basic_blocks().len());
|
||||
let mut bb = START_BLOCK;
|
||||
loop {
|
||||
seen_blocks.insert(bb.index());
|
||||
|
||||
self.visit_basic_block_data(bb, &mir[bb]);
|
||||
self.visit_basic_block_data(bb, &body[bb]);
|
||||
|
||||
let target = match mir[bb].terminator().kind {
|
||||
let target = match body[bb].terminator().kind {
|
||||
TerminatorKind::Goto { target } |
|
||||
TerminatorKind::Drop { target, .. } |
|
||||
TerminatorKind::Assert { target, .. } |
|
||||
|
@ -894,7 +894,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
|||
for candidate in &self.promotion_candidates {
|
||||
match *candidate {
|
||||
Candidate::Ref(Location { block: bb, statement_index: stmt_idx }) => {
|
||||
match self.mir[bb].statements[stmt_idx].kind {
|
||||
match self.body[bb].statements[stmt_idx].kind {
|
||||
StatementKind::Assign(
|
||||
_,
|
||||
box Rvalue::Ref(_, _, Place::Base(PlaceBase::Local(index)))
|
||||
|
@ -913,7 +913,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
|
|||
// Account for errors in consts by using the
|
||||
// conservative type qualification instead.
|
||||
if qualifs[IsNotPromotable] {
|
||||
qualifs = self.qualifs_in_any_value_of_ty(mir.return_ty());
|
||||
qualifs = self.qualifs_in_any_value_of_ty(body.return_ty());
|
||||
}
|
||||
|
||||
(qualifs.encode_to_bits(), self.tcx.arena.alloc(promoted_temps))
|
||||
|
@ -1003,7 +1003,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
|
|||
// `not_const` errors out in const contexts
|
||||
self.not_const()
|
||||
}
|
||||
let base_ty = proj.base.ty(self.mir, self.tcx).ty;
|
||||
let base_ty = proj.base.ty(self.body, self.tcx).ty;
|
||||
match self.mode {
|
||||
Mode::Fn => {},
|
||||
_ => {
|
||||
|
@ -1027,7 +1027,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
|
|||
ProjectionElem::Subslice {..} |
|
||||
ProjectionElem::Field(..) |
|
||||
ProjectionElem::Index(_) => {
|
||||
let base_ty = proj.base.ty(self.mir, self.tcx).ty;
|
||||
let base_ty = proj.base.ty(self.body, self.tcx).ty;
|
||||
if let Some(def) = base_ty.ty_adt_def() {
|
||||
if def.is_union() {
|
||||
match self.mode {
|
||||
|
@ -1082,7 +1082,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
|
|||
let mut reborrow_place = None;
|
||||
if let Place::Projection(ref proj) = *place {
|
||||
if let ProjectionElem::Deref = proj.elem {
|
||||
let base_ty = proj.base.ty(self.mir, self.tcx).ty;
|
||||
let base_ty = proj.base.ty(self.body, self.tcx).ty;
|
||||
if let ty::Ref(..) = base_ty.sty {
|
||||
reborrow_place = Some(&proj.base);
|
||||
}
|
||||
|
@ -1126,7 +1126,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
|
|||
Rvalue::Aggregate(..) => {}
|
||||
|
||||
Rvalue::Cast(CastKind::Misc, ref operand, cast_ty) => {
|
||||
let operand_ty = operand.ty(self.mir, self.tcx);
|
||||
let operand_ty = operand.ty(self.body, self.tcx);
|
||||
let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
|
||||
let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
|
||||
match (cast_in, cast_out) {
|
||||
|
@ -1151,7 +1151,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
|
|||
}
|
||||
|
||||
Rvalue::BinaryOp(op, ref lhs, _) => {
|
||||
if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.mir, self.tcx).sty {
|
||||
if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.body, self.tcx).sty {
|
||||
assert!(op == BinOp::Eq || op == BinOp::Ne ||
|
||||
op == BinOp::Le || op == BinOp::Lt ||
|
||||
op == BinOp::Ge || op == BinOp::Gt ||
|
||||
|
@ -1201,11 +1201,11 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
|
|||
self.assign(dest, ValueSource::Call {
|
||||
callee: func,
|
||||
args,
|
||||
return_ty: dest.ty(self.mir, self.tcx).ty,
|
||||
return_ty: dest.ty(self.body, self.tcx).ty,
|
||||
}, location);
|
||||
}
|
||||
|
||||
let fn_ty = func.ty(self.mir, self.tcx);
|
||||
let fn_ty = func.ty(self.body, self.tcx);
|
||||
let mut callee_def_id = None;
|
||||
let mut is_shuffle = false;
|
||||
match fn_ty.sty {
|
||||
|
@ -1367,7 +1367,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
|
|||
// conservatively, that drop elaboration will do.
|
||||
let needs_drop = if let Place::Base(PlaceBase::Local(local)) = *place {
|
||||
if NeedsDrop::in_local(self, local) {
|
||||
Some(self.mir.local_decls[local].source_info.span)
|
||||
Some(self.body.local_decls[local].source_info.span)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -1377,7 +1377,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
|
|||
|
||||
if let Some(span) = needs_drop {
|
||||
// Double-check the type being dropped, to minimize false positives.
|
||||
let ty = place.ty(self.mir, self.tcx).ty;
|
||||
let ty = place.ty(self.body, self.tcx).ty;
|
||||
if ty.needs_drop(self.tcx, self.param_env) {
|
||||
struct_span_err!(self.tcx.sess, span, E0493,
|
||||
"destructors cannot be evaluated at compile-time")
|
||||
|
@ -1441,14 +1441,14 @@ fn mir_const_qualif<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
// cannot yet be stolen), because `mir_validated()`, which steals
|
||||
// from `mir_const(), forces this query to execute before
|
||||
// performing the steal.
|
||||
let mir = &tcx.mir_const(def_id).borrow();
|
||||
let body = &tcx.mir_const(def_id).borrow();
|
||||
|
||||
if mir.return_ty().references_error() {
|
||||
tcx.sess.delay_span_bug(mir.span, "mir_const_qualif: MIR had errors");
|
||||
if body.return_ty().references_error() {
|
||||
tcx.sess.delay_span_bug(body.span, "mir_const_qualif: MIR had errors");
|
||||
return (1 << IsNotPromotable::IDX, tcx.arena.alloc(BitSet::new_empty(0)));
|
||||
}
|
||||
|
||||
Checker::new(tcx, def_id, mir, Mode::Const).check_const()
|
||||
Checker::new(tcx, def_id, body, Mode::Const).check_const()
|
||||
}
|
||||
|
||||
pub struct QualifyAndPromoteConstants;
|
||||
|
@ -1457,10 +1457,10 @@ impl MirPass for QualifyAndPromoteConstants {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
body: &mut Body<'tcx>) {
|
||||
// There's not really any point in promoting errorful MIR.
|
||||
if mir.return_ty().references_error() {
|
||||
tcx.sess.delay_span_bug(mir.span, "QualifyAndPromoteConstants: MIR had errors");
|
||||
if body.return_ty().references_error() {
|
||||
tcx.sess.delay_span_bug(body.span, "QualifyAndPromoteConstants: MIR had errors");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1493,14 +1493,14 @@ impl MirPass for QualifyAndPromoteConstants {
|
|||
// This is ugly because Checker holds onto mir,
|
||||
// which can't be mutated until its scope ends.
|
||||
let (temps, candidates) = {
|
||||
let mut checker = Checker::new(tcx, def_id, mir, mode);
|
||||
let mut checker = Checker::new(tcx, def_id, body, mode);
|
||||
if mode == Mode::ConstFn {
|
||||
if tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you {
|
||||
checker.check_const();
|
||||
} else if tcx.is_min_const_fn(def_id) {
|
||||
// enforce `min_const_fn` for stable const fns
|
||||
use super::qualify_min_const_fn::is_min_const_fn;
|
||||
if let Err((span, err)) = is_min_const_fn(tcx, def_id, mir) {
|
||||
if let Err((span, err)) = is_min_const_fn(tcx, def_id, body) {
|
||||
let mut diag = struct_span_err!(
|
||||
tcx.sess,
|
||||
span,
|
||||
|
@ -1533,12 +1533,12 @@ impl MirPass for QualifyAndPromoteConstants {
|
|||
};
|
||||
|
||||
// Do the actual promotion, now that we know what's viable.
|
||||
promote_consts::promote_candidates(mir, tcx, temps, candidates);
|
||||
promote_consts::promote_candidates(body, tcx, temps, candidates);
|
||||
} else {
|
||||
if !mir.control_flow_destroyed.is_empty() {
|
||||
let mut locals = mir.vars_iter();
|
||||
if !body.control_flow_destroyed.is_empty() {
|
||||
let mut locals = body.vars_iter();
|
||||
if let Some(local) = locals.next() {
|
||||
let span = mir.local_decls[local].source_info.span;
|
||||
let span = body.local_decls[local].source_info.span;
|
||||
let mut error = tcx.sess.struct_span_err(
|
||||
span,
|
||||
&format!(
|
||||
|
@ -1547,7 +1547,7 @@ impl MirPass for QualifyAndPromoteConstants {
|
|||
mode,
|
||||
),
|
||||
);
|
||||
for (span, kind) in mir.control_flow_destroyed.iter() {
|
||||
for (span, kind) in body.control_flow_destroyed.iter() {
|
||||
error.span_note(
|
||||
*span,
|
||||
&format!("use of {} here does not actually short circuit due to \
|
||||
|
@ -1557,7 +1557,7 @@ impl MirPass for QualifyAndPromoteConstants {
|
|||
);
|
||||
}
|
||||
for local in locals {
|
||||
let span = mir.local_decls[local].source_info.span;
|
||||
let span = body.local_decls[local].source_info.span;
|
||||
error.span_note(
|
||||
span,
|
||||
"more locals defined here",
|
||||
|
@ -1570,14 +1570,14 @@ impl MirPass for QualifyAndPromoteConstants {
|
|||
// Already computed by `mir_const_qualif`.
|
||||
const_promoted_temps.unwrap()
|
||||
} else {
|
||||
Checker::new(tcx, def_id, mir, mode).check_const().1
|
||||
Checker::new(tcx, def_id, body, mode).check_const().1
|
||||
};
|
||||
|
||||
// In `const` and `static` everything without `StorageDead`
|
||||
// is `'static`, we don't have to create promoted MIR fragments,
|
||||
// just remove `Drop` and `StorageDead` on "promoted" locals.
|
||||
debug!("run_pass: promoted_temps={:?}", promoted_temps);
|
||||
for block in mir.basic_blocks_mut() {
|
||||
for block in body.basic_blocks_mut() {
|
||||
block.statements.retain(|statement| {
|
||||
match statement.kind {
|
||||
StatementKind::StorageDead(index) => {
|
||||
|
@ -1612,10 +1612,10 @@ impl MirPass for QualifyAndPromoteConstants {
|
|||
return;
|
||||
}
|
||||
}
|
||||
let ty = mir.return_ty();
|
||||
let ty = body.return_ty();
|
||||
tcx.infer_ctxt().enter(|infcx| {
|
||||
let param_env = ty::ParamEnv::empty();
|
||||
let cause = traits::ObligationCause::new(mir.span, id, traits::SharedStatic);
|
||||
let cause = traits::ObligationCause::new(body.span, id, traits::SharedStatic);
|
||||
let mut fulfillment_cx = traits::FulfillmentContext::new();
|
||||
fulfillment_cx.register_bound(&infcx,
|
||||
param_env,
|
||||
|
|
|
@ -11,7 +11,7 @@ type McfResult = Result<(), (Span, Cow<'static, str>)>;
|
|||
pub fn is_min_const_fn(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
def_id: DefId,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
) -> McfResult {
|
||||
let mut current = def_id;
|
||||
loop {
|
||||
|
@ -59,21 +59,21 @@ pub fn is_min_const_fn(
|
|||
}
|
||||
}
|
||||
|
||||
for local in &mir.local_decls {
|
||||
for local in &body.local_decls {
|
||||
check_ty(tcx, local.ty, local.source_info.span, def_id)?;
|
||||
}
|
||||
// impl trait is gone in MIR, so check the return type manually
|
||||
check_ty(
|
||||
tcx,
|
||||
tcx.fn_sig(def_id).output().skip_binder(),
|
||||
mir.local_decls.iter().next().unwrap().source_info.span,
|
||||
body.local_decls.iter().next().unwrap().source_info.span,
|
||||
def_id,
|
||||
)?;
|
||||
|
||||
for bb in mir.basic_blocks() {
|
||||
check_terminator(tcx, mir, bb.terminator())?;
|
||||
for bb in body.basic_blocks() {
|
||||
check_terminator(tcx, body, bb.terminator())?;
|
||||
for stmt in &bb.statements {
|
||||
check_statement(tcx, mir, stmt)?;
|
||||
check_statement(tcx, body, stmt)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -130,7 +130,7 @@ fn check_ty(
|
|||
|
||||
fn check_rvalue(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
rvalue: &Rvalue<'tcx>,
|
||||
span: Span,
|
||||
) -> McfResult {
|
||||
|
@ -143,7 +143,7 @@ fn check_rvalue(
|
|||
}
|
||||
Rvalue::Cast(CastKind::Misc, operand, cast_ty) => {
|
||||
use rustc::ty::cast::CastTy;
|
||||
let cast_in = CastTy::from_ty(operand.ty(mir, tcx)).expect("bad input type for cast");
|
||||
let cast_in = CastTy::from_ty(operand.ty(body, tcx)).expect("bad input type for cast");
|
||||
let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
|
||||
match (cast_in, cast_out) {
|
||||
(CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => Err((
|
||||
|
@ -173,7 +173,7 @@ fn check_rvalue(
|
|||
Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => {
|
||||
check_operand(lhs, span)?;
|
||||
check_operand(rhs, span)?;
|
||||
let ty = lhs.ty(mir, tcx);
|
||||
let ty = lhs.ty(body, tcx);
|
||||
if ty.is_integral() || ty.is_bool() || ty.is_char() {
|
||||
Ok(())
|
||||
} else {
|
||||
|
@ -189,7 +189,7 @@ fn check_rvalue(
|
|||
"heap allocations are not allowed in const fn".into(),
|
||||
)),
|
||||
Rvalue::UnaryOp(_, operand) => {
|
||||
let ty = operand.ty(mir, tcx);
|
||||
let ty = operand.ty(body, tcx);
|
||||
if ty.is_integral() || ty.is_bool() {
|
||||
check_operand(operand, span)
|
||||
} else {
|
||||
|
@ -210,14 +210,14 @@ fn check_rvalue(
|
|||
|
||||
fn check_statement(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
statement: &Statement<'tcx>,
|
||||
) -> McfResult {
|
||||
let span = statement.source_info.span;
|
||||
match &statement.kind {
|
||||
StatementKind::Assign(place, rval) => {
|
||||
check_place(place, span)?;
|
||||
check_rvalue(tcx, mir, rval, span)
|
||||
check_rvalue(tcx, body, rval, span)
|
||||
}
|
||||
|
||||
StatementKind::FakeRead(_, place) => check_place(place, span),
|
||||
|
@ -280,7 +280,7 @@ fn check_place(
|
|||
|
||||
fn check_terminator(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
terminator: &Terminator<'tcx>,
|
||||
) -> McfResult {
|
||||
let span = terminator.source_info.span;
|
||||
|
@ -315,7 +315,7 @@ fn check_terminator(
|
|||
destination: _,
|
||||
cleanup: _,
|
||||
} => {
|
||||
let fn_ty = func.ty(mir, tcx);
|
||||
let fn_ty = func.ty(body, tcx);
|
||||
if let ty::FnDef(def_id, _) = fn_ty.sty {
|
||||
|
||||
// some intrinsics are waved through if called inside the
|
||||
|
|
|
@ -11,22 +11,22 @@ pub struct RemoveNoopLandingPads;
|
|||
|
||||
pub fn remove_noop_landing_pads<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &mut Body<'tcx>)
|
||||
body: &mut Body<'tcx>)
|
||||
{
|
||||
if tcx.sess.no_landing_pads() {
|
||||
return
|
||||
}
|
||||
debug!("remove_noop_landing_pads({:?})", mir);
|
||||
debug!("remove_noop_landing_pads({:?})", body);
|
||||
|
||||
RemoveNoopLandingPads.remove_nop_landing_pads(mir)
|
||||
RemoveNoopLandingPads.remove_nop_landing_pads(body)
|
||||
}
|
||||
|
||||
impl MirPass for RemoveNoopLandingPads {
|
||||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_src: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
remove_noop_landing_pads(tcx, mir);
|
||||
body: &mut Body<'tcx>) {
|
||||
remove_noop_landing_pads(tcx, body);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,10 +34,10 @@ impl RemoveNoopLandingPads {
|
|||
fn is_nop_landing_pad(
|
||||
&self,
|
||||
bb: BasicBlock,
|
||||
mir: &Body<'_>,
|
||||
body: &Body<'_>,
|
||||
nop_landing_pads: &BitSet<BasicBlock>,
|
||||
) -> bool {
|
||||
for stmt in &mir[bb].statements {
|
||||
for stmt in &body[bb].statements {
|
||||
match stmt.kind {
|
||||
StatementKind::FakeRead(..) |
|
||||
StatementKind::StorageLive(_) |
|
||||
|
@ -61,7 +61,7 @@ impl RemoveNoopLandingPads {
|
|||
}
|
||||
}
|
||||
|
||||
let terminator = mir[bb].terminator();
|
||||
let terminator = body[bb].terminator();
|
||||
match terminator.kind {
|
||||
TerminatorKind::Goto { .. } |
|
||||
TerminatorKind::Resume |
|
||||
|
@ -86,26 +86,26 @@ impl RemoveNoopLandingPads {
|
|||
}
|
||||
}
|
||||
|
||||
fn remove_nop_landing_pads(&self, mir: &mut Body<'_>) {
|
||||
fn remove_nop_landing_pads(&self, body: &mut Body<'_>) {
|
||||
// make sure there's a single resume block
|
||||
let resume_block = {
|
||||
let patch = MirPatch::new(mir);
|
||||
let patch = MirPatch::new(body);
|
||||
let resume_block = patch.resume_block();
|
||||
patch.apply(mir);
|
||||
patch.apply(body);
|
||||
resume_block
|
||||
};
|
||||
debug!("remove_noop_landing_pads: resume block is {:?}", resume_block);
|
||||
|
||||
let mut jumps_folded = 0;
|
||||
let mut landing_pads_removed = 0;
|
||||
let mut nop_landing_pads = BitSet::new_empty(mir.basic_blocks().len());
|
||||
let mut nop_landing_pads = BitSet::new_empty(body.basic_blocks().len());
|
||||
|
||||
// This is a post-order traversal, so that if A post-dominates B
|
||||
// then A will be visited before B.
|
||||
let postorder: Vec<_> = traversal::postorder(mir).map(|(bb, _)| bb).collect();
|
||||
let postorder: Vec<_> = traversal::postorder(body).map(|(bb, _)| bb).collect();
|
||||
for bb in postorder {
|
||||
debug!(" processing {:?}", bb);
|
||||
for target in mir[bb].terminator_mut().successors_mut() {
|
||||
for target in body[bb].terminator_mut().successors_mut() {
|
||||
if *target != resume_block && nop_landing_pads.contains(*target) {
|
||||
debug!(" folding noop jump to {:?} to resume block", target);
|
||||
*target = resume_block;
|
||||
|
@ -113,7 +113,7 @@ impl RemoveNoopLandingPads {
|
|||
}
|
||||
}
|
||||
|
||||
match mir[bb].terminator_mut().unwind_mut() {
|
||||
match body[bb].terminator_mut().unwind_mut() {
|
||||
Some(unwind) => {
|
||||
if *unwind == Some(resume_block) {
|
||||
debug!(" removing noop landing pad");
|
||||
|
@ -125,7 +125,7 @@ impl RemoveNoopLandingPads {
|
|||
_ => {}
|
||||
}
|
||||
|
||||
let is_nop_landing_pad = self.is_nop_landing_pad(bb, mir, &nop_landing_pads);
|
||||
let is_nop_landing_pad = self.is_nop_landing_pad(bb, body, &nop_landing_pads);
|
||||
if is_nop_landing_pad {
|
||||
nop_landing_pads.insert(bb);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ pub struct SanityCheck;
|
|||
|
||||
impl MirPass for SanityCheck {
|
||||
fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource<'tcx>, mir: &mut Body<'tcx>) {
|
||||
src: MirSource<'tcx>, body: &mut Body<'tcx>) {
|
||||
let def_id = src.def_id();
|
||||
if !tcx.has_attr(def_id, sym::rustc_mir) {
|
||||
debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
|
||||
|
@ -37,30 +37,30 @@ impl MirPass for SanityCheck {
|
|||
|
||||
let attributes = tcx.get_attrs(def_id);
|
||||
let param_env = tcx.param_env(def_id);
|
||||
let move_data = MoveData::gather_moves(mir, tcx).unwrap();
|
||||
let move_data = MoveData::gather_moves(body, tcx).unwrap();
|
||||
let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
|
||||
let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len());
|
||||
let dead_unwinds = BitSet::new_empty(body.basic_blocks().len());
|
||||
let flow_inits =
|
||||
do_dataflow(tcx, mir, def_id, &attributes, &dead_unwinds,
|
||||
MaybeInitializedPlaces::new(tcx, mir, &mdpe),
|
||||
do_dataflow(tcx, body, def_id, &attributes, &dead_unwinds,
|
||||
MaybeInitializedPlaces::new(tcx, body, &mdpe),
|
||||
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
|
||||
let flow_uninits =
|
||||
do_dataflow(tcx, mir, def_id, &attributes, &dead_unwinds,
|
||||
MaybeUninitializedPlaces::new(tcx, mir, &mdpe),
|
||||
do_dataflow(tcx, body, def_id, &attributes, &dead_unwinds,
|
||||
MaybeUninitializedPlaces::new(tcx, body, &mdpe),
|
||||
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
|
||||
let flow_def_inits =
|
||||
do_dataflow(tcx, mir, def_id, &attributes, &dead_unwinds,
|
||||
DefinitelyInitializedPlaces::new(tcx, mir, &mdpe),
|
||||
do_dataflow(tcx, body, def_id, &attributes, &dead_unwinds,
|
||||
DefinitelyInitializedPlaces::new(tcx, body, &mdpe),
|
||||
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]));
|
||||
|
||||
if has_rustc_mir_with(&attributes, sym::rustc_peek_maybe_init).is_some() {
|
||||
sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_inits);
|
||||
sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_inits);
|
||||
}
|
||||
if has_rustc_mir_with(&attributes, sym::rustc_peek_maybe_uninit).is_some() {
|
||||
sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_uninits);
|
||||
sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_uninits);
|
||||
}
|
||||
if has_rustc_mir_with(&attributes, sym::rustc_peek_definite_init).is_some() {
|
||||
sanity_check_via_rustc_peek(tcx, mir, def_id, &attributes, &flow_def_inits);
|
||||
sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_def_inits);
|
||||
}
|
||||
if has_rustc_mir_with(&attributes, sym::stop_after_dataflow).is_some() {
|
||||
tcx.sess.fatal("stop_after_dataflow ended compilation");
|
||||
|
@ -85,7 +85,7 @@ impl MirPass for SanityCheck {
|
|||
/// expression form above, then that emits an error as well, but those
|
||||
/// errors are not intended to be used for unit tests.)
|
||||
pub fn sanity_check_via_rustc_peek<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
def_id: DefId,
|
||||
_attributes: &[ast::Attribute],
|
||||
results: &DataflowResults<'tcx, O>)
|
||||
|
@ -96,19 +96,19 @@ pub fn sanity_check_via_rustc_peek<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
// `dataflow::build_sets`. (But note it is doing non-standard
|
||||
// stuff, so such generalization may not be realistic.)
|
||||
|
||||
for bb in mir.basic_blocks().indices() {
|
||||
each_block(tcx, mir, results, bb);
|
||||
for bb in body.basic_blocks().indices() {
|
||||
each_block(tcx, body, results, bb);
|
||||
}
|
||||
}
|
||||
|
||||
fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
results: &DataflowResults<'tcx, O>,
|
||||
bb: mir::BasicBlock) where
|
||||
O: BitDenotation<'tcx, Idx=MovePathIndex> + HasMoveData<'tcx>
|
||||
{
|
||||
let move_data = results.0.operator.move_data();
|
||||
let mir::BasicBlockData { ref statements, ref terminator, is_cleanup: _ } = mir[bb];
|
||||
let mir::BasicBlockData { ref statements, ref terminator, is_cleanup: _ } = body[bb];
|
||||
|
||||
let (args, span) = match is_rustc_peek(tcx, terminator) {
|
||||
Some(args_and_span) => args_and_span,
|
||||
|
|
|
@ -44,12 +44,12 @@ impl SimplifyCfg {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn simplify_cfg(mir: &mut Body<'_>) {
|
||||
CfgSimplifier::new(mir).simplify();
|
||||
remove_dead_blocks(mir);
|
||||
pub fn simplify_cfg(body: &mut Body<'_>) {
|
||||
CfgSimplifier::new(body).simplify();
|
||||
remove_dead_blocks(body);
|
||||
|
||||
// FIXME: Should probably be moved into some kind of pass manager
|
||||
mir.basic_blocks_mut().raw.shrink_to_fit();
|
||||
body.basic_blocks_mut().raw.shrink_to_fit();
|
||||
}
|
||||
|
||||
impl MirPass for SimplifyCfg {
|
||||
|
@ -60,9 +60,9 @@ impl MirPass for SimplifyCfg {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_src: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, mir);
|
||||
simplify_cfg(mir);
|
||||
body: &mut Body<'tcx>) {
|
||||
debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, body);
|
||||
simplify_cfg(body);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,14 +72,14 @@ pub struct CfgSimplifier<'a, 'tcx: 'a> {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> {
|
||||
pub fn new(mir: &'a mut Body<'tcx>) -> Self {
|
||||
let mut pred_count = IndexVec::from_elem(0u32, mir.basic_blocks());
|
||||
pub fn new(body: &'a mut Body<'tcx>) -> Self {
|
||||
let mut pred_count = IndexVec::from_elem(0u32, body.basic_blocks());
|
||||
|
||||
// we can't use mir.predecessors() here because that counts
|
||||
// dead blocks, which we don't want to.
|
||||
pred_count[START_BLOCK] = 1;
|
||||
|
||||
for (_, data) in traversal::preorder(mir) {
|
||||
for (_, data) in traversal::preorder(body) {
|
||||
if let Some(ref term) = data.terminator {
|
||||
for &tgt in term.successors() {
|
||||
pred_count[tgt] += 1;
|
||||
|
@ -87,7 +87,7 @@ impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
let basic_blocks = mir.basic_blocks_mut();
|
||||
let basic_blocks = body.basic_blocks_mut();
|
||||
|
||||
CfgSimplifier {
|
||||
basic_blocks,
|
||||
|
@ -263,13 +263,13 @@ impl<'a, 'tcx: 'a> CfgSimplifier<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn remove_dead_blocks(mir: &mut Body<'_>) {
|
||||
let mut seen = BitSet::new_empty(mir.basic_blocks().len());
|
||||
for (bb, _) in traversal::preorder(mir) {
|
||||
pub fn remove_dead_blocks(body: &mut Body<'_>) {
|
||||
let mut seen = BitSet::new_empty(body.basic_blocks().len());
|
||||
for (bb, _) in traversal::preorder(body) {
|
||||
seen.insert(bb.index());
|
||||
}
|
||||
|
||||
let basic_blocks = mir.basic_blocks_mut();
|
||||
let basic_blocks = body.basic_blocks_mut();
|
||||
|
||||
let num_blocks = basic_blocks.len();
|
||||
let mut replacements : Vec<_> = (0..num_blocks).map(BasicBlock::new).collect();
|
||||
|
@ -299,26 +299,26 @@ impl MirPass for SimplifyLocals {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
let mut marker = DeclMarker { locals: BitSet::new_empty(mir.local_decls.len()) };
|
||||
marker.visit_body(mir);
|
||||
body: &mut Body<'tcx>) {
|
||||
let mut marker = DeclMarker { locals: BitSet::new_empty(body.local_decls.len()) };
|
||||
marker.visit_body(body);
|
||||
// Return pointer and arguments are always live
|
||||
marker.locals.insert(RETURN_PLACE);
|
||||
for arg in mir.args_iter() {
|
||||
for arg in body.args_iter() {
|
||||
marker.locals.insert(arg);
|
||||
}
|
||||
|
||||
// We may need to keep dead user variables live for debuginfo.
|
||||
if tcx.sess.opts.debuginfo == DebugInfo::Full {
|
||||
for local in mir.vars_iter() {
|
||||
for local in body.vars_iter() {
|
||||
marker.locals.insert(local);
|
||||
}
|
||||
}
|
||||
|
||||
let map = make_local_map(&mut mir.local_decls, marker.locals);
|
||||
let map = make_local_map(&mut body.local_decls, marker.locals);
|
||||
// Update references to all vars and tmps now
|
||||
LocalUpdater { map }.visit_body(mir);
|
||||
mir.local_decls.shrink_to_fit();
|
||||
LocalUpdater { map }.visit_body(body);
|
||||
body.local_decls.shrink_to_fit();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@ impl MirPass for SimplifyBranches {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_src: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
for block in mir.basic_blocks_mut() {
|
||||
body: &mut Body<'tcx>) {
|
||||
for block in body.basic_blocks_mut() {
|
||||
let terminator = block.terminator_mut();
|
||||
terminator.kind = match terminator.kind {
|
||||
TerminatorKind::SwitchInt {
|
||||
|
|
|
@ -40,18 +40,18 @@ impl MirPass for UniformArrayMoveOut {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_src: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
let mut patch = MirPatch::new(mir);
|
||||
body: &mut Body<'tcx>) {
|
||||
let mut patch = MirPatch::new(body);
|
||||
{
|
||||
let mut visitor = UniformArrayMoveOutVisitor{mir, patch: &mut patch, tcx};
|
||||
visitor.visit_body(mir);
|
||||
let mut visitor = UniformArrayMoveOutVisitor{body, patch: &mut patch, tcx};
|
||||
visitor.visit_body(body);
|
||||
}
|
||||
patch.apply(mir);
|
||||
patch.apply(body);
|
||||
}
|
||||
}
|
||||
|
||||
struct UniformArrayMoveOutVisitor<'a, 'tcx: 'a> {
|
||||
mir: &'a Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
patch: &'a mut MirPatch<'tcx>,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UniformArrayMoveOutVisitor<'a, 'tcx> {
|
|||
from_end: false} = proj.elem {
|
||||
// no need to transformation
|
||||
} else {
|
||||
let place_ty = proj.base.ty(self.mir, self.tcx).ty;
|
||||
let place_ty = proj.base.ty(self.body, self.tcx).ty;
|
||||
if let ty::Array(item_ty, const_size) = place_ty.sty {
|
||||
if let Some(size) = const_size.assert_usize(self.tcx) {
|
||||
assert!(size <= u32::max_value() as u64,
|
||||
|
@ -97,7 +97,7 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> {
|
|||
ProjectionElem::Subslice{from, to} => {
|
||||
self.patch.make_nop(location);
|
||||
let temps : Vec<_> = (from..(size-to)).map(|i| {
|
||||
let temp = self.patch.new_temp(item_ty, self.mir.source_info(location).span);
|
||||
let temp = self.patch.new_temp(item_ty, self.body.source_info(location).span);
|
||||
self.patch.add_statement(location, StatementKind::StorageLive(temp));
|
||||
self.patch.add_assign(location,
|
||||
Place::Base(PlaceBase::Local(temp)),
|
||||
|
@ -165,23 +165,24 @@ impl MirPass for RestoreSubsliceArrayMoveOut {
|
|||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_src: MirSource<'tcx>,
|
||||
mir: &mut Body<'tcx>) {
|
||||
let mut patch = MirPatch::new(mir);
|
||||
body: &mut Body<'tcx>) {
|
||||
let mut patch = MirPatch::new(body);
|
||||
{
|
||||
let mut visitor = RestoreDataCollector {
|
||||
locals_use: IndexVec::from_elem(LocalUse::new(), &mir.local_decls),
|
||||
locals_use: IndexVec::from_elem(LocalUse::new(), &body.local_decls),
|
||||
candidates: vec![],
|
||||
};
|
||||
visitor.visit_body(mir);
|
||||
visitor.visit_body(body);
|
||||
|
||||
for candidate in &visitor.candidates {
|
||||
let statement = &mir[candidate.block].statements[candidate.statement_index];
|
||||
let statement = &body[candidate.block].statements[candidate.statement_index];
|
||||
if let StatementKind::Assign(ref dst_place, ref rval) = statement.kind {
|
||||
if let Rvalue::Aggregate(box AggregateKind::Array(_), ref items) = **rval {
|
||||
let items : Vec<_> = items.iter().map(|item| {
|
||||
if let Operand::Move(Place::Base(PlaceBase::Local(local))) = item {
|
||||
let local_use = &visitor.locals_use[*local];
|
||||
let opt_index_and_place = Self::try_get_item_source(local_use, mir);
|
||||
let opt_index_and_place =
|
||||
Self::try_get_item_source(local_use, body);
|
||||
// each local should be used twice:
|
||||
// in assign and in aggregate statements
|
||||
if local_use.use_count == 2 && opt_index_and_place.is_some() {
|
||||
|
@ -194,7 +195,7 @@ impl MirPass for RestoreSubsliceArrayMoveOut {
|
|||
|
||||
let opt_src_place = items.first().and_then(|x| *x).map(|x| x.2);
|
||||
let opt_size = opt_src_place.and_then(|src_place| {
|
||||
let src_ty = src_place.ty(mir, tcx).ty;
|
||||
let src_ty = src_place.ty(body, tcx).ty;
|
||||
if let ty::Array(_, ref size_o) = src_ty.sty {
|
||||
size_o.assert_usize(tcx)
|
||||
} else {
|
||||
|
@ -206,7 +207,7 @@ impl MirPass for RestoreSubsliceArrayMoveOut {
|
|||
}
|
||||
}
|
||||
}
|
||||
patch.apply(mir);
|
||||
patch.apply(body);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,9 +255,9 @@ impl RestoreSubsliceArrayMoveOut {
|
|||
}
|
||||
|
||||
fn try_get_item_source<'a, 'tcx>(local_use: &LocalUse,
|
||||
mir: &'a Body<'tcx>) -> Option<(u32, &'a Place<'tcx>)> {
|
||||
body: &'a Body<'tcx>) -> Option<(u32, &'a Place<'tcx>)> {
|
||||
if let Some(location) = local_use.first_use {
|
||||
let block = &mir[location.block];
|
||||
let block = &body[location.block];
|
||||
if block.statements.len() > location.statement_index {
|
||||
let statement = &block.statements[location.statement_index];
|
||||
if let StatementKind::Assign(
|
||||
|
|
|
@ -21,19 +21,19 @@ pub struct Use {
|
|||
}
|
||||
|
||||
impl DefUseAnalysis {
|
||||
pub fn new(mir: &Body<'_>) -> DefUseAnalysis {
|
||||
pub fn new(body: &Body<'_>) -> DefUseAnalysis {
|
||||
DefUseAnalysis {
|
||||
info: IndexVec::from_elem_n(Info::new(), mir.local_decls.len()),
|
||||
info: IndexVec::from_elem_n(Info::new(), body.local_decls.len()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn analyze(&mut self, mir: &Body<'_>) {
|
||||
pub fn analyze(&mut self, body: &Body<'_>) {
|
||||
self.clear();
|
||||
|
||||
let mut finder = DefUseFinder {
|
||||
info: mem::replace(&mut self.info, IndexVec::new()),
|
||||
};
|
||||
finder.visit_body(mir);
|
||||
finder.visit_body(body);
|
||||
self.info = finder.info
|
||||
}
|
||||
|
||||
|
@ -47,23 +47,23 @@ impl DefUseAnalysis {
|
|||
&self.info[local]
|
||||
}
|
||||
|
||||
fn mutate_defs_and_uses<F>(&self, local: Local, mir: &mut Body<'_>, mut callback: F)
|
||||
fn mutate_defs_and_uses<F>(&self, local: Local, body: &mut Body<'_>, mut callback: F)
|
||||
where F: for<'a> FnMut(&'a mut Local,
|
||||
PlaceContext,
|
||||
Location) {
|
||||
for place_use in &self.info[local].defs_and_uses {
|
||||
MutateUseVisitor::new(local,
|
||||
&mut callback,
|
||||
mir).visit_location(mir, place_use.location)
|
||||
body).visit_location(body, place_use.location)
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(pcwalton): this should update the def-use chains.
|
||||
pub fn replace_all_defs_and_uses_with(&self,
|
||||
local: Local,
|
||||
mir: &mut Body<'_>,
|
||||
body: &mut Body<'_>,
|
||||
new_local: Local) {
|
||||
self.mutate_defs_and_uses(local, mir, |local, _, _| *local = new_local)
|
||||
self.mutate_defs_and_uses(local, body, |local, _, _| *local = new_local)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ pub trait DropElaborator<'a, 'tcx: 'a> : fmt::Debug {
|
|||
type Path : Copy + fmt::Debug;
|
||||
|
||||
fn patch(&mut self) -> &mut MirPatch<'tcx>;
|
||||
fn mir(&self) -> &'a Body<'tcx>;
|
||||
fn body(&self) -> &'a Body<'tcx>;
|
||||
fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx>;
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx>;
|
||||
|
||||
|
@ -122,7 +122,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
|||
where D: DropElaborator<'b, 'tcx>
|
||||
{
|
||||
fn place_ty(&self, place: &Place<'tcx>) -> Ty<'tcx> {
|
||||
place.ty(self.elaborator.mir(), self.tcx()).ty
|
||||
place.ty(self.elaborator.body(), self.tcx()).ty
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'b, 'tcx, 'tcx> {
|
||||
|
@ -799,7 +799,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
|||
// within that own generator's resume function.
|
||||
// This should only happen for the self argument on the resume function.
|
||||
// It effetively only contains upvars until the generator transformation runs.
|
||||
// See librustc_mir/transform/generator.rs for more details.
|
||||
// See librustc_body/transform/generator.rs for more details.
|
||||
ty::Generator(def_id, substs, _) => {
|
||||
let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx()).collect();
|
||||
self.open_drop_for_tuple(&tys)
|
||||
|
@ -966,8 +966,8 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
|||
}
|
||||
|
||||
fn terminator_loc(&mut self, bb: BasicBlock) -> Location {
|
||||
let mir = self.elaborator.mir();
|
||||
self.elaborator.patch().terminator_loc(mir, bb)
|
||||
let body = self.elaborator.body();
|
||||
self.elaborator.patch().terminator_loc(body, bb)
|
||||
}
|
||||
|
||||
fn constant_usize(&self, val: u16) -> Operand<'tcx> {
|
||||
|
|
|
@ -15,8 +15,8 @@ pub fn write_mir_graphviz<'tcx, W>(tcx: TyCtxt<'_, '_, 'tcx>,
|
|||
where W: Write
|
||||
{
|
||||
for def_id in dump_mir_def_ids(tcx, single) {
|
||||
let mir = &tcx.optimized_mir(def_id);
|
||||
write_mir_fn_graphviz(tcx, def_id, mir, w)?;
|
||||
let body = &tcx.optimized_mir(def_id);
|
||||
write_mir_fn_graphviz(tcx, def_id, body, w)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ pub fn graphviz_safe_def_name(def_id: DefId) -> String {
|
|||
/// Write a graphviz DOT graph of the MIR.
|
||||
pub fn write_mir_fn_graphviz<'tcx, W>(tcx: TyCtxt<'_, '_, 'tcx>,
|
||||
def_id: DefId,
|
||||
mir: &Body<'_>,
|
||||
body: &Body<'_>,
|
||||
w: &mut W) -> io::Result<()>
|
||||
where W: Write
|
||||
{
|
||||
|
@ -46,16 +46,16 @@ pub fn write_mir_fn_graphviz<'tcx, W>(tcx: TyCtxt<'_, '_, 'tcx>,
|
|||
writeln!(w, r#" edge [fontname="monospace"];"#)?;
|
||||
|
||||
// Graph label
|
||||
write_graph_label(tcx, def_id, mir, w)?;
|
||||
write_graph_label(tcx, def_id, body, w)?;
|
||||
|
||||
// Nodes
|
||||
for (block, _) in mir.basic_blocks().iter_enumerated() {
|
||||
write_node(block, mir, w)?;
|
||||
for (block, _) in body.basic_blocks().iter_enumerated() {
|
||||
write_node(block, body, w)?;
|
||||
}
|
||||
|
||||
// Edges
|
||||
for (source, _) in mir.basic_blocks().iter_enumerated() {
|
||||
write_edges(source, mir, w)?;
|
||||
for (source, _) in body.basic_blocks().iter_enumerated() {
|
||||
write_edges(source, body, w)?;
|
||||
}
|
||||
writeln!(w, "}}")
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ pub fn write_mir_fn_graphviz<'tcx, W>(tcx: TyCtxt<'_, '_, 'tcx>,
|
|||
/// `init` and `fini` are callbacks for emitting additional rows of
|
||||
/// data (using HTML enclosed with `<tr>` in the emitted text).
|
||||
pub fn write_node_label<W: Write, INIT, FINI>(block: BasicBlock,
|
||||
mir: &Body<'_>,
|
||||
body: &Body<'_>,
|
||||
w: &mut W,
|
||||
num_cols: u32,
|
||||
init: INIT,
|
||||
|
@ -76,7 +76,7 @@ pub fn write_node_label<W: Write, INIT, FINI>(block: BasicBlock,
|
|||
where INIT: Fn(&mut W) -> io::Result<()>,
|
||||
FINI: Fn(&mut W) -> io::Result<()>
|
||||
{
|
||||
let data = &mir[block];
|
||||
let data = &body[block];
|
||||
|
||||
write!(w, r#"<table border="0" cellborder="1" cellspacing="0">"#)?;
|
||||
|
||||
|
@ -110,17 +110,17 @@ pub fn write_node_label<W: Write, INIT, FINI>(block: BasicBlock,
|
|||
}
|
||||
|
||||
/// Write a graphviz DOT node for the given basic block.
|
||||
fn write_node<W: Write>(block: BasicBlock, mir: &Body<'_>, w: &mut W) -> io::Result<()> {
|
||||
fn write_node<W: Write>(block: BasicBlock, body: &Body<'_>, w: &mut W) -> io::Result<()> {
|
||||
// Start a new node with the label to follow, in one of DOT's pseudo-HTML tables.
|
||||
write!(w, r#" {} [shape="none", label=<"#, node(block))?;
|
||||
write_node_label(block, mir, w, 1, |_| Ok(()), |_| Ok(()))?;
|
||||
write_node_label(block, body, w, 1, |_| Ok(()), |_| Ok(()))?;
|
||||
// Close the node label and the node itself.
|
||||
writeln!(w, ">];")
|
||||
}
|
||||
|
||||
/// Write graphviz DOT edges with labels between the given basic block and all of its successors.
|
||||
fn write_edges<W: Write>(source: BasicBlock, mir: &Body<'_>, w: &mut W) -> io::Result<()> {
|
||||
let terminator = mir[source].terminator();
|
||||
fn write_edges<W: Write>(source: BasicBlock, body: &Body<'_>, w: &mut W) -> io::Result<()> {
|
||||
let terminator = body[source].terminator();
|
||||
let labels = terminator.kind.fmt_successor_labels();
|
||||
|
||||
for (&target, label) in terminator.successors().zip(labels) {
|
||||
|
@ -135,28 +135,28 @@ fn write_edges<W: Write>(source: BasicBlock, mir: &Body<'_>, w: &mut W) -> io::R
|
|||
/// all the variables and temporaries.
|
||||
fn write_graph_label<'a, 'gcx, 'tcx, W: Write>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
def_id: DefId,
|
||||
mir: &Body<'_>,
|
||||
body: &Body<'_>,
|
||||
w: &mut W)
|
||||
-> io::Result<()> {
|
||||
write!(w, " label=<fn {}(", dot::escape_html(&tcx.def_path_str(def_id)))?;
|
||||
|
||||
// fn argument types.
|
||||
for (i, arg) in mir.args_iter().enumerate() {
|
||||
for (i, arg) in body.args_iter().enumerate() {
|
||||
if i > 0 {
|
||||
write!(w, ", ")?;
|
||||
}
|
||||
write!(w,
|
||||
"{:?}: {}",
|
||||
Place::Base(PlaceBase::Local(arg)),
|
||||
escape(&mir.local_decls[arg].ty)
|
||||
escape(&body.local_decls[arg].ty)
|
||||
)?;
|
||||
}
|
||||
|
||||
write!(w, ") -> {}", escape(&mir.return_ty()))?;
|
||||
write!(w, ") -> {}", escape(&body.return_ty()))?;
|
||||
write!(w, r#"<br align="left"/>"#)?;
|
||||
|
||||
for local in mir.vars_and_temps_iter() {
|
||||
let decl = &mir.local_decls[local];
|
||||
for local in body.vars_and_temps_iter() {
|
||||
let decl = &body.local_decls[local];
|
||||
|
||||
write!(w, "let ")?;
|
||||
if decl.mutability == Mutability::Mut {
|
||||
|
|
|
@ -57,17 +57,17 @@ pub struct LivenessResult {
|
|||
/// Computes which local variables are live within the given function
|
||||
/// `mir`, including drops.
|
||||
pub fn liveness_of_locals<'tcx>(
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
) -> LivenessResult {
|
||||
let num_live_vars = mir.local_decls.len();
|
||||
let num_live_vars = body.local_decls.len();
|
||||
|
||||
let def_use: IndexVec<_, DefsUses> = mir
|
||||
let def_use: IndexVec<_, DefsUses> = body
|
||||
.basic_blocks()
|
||||
.iter()
|
||||
.map(|b| block(b, num_live_vars))
|
||||
.collect();
|
||||
|
||||
let mut outs: IndexVec<_, LiveVarSet> = mir
|
||||
let mut outs: IndexVec<_, LiveVarSet> = body
|
||||
.basic_blocks()
|
||||
.indices()
|
||||
.map(|_| LiveVarSet::new_empty(num_live_vars))
|
||||
|
@ -77,9 +77,9 @@ pub fn liveness_of_locals<'tcx>(
|
|||
|
||||
// queue of things that need to be re-processed, and a set containing
|
||||
// the things currently in the queue
|
||||
let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_all(mir.basic_blocks().len());
|
||||
let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_all(body.basic_blocks().len());
|
||||
|
||||
let predecessors = mir.predecessors();
|
||||
let predecessors = body.predecessors();
|
||||
|
||||
while let Some(bb) = dirty_queue.pop() {
|
||||
// bits = use ∪ (bits - def)
|
||||
|
@ -258,7 +258,7 @@ pub fn dump_mir<'a, 'tcx>(
|
|||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pass_name: &str,
|
||||
source: MirSource<'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
result: &LivenessResult,
|
||||
) {
|
||||
if !dump_enabled(tcx, pass_name, source) {
|
||||
|
@ -268,7 +268,7 @@ pub fn dump_mir<'a, 'tcx>(
|
|||
// see notes on #41697 below
|
||||
tcx.def_path_str(source.def_id())
|
||||
});
|
||||
dump_matched_mir_node(tcx, pass_name, &node_path, source, mir, result);
|
||||
dump_matched_mir_node(tcx, pass_name, &node_path, source, body, result);
|
||||
}
|
||||
|
||||
fn dump_matched_mir_node<'a, 'tcx>(
|
||||
|
@ -276,7 +276,7 @@ fn dump_matched_mir_node<'a, 'tcx>(
|
|||
pass_name: &str,
|
||||
node_path: &str,
|
||||
source: MirSource<'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
result: &LivenessResult,
|
||||
) {
|
||||
let mut file_path = PathBuf::new();
|
||||
|
@ -289,7 +289,7 @@ fn dump_matched_mir_node<'a, 'tcx>(
|
|||
writeln!(file, "// source = {:?}", source)?;
|
||||
writeln!(file, "// pass_name = {}", pass_name)?;
|
||||
writeln!(file, "")?;
|
||||
write_mir_fn(tcx, source, mir, &mut file, result)?;
|
||||
write_mir_fn(tcx, source, body, &mut file, result)?;
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
|
@ -297,12 +297,12 @@ fn dump_matched_mir_node<'a, 'tcx>(
|
|||
pub fn write_mir_fn<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource<'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
w: &mut dyn Write,
|
||||
result: &LivenessResult,
|
||||
) -> io::Result<()> {
|
||||
write_mir_intro(tcx, src, mir, w)?;
|
||||
for block in mir.basic_blocks().indices() {
|
||||
write_mir_intro(tcx, src, body, w)?;
|
||||
for block in body.basic_blocks().indices() {
|
||||
let print = |w: &mut dyn Write, prefix, result: &IndexVec<BasicBlock, LiveVarSet>| {
|
||||
let live: Vec<String> = result[block]
|
||||
.iter()
|
||||
|
@ -310,9 +310,9 @@ pub fn write_mir_fn<'a, 'tcx>(
|
|||
.collect();
|
||||
writeln!(w, "{} {{{}}}", prefix, live.join(", "))
|
||||
};
|
||||
write_basic_block(tcx, block, mir, &mut |_, _| Ok(()), w)?;
|
||||
write_basic_block(tcx, block, body, &mut |_, _| Ok(()), w)?;
|
||||
print(w, " ", &result.outs)?;
|
||||
if block.index() + 1 != mir.basic_blocks().len() {
|
||||
if block.index() + 1 != body.basic_blocks().len() {
|
||||
writeln!(w, "")?;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,13 +17,13 @@ pub struct MirPatch<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> MirPatch<'tcx> {
|
||||
pub fn new(mir: &Body<'tcx>) -> Self {
|
||||
pub fn new(body: &Body<'tcx>) -> Self {
|
||||
let mut result = MirPatch {
|
||||
patch_map: IndexVec::from_elem(None, mir.basic_blocks()),
|
||||
patch_map: IndexVec::from_elem(None, body.basic_blocks()),
|
||||
new_blocks: vec![],
|
||||
new_statements: vec![],
|
||||
new_locals: vec![],
|
||||
next_local: mir.local_decls.len(),
|
||||
next_local: body.local_decls.len(),
|
||||
resume_block: START_BLOCK,
|
||||
make_nop: vec![]
|
||||
};
|
||||
|
@ -35,7 +35,7 @@ impl<'tcx> MirPatch<'tcx> {
|
|||
|
||||
let mut resume_block = None;
|
||||
let mut resume_stmt_block = None;
|
||||
for (bb, block) in mir.basic_blocks().iter_enumerated() {
|
||||
for (bb, block) in body.basic_blocks().iter_enumerated() {
|
||||
if let TerminatorKind::Resume = block.terminator().kind {
|
||||
if block.statements.len() > 0 {
|
||||
assert!(resume_stmt_block.is_none());
|
||||
|
@ -51,7 +51,7 @@ impl<'tcx> MirPatch<'tcx> {
|
|||
statements: vec![],
|
||||
terminator: Some(Terminator {
|
||||
source_info: SourceInfo {
|
||||
span: mir.span,
|
||||
span: body.span,
|
||||
scope: OUTERMOST_SOURCE_SCOPE
|
||||
},
|
||||
kind: TerminatorKind::Resume
|
||||
|
@ -75,10 +75,10 @@ impl<'tcx> MirPatch<'tcx> {
|
|||
self.patch_map[bb].is_some()
|
||||
}
|
||||
|
||||
pub fn terminator_loc(&self, mir: &Body<'tcx>, bb: BasicBlock) -> Location {
|
||||
let offset = match bb.index().checked_sub(mir.basic_blocks().len()) {
|
||||
pub fn terminator_loc(&self, body: &Body<'tcx>, bb: BasicBlock) -> Location {
|
||||
let offset = match bb.index().checked_sub(body.basic_blocks().len()) {
|
||||
Some(index) => self.new_blocks[index].statements.len(),
|
||||
None => mir[bb].statements.len()
|
||||
None => body[bb].statements.len()
|
||||
};
|
||||
Location {
|
||||
block: bb,
|
||||
|
@ -127,21 +127,21 @@ impl<'tcx> MirPatch<'tcx> {
|
|||
self.make_nop.push(loc);
|
||||
}
|
||||
|
||||
pub fn apply(self, mir: &mut Body<'tcx>) {
|
||||
pub fn apply(self, body: &mut Body<'tcx>) {
|
||||
debug!("MirPatch: make nops at: {:?}", self.make_nop);
|
||||
for loc in self.make_nop {
|
||||
mir.make_statement_nop(loc);
|
||||
body.make_statement_nop(loc);
|
||||
}
|
||||
debug!("MirPatch: {:?} new temps, starting from index {}: {:?}",
|
||||
self.new_locals.len(), mir.local_decls.len(), self.new_locals);
|
||||
self.new_locals.len(), body.local_decls.len(), self.new_locals);
|
||||
debug!("MirPatch: {} new blocks, starting from index {}",
|
||||
self.new_blocks.len(), mir.basic_blocks().len());
|
||||
mir.basic_blocks_mut().extend(self.new_blocks);
|
||||
mir.local_decls.extend(self.new_locals);
|
||||
self.new_blocks.len(), body.basic_blocks().len());
|
||||
body.basic_blocks_mut().extend(self.new_blocks);
|
||||
body.local_decls.extend(self.new_locals);
|
||||
for (src, patch) in self.patch_map.into_iter_enumerated() {
|
||||
if let Some(patch) = patch {
|
||||
debug!("MirPatch: patching block {:?}", src);
|
||||
mir[src].terminator_mut().kind = patch;
|
||||
body[src].terminator_mut().kind = patch;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,9 +159,9 @@ impl<'tcx> MirPatch<'tcx> {
|
|||
stmt, loc, delta);
|
||||
loc.statement_index += delta;
|
||||
let source_info = Self::source_info_for_index(
|
||||
&mir[loc.block], loc
|
||||
&body[loc.block], loc
|
||||
);
|
||||
mir[loc.block].statements.insert(
|
||||
body[loc.block].statements.insert(
|
||||
loc.statement_index, Statement {
|
||||
source_info,
|
||||
kind: stmt
|
||||
|
@ -177,10 +177,10 @@ impl<'tcx> MirPatch<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn source_info_for_location(&self, mir: &Body<'_>, loc: Location) -> SourceInfo {
|
||||
let data = match loc.block.index().checked_sub(mir.basic_blocks().len()) {
|
||||
pub fn source_info_for_location(&self, body: &Body<'_>, loc: Location) -> SourceInfo {
|
||||
let data = match loc.block.index().checked_sub(body.basic_blocks().len()) {
|
||||
Some(new) => &self.new_blocks[new],
|
||||
None => &mir[loc.block]
|
||||
None => &body[loc.block]
|
||||
};
|
||||
Self::source_info_for_index(data, loc)
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>(
|
|||
pass_name: &str,
|
||||
disambiguator: &dyn Display,
|
||||
source: MirSource<'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
extra_data: F,
|
||||
) where
|
||||
F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>,
|
||||
|
@ -88,7 +88,7 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>(
|
|||
&node_path,
|
||||
disambiguator,
|
||||
source,
|
||||
mir,
|
||||
body,
|
||||
extra_data,
|
||||
);
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
|
|||
node_path: &str,
|
||||
disambiguator: &dyn Display,
|
||||
source: MirSource<'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
mut extra_data: F,
|
||||
) where
|
||||
F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>,
|
||||
|
@ -135,13 +135,13 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
|
|||
writeln!(file, "// source = {:?}", source)?;
|
||||
writeln!(file, "// pass_name = {}", pass_name)?;
|
||||
writeln!(file, "// disambiguator = {}", disambiguator)?;
|
||||
if let Some(ref layout) = mir.generator_layout {
|
||||
if let Some(ref layout) = body.generator_layout {
|
||||
writeln!(file, "// generator_layout = {:?}", layout)?;
|
||||
}
|
||||
writeln!(file, "")?;
|
||||
extra_data(PassWhere::BeforeCFG, &mut file)?;
|
||||
write_user_type_annotations(mir, &mut file)?;
|
||||
write_mir_fn(tcx, source, mir, &mut extra_data, &mut file)?;
|
||||
write_user_type_annotations(body, &mut file)?;
|
||||
write_mir_fn(tcx, source, body, &mut extra_data, &mut file)?;
|
||||
extra_data(PassWhere::AfterCFG, &mut file)?;
|
||||
};
|
||||
|
||||
|
@ -149,7 +149,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
|
|||
let _: io::Result<()> = try {
|
||||
let mut file =
|
||||
create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, source)?;
|
||||
write_mir_fn_graphviz(tcx, source.def_id(), mir, &mut file)?;
|
||||
write_mir_fn_graphviz(tcx, source.def_id(), body, &mut file)?;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -256,7 +256,7 @@ pub fn write_mir_pretty<'a, 'gcx, 'tcx>(
|
|||
|
||||
let mut first = true;
|
||||
for def_id in dump_mir_def_ids(tcx, single) {
|
||||
let mir = &tcx.optimized_mir(def_id);
|
||||
let body = &tcx.optimized_mir(def_id);
|
||||
|
||||
if first {
|
||||
first = false;
|
||||
|
@ -265,15 +265,15 @@ pub fn write_mir_pretty<'a, 'gcx, 'tcx>(
|
|||
writeln!(w, "")?;
|
||||
}
|
||||
|
||||
write_mir_fn(tcx, MirSource::item(def_id), mir, &mut |_, _| Ok(()), w)?;
|
||||
write_mir_fn(tcx, MirSource::item(def_id), body, &mut |_, _| Ok(()), w)?;
|
||||
|
||||
for (i, mir) in mir.promoted.iter_enumerated() {
|
||||
for (i, body) in body.promoted.iter_enumerated() {
|
||||
writeln!(w, "")?;
|
||||
let src = MirSource {
|
||||
instance: ty::InstanceDef::Item(def_id),
|
||||
promoted: Some(i),
|
||||
};
|
||||
write_mir_fn(tcx, src, mir, &mut |_, _| Ok(()), w)?;
|
||||
write_mir_fn(tcx, src, body, &mut |_, _| Ok(()), w)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -282,18 +282,18 @@ pub fn write_mir_pretty<'a, 'gcx, 'tcx>(
|
|||
pub fn write_mir_fn<'a, 'gcx, 'tcx, F>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
src: MirSource<'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
extra_data: &mut F,
|
||||
w: &mut dyn Write,
|
||||
) -> io::Result<()>
|
||||
where
|
||||
F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>,
|
||||
{
|
||||
write_mir_intro(tcx, src, mir, w)?;
|
||||
for block in mir.basic_blocks().indices() {
|
||||
write_mir_intro(tcx, src, body, w)?;
|
||||
for block in body.basic_blocks().indices() {
|
||||
extra_data(PassWhere::BeforeBlock(block), w)?;
|
||||
write_basic_block(tcx, block, mir, extra_data, w)?;
|
||||
if block.index() + 1 != mir.basic_blocks().len() {
|
||||
write_basic_block(tcx, block, body, extra_data, w)?;
|
||||
if block.index() + 1 != body.basic_blocks().len() {
|
||||
writeln!(w, "")?;
|
||||
}
|
||||
}
|
||||
|
@ -306,14 +306,14 @@ where
|
|||
pub fn write_basic_block<'cx, 'gcx, 'tcx, F>(
|
||||
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||
block: BasicBlock,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
extra_data: &mut F,
|
||||
w: &mut dyn Write,
|
||||
) -> io::Result<()>
|
||||
where
|
||||
F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>,
|
||||
{
|
||||
let data = &mir[block];
|
||||
let data = &body[block];
|
||||
|
||||
// Basic block label at the top.
|
||||
let cleanup_text = if data.is_cleanup { " (cleanup)" } else { "" };
|
||||
|
@ -326,11 +326,11 @@ where
|
|||
};
|
||||
for statement in &data.statements {
|
||||
extra_data(PassWhere::BeforeLocation(current_location), w)?;
|
||||
let indented_mir = format!("{0}{0}{1:?};", INDENT, statement);
|
||||
let indented_body = format!("{0}{0}{1:?};", INDENT, statement);
|
||||
writeln!(
|
||||
w,
|
||||
"{:A$} // {:?}: {}",
|
||||
indented_mir,
|
||||
indented_body,
|
||||
current_location,
|
||||
comment(tcx, statement.source_info),
|
||||
A = ALIGN,
|
||||
|
@ -464,7 +464,7 @@ fn comment(tcx: TyCtxt<'_, '_, '_>, SourceInfo { span, scope }: SourceInfo) -> S
|
|||
/// Prints local variables in a scope tree.
|
||||
fn write_scope_tree(
|
||||
tcx: TyCtxt<'_, '_, '_>,
|
||||
mir: &Body<'_>,
|
||||
body: &Body<'_>,
|
||||
scope_tree: &FxHashMap<SourceScope, Vec<SourceScope>>,
|
||||
w: &mut dyn Write,
|
||||
parent: SourceScope,
|
||||
|
@ -473,8 +473,8 @@ fn write_scope_tree(
|
|||
let indent = depth * INDENT.len();
|
||||
|
||||
// Local variable types (including the user's name in a comment).
|
||||
for (local, local_decl) in mir.local_decls.iter_enumerated() {
|
||||
if (1..mir.arg_count+1).contains(&local.index()) {
|
||||
for (local, local_decl) in body.local_decls.iter_enumerated() {
|
||||
if (1..body.arg_count+1).contains(&local.index()) {
|
||||
// Skip over argument locals, they're printed in the signature.
|
||||
continue;
|
||||
}
|
||||
|
@ -527,9 +527,9 @@ fn write_scope_tree(
|
|||
};
|
||||
|
||||
for &child in children {
|
||||
assert_eq!(mir.source_scopes[child].parent_scope, Some(parent));
|
||||
assert_eq!(body.source_scopes[child].parent_scope, Some(parent));
|
||||
writeln!(w, "{0:1$}scope {2} {{", "", indent, child.index())?;
|
||||
write_scope_tree(tcx, mir, scope_tree, w, child, depth + 1)?;
|
||||
write_scope_tree(tcx, body, scope_tree, w, child, depth + 1)?;
|
||||
writeln!(w, "{0:1$}}}", "", depth * INDENT.len())?;
|
||||
}
|
||||
|
||||
|
@ -541,15 +541,15 @@ fn write_scope_tree(
|
|||
pub fn write_mir_intro<'a, 'gcx, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
src: MirSource<'tcx>,
|
||||
mir: &Body<'_>,
|
||||
body: &Body<'_>,
|
||||
w: &mut dyn Write,
|
||||
) -> io::Result<()> {
|
||||
write_mir_sig(tcx, src, mir, w)?;
|
||||
write_mir_sig(tcx, src, body, w)?;
|
||||
writeln!(w, "{{")?;
|
||||
|
||||
// construct a scope tree and write it out
|
||||
let mut scope_tree: FxHashMap<SourceScope, Vec<SourceScope>> = Default::default();
|
||||
for (index, scope_data) in mir.source_scopes.iter().enumerate() {
|
||||
for (index, scope_data) in body.source_scopes.iter().enumerate() {
|
||||
if let Some(parent) = scope_data.parent_scope {
|
||||
scope_tree
|
||||
.entry(parent)
|
||||
|
@ -561,7 +561,7 @@ pub fn write_mir_intro<'a, 'gcx, 'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
write_scope_tree(tcx, mir, &scope_tree, w, OUTERMOST_SOURCE_SCOPE, 1)?;
|
||||
write_scope_tree(tcx, body, &scope_tree, w, OUTERMOST_SOURCE_SCOPE, 1)?;
|
||||
|
||||
// Add an empty line before the first block is printed.
|
||||
writeln!(w, "")?;
|
||||
|
@ -572,7 +572,7 @@ pub fn write_mir_intro<'a, 'gcx, 'tcx>(
|
|||
fn write_mir_sig(
|
||||
tcx: TyCtxt<'_, '_, '_>,
|
||||
src: MirSource<'tcx>,
|
||||
mir: &Body<'_>,
|
||||
body: &Body<'_>,
|
||||
w: &mut dyn Write,
|
||||
) -> io::Result<()> {
|
||||
use rustc::hir::def::DefKind;
|
||||
|
@ -605,20 +605,20 @@ fn write_mir_sig(
|
|||
write!(w, "(")?;
|
||||
|
||||
// fn argument types.
|
||||
for (i, arg) in mir.args_iter().enumerate() {
|
||||
for (i, arg) in body.args_iter().enumerate() {
|
||||
if i != 0 {
|
||||
write!(w, ", ")?;
|
||||
}
|
||||
write!(w, "{:?}: {}", Place::Base(PlaceBase::Local(arg)), mir.local_decls[arg].ty)?;
|
||||
write!(w, "{:?}: {}", Place::Base(PlaceBase::Local(arg)), body.local_decls[arg].ty)?;
|
||||
}
|
||||
|
||||
write!(w, ") -> {}", mir.return_ty())?;
|
||||
write!(w, ") -> {}", body.return_ty())?;
|
||||
} else {
|
||||
assert_eq!(mir.arg_count, 0);
|
||||
write!(w, ": {} =", mir.return_ty())?;
|
||||
assert_eq!(body.arg_count, 0);
|
||||
write!(w, ": {} =", body.return_ty())?;
|
||||
}
|
||||
|
||||
if let Some(yield_ty) = mir.yield_ty {
|
||||
if let Some(yield_ty) = body.yield_ty {
|
||||
writeln!(w)?;
|
||||
writeln!(w, "yields {}", yield_ty)?;
|
||||
}
|
||||
|
@ -629,14 +629,14 @@ fn write_mir_sig(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn write_user_type_annotations(mir: &Body<'_>, w: &mut dyn Write) -> io::Result<()> {
|
||||
if !mir.user_type_annotations.is_empty() {
|
||||
fn write_user_type_annotations(body: &Body<'_>, w: &mut dyn Write) -> io::Result<()> {
|
||||
if !body.user_type_annotations.is_empty() {
|
||||
writeln!(w, "| User Type Annotations")?;
|
||||
}
|
||||
for (index, annotation) in mir.user_type_annotations.iter_enumerated() {
|
||||
for (index, annotation) in body.user_type_annotations.iter_enumerated() {
|
||||
writeln!(w, "| {:?}: {:?} at {:?}", index.index(), annotation.user_ty, annotation.span)?;
|
||||
}
|
||||
if !mir.user_type_annotations.is_empty() {
|
||||
if !body.user_type_annotations.is_empty() {
|
||||
writeln!(w, "|")?;
|
||||
}
|
||||
Ok(())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue