use crate::hir::def_id::DefId;
use crate::ty::subst::SubstsRef;
-use crate::ty::{CanonicalUserTypeAnnotation, ClosureSubsts, GeneratorSubsts, Region, Ty};
+use crate::ty::{CanonicalUserTypeAnnotation, ClosureSubsts, GeneratorSubsts, Ty};
use crate::mir::*;
use syntax_pos::Span;
fn visit_place(&mut self,
place: & $($mutability)? Place<'tcx>,
- context: PlaceContext<'tcx>,
+ context: PlaceContext,
location: Location) {
self.super_place(place, context, location);
}
fn visit_projection(&mut self,
place: & $($mutability)? PlaceProjection<'tcx>,
- context: PlaceContext<'tcx>,
+ context: PlaceContext,
location: Location) {
self.super_projection(place, context, location);
}
fn visit_local(&mut self,
_local: & $($mutability)? Local,
- _context: PlaceContext<'tcx>,
+ _context: PlaceContext,
_location: Location) {
}
self.visit_region(r, location);
let ctx = match bk {
BorrowKind::Shared => PlaceContext::NonMutatingUse(
- NonMutatingUseContext::SharedBorrow(*r)
+ NonMutatingUseContext::SharedBorrow
),
BorrowKind::Shallow => PlaceContext::NonMutatingUse(
- NonMutatingUseContext::ShallowBorrow(*r)
+ NonMutatingUseContext::ShallowBorrow
),
BorrowKind::Unique => PlaceContext::NonMutatingUse(
- NonMutatingUseContext::UniqueBorrow(*r)
+ NonMutatingUseContext::UniqueBorrow
),
BorrowKind::Mut { .. } =>
- PlaceContext::MutatingUse(MutatingUseContext::Borrow(*r)),
+ PlaceContext::MutatingUse(MutatingUseContext::Borrow),
};
self.visit_place(path, ctx, location);
}
fn super_place(&mut self,
place: & $($mutability)? Place<'tcx>,
- context: PlaceContext<'tcx>,
+ context: PlaceContext,
location: Location) {
match place {
Place::Base(PlaceBase::Local(local)) => {
fn super_projection(&mut self,
proj: & $($mutability)? PlaceProjection<'tcx>,
- context: PlaceContext<'tcx>,
+ context: PlaceContext,
location: Location) {
let Projection { base, elem } = proj;
let context = if context.is_mutating_use() {
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum NonMutatingUseContext<'tcx> {
+pub enum NonMutatingUseContext {
/// Being inspected in some way, like loading a len.
Inspect,
/// Consumed as part of an operand.
/// Consumed as part of an operand.
Move,
/// Shared borrow.
- SharedBorrow(Region<'tcx>),
+ SharedBorrow,
/// Shallow borrow.
- ShallowBorrow(Region<'tcx>),
+ ShallowBorrow,
/// Unique borrow.
- UniqueBorrow(Region<'tcx>),
+ UniqueBorrow,
/// Used as base for another place, e.g., `x` in `x.y`. Will not mutate the place.
/// For example, the projection `x.y` is not marked as a mutation in these cases:
///
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum MutatingUseContext<'tcx> {
+pub enum MutatingUseContext {
/// Appears as LHS of an assignment.
Store,
/// Can often be treated as a `Store`, but needs to be separate because
/// Being dropped.
Drop,
/// Mutable borrow.
- Borrow(Region<'tcx>),
+ Borrow,
/// Used as base for another place, e.g., `x` in `x.y`. Could potentially mutate the place.
/// For example, the projection `x.y` is marked as a mutation in these cases:
///
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum PlaceContext<'tcx> {
- NonMutatingUse(NonMutatingUseContext<'tcx>),
- MutatingUse(MutatingUseContext<'tcx>),
+pub enum PlaceContext {
+ NonMutatingUse(NonMutatingUseContext),
+ MutatingUse(MutatingUseContext),
NonUse(NonUseContext),
}
-impl<'tcx> PlaceContext<'tcx> {
+impl<'tcx> PlaceContext {
/// Returns `true` if this place context represents a drop.
pub fn is_drop(&self) -> bool {
match *self {
/// Returns `true` if this place context represents a borrow.
pub fn is_borrow(&self) -> bool {
match *self {
- PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow(..)) |
- PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow(..)) |
- PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow(..)) |
- PlaceContext::MutatingUse(MutatingUseContext::Borrow(..)) => true,
+ PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) |
+ PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) |
+ PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow) |
+ PlaceContext::MutatingUse(MutatingUseContext::Borrow) => true,
_ => false,
}
}
fn visit_place(&mut self,
place: &mir::Place<'tcx>,
- context: PlaceContext<'tcx>,
+ context: PlaceContext,
location: Location) {
debug!("visit_place(place={:?}, context={:?})", place, context);
let cx = self.fx.cx;
fn visit_local(&mut self,
&local: &mir::Local,
- context: PlaceContext<'tcx>,
+ context: PlaceContext,
location: Location) {
match context {
PlaceContext::MutatingUse(MutatingUseContext::Call) => {
PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect) |
PlaceContext::MutatingUse(MutatingUseContext::Store) |
PlaceContext::MutatingUse(MutatingUseContext::AsmOutput) |
- PlaceContext::MutatingUse(MutatingUseContext::Borrow(..)) |
+ PlaceContext::MutatingUse(MutatingUseContext::Borrow) |
PlaceContext::MutatingUse(MutatingUseContext::Projection) |
- PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow(..)) |
- PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow(..)) |
- PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow(..)) |
+ PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) |
+ PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow) |
+ PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) => {
self.not_ssa(local);
}
struct HasStorageDead(BitSet<Local>);
impl<'tcx> Visitor<'tcx> for HasStorageDead {
- fn visit_local(&mut self, local: &Local, ctx: PlaceContext<'tcx>, _: Location) {
+ fn visit_local(&mut self, local: &Local, ctx: PlaceContext, _: Location) {
if ctx == PlaceContext::NonUse(NonUseContext::StorageDead) {
self.0.insert(*local);
}
fn visit_local(
&mut self,
temp: &Local,
- context: PlaceContext<'tcx>,
+ context: PlaceContext,
location: Location,
) {
if !context.is_use() {
}
impl<'cx, 'gcx, 'tcx> Visitor<'tcx> for DefUseVisitor<'cx, 'gcx, 'tcx> {
- fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) {
+ fn visit_local(&mut self, &local: &Local, context: PlaceContext, _: Location) {
let local_ty = self.mir.local_decls[local].ty;
let mut found_it = false;
}
impl Visitor<'tcx> for LocalUseMapBuild<'_> {
- fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, location: Location) {
+ fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) {
if self.locals_with_use_data[local] {
match categorize(context) {
Some(DefUse::Def) => self.insert_def(local, location),
}
}
- fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext<'_>, location: Location) {
+ fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
self.sanitize_place(place, location, context);
}
&mut self,
place: &Place<'tcx>,
location: Location,
- context: PlaceContext<'_>,
+ context: PlaceContext,
) -> PlaceTy<'tcx> {
debug!("sanitize_place: {:?}", place);
let place_ty = match place {
fn visit_local(
&mut self,
local: &Local,
- place_context: PlaceContext<'tcx>,
+ place_context: PlaceContext,
location: Location,
) {
if place_context.is_place_assignment() && self.temporary_used_locals.contains(local) {
fn visit_place(&mut self,
place: &mir::Place<'tcx>,
- context: mir::visit::PlaceContext<'tcx>,
+ context: mir::visit::PlaceContext,
location: Location) {
match place {
Place::Base(
fn visit_place(&mut self,
place: &Place<'tcx>,
- context: PlaceContext<'tcx>,
+ context: PlaceContext,
location: Location) {
match place {
&Place::Projection(box Projection {
fn visit_local(
&mut self,
&local: &Local,
- context: PlaceContext<'tcx>,
+ context: PlaceContext,
_: Location,
) {
use rustc::mir::visit::PlaceContext::*;
}
}
-fn eliminate_self_assignments<'tcx>(
- mir: &mut Mir<'tcx>,
- def_use_analysis: &DefUseAnalysis<'tcx>,
+fn eliminate_self_assignments(
+ mir: &mut Mir<'_>,
+ def_use_analysis: &DefUseAnalysis,
) -> bool {
let mut changed = false;
}
impl<'tcx> Action<'tcx> {
- fn local_copy(mir: &Mir<'tcx>, def_use_analysis: &DefUseAnalysis<'_>, src_place: &Place<'tcx>)
+ fn local_copy(mir: &Mir<'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 {
fn perform(self,
mir: &mut Mir<'tcx>,
- def_use_analysis: &DefUseAnalysis<'tcx>,
+ def_use_analysis: &DefUseAnalysis,
dest_local: Local,
location: Location)
-> bool {
impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor {
fn visit_local(&mut self,
local: &mut Local,
- _: PlaceContext<'tcx>,
+ _: PlaceContext,
_: Location) {
if *local == self.from {
*local = self.to;
impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor {
fn visit_local(&mut self,
local: &mut Local,
- _: PlaceContext<'tcx>,
+ _: PlaceContext,
_: Location) {
assert_ne!(*local, self_arg());
}
fn visit_place(&mut self,
place: &mut Place<'tcx>,
- context: PlaceContext<'tcx>,
+ context: PlaceContext,
location: Location) {
if *place == Place::Base(PlaceBase::Local(self_arg())) {
*place = Place::Projection(Box::new(Projection {
impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
fn visit_local(&mut self,
local: &mut Local,
- _: PlaceContext<'tcx>,
+ _: PlaceContext,
_: Location) {
assert_ne!(*local, self_arg());
}
fn visit_place(&mut self,
place: &mut Place<'tcx>,
- context: PlaceContext<'tcx>,
+ context: PlaceContext,
location: Location) {
if *place == Place::Base(PlaceBase::Local(self_arg())) {
*place = Place::Projection(Box::new(Projection {
impl<'a, 'tcx> MutVisitor<'tcx> for TransformVisitor<'a, 'tcx> {
fn visit_local(&mut self,
local: &mut Local,
- _: PlaceContext<'tcx>,
+ _: PlaceContext,
_: Location) {
assert_eq!(self.remap.get(local), None);
}
fn visit_place(&mut self,
place: &mut Place<'tcx>,
- context: PlaceContext<'tcx>,
+ context: PlaceContext,
location: Location) {
if let Place::Base(PlaceBase::Local(l)) = *place {
// Replace an Local in the remap with a generator struct access
impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
fn visit_local(&mut self,
local: &mut Local,
- _ctxt: PlaceContext<'tcx>,
+ _ctxt: PlaceContext,
_location: Location) {
if *local == RETURN_PLACE {
match self.destination {
fn visit_place(&mut self,
place: &mut Place<'tcx>,
- _ctxt: PlaceContext<'tcx>,
+ _ctxt: PlaceContext,
_location: Location) {
match place {
impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> {
fn visit_local(&mut self,
&index: &Local,
- context: PlaceContext<'tcx>,
+ context: PlaceContext,
location: Location) {
debug!("visit_local: index={:?} context={:?} location={:?}", index, context, location);
// We're only interested in temporaries and the return place
impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> {
fn visit_local(&mut self,
local: &mut Local,
- _: PlaceContext<'tcx>,
+ _: PlaceContext,
_: Location) {
if self.source.local_kind(*local) == LocalKind::Temp {
*local = self.promote_temp(*local);
impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
fn visit_place(&mut self,
place: &Place<'tcx>,
- context: PlaceContext<'tcx>,
+ context: PlaceContext,
location: Location) {
debug!("visit_place: place={:?} context={:?} location={:?}", place, context, location);
self.super_place(place, context, location);
debug!("visit_rvalue: rvalue={:?} location={:?}", rvalue, location);
// Check nested operands and places.
- if let Rvalue::Ref(region, kind, ref place) = *rvalue {
+ if let Rvalue::Ref(_, kind, ref place) = *rvalue {
// Special-case reborrows.
let mut is_reborrow = false;
if let Place::Projection(ref proj) = *place {
if is_reborrow {
let ctx = match kind {
BorrowKind::Shared => PlaceContext::NonMutatingUse(
- NonMutatingUseContext::SharedBorrow(region),
+ NonMutatingUseContext::SharedBorrow,
),
BorrowKind::Shallow => PlaceContext::NonMutatingUse(
- NonMutatingUseContext::ShallowBorrow(region),
+ NonMutatingUseContext::ShallowBorrow,
),
BorrowKind::Unique => PlaceContext::NonMutatingUse(
- NonMutatingUseContext::UniqueBorrow(region),
+ NonMutatingUseContext::UniqueBorrow,
),
BorrowKind::Mut { .. } => PlaceContext::MutatingUse(
- MutatingUseContext::Borrow(region),
+ MutatingUseContext::Borrow,
),
};
self.super_place(place, ctx, location);
}
impl<'tcx> Visitor<'tcx> for DeclMarker {
- fn visit_local(&mut self, local: &Local, ctx: PlaceContext<'tcx>, _: Location) {
+ fn visit_local(&mut self, local: &Local, ctx: PlaceContext, _: Location) {
// Ignore storage markers altogether, they get removed along with their otherwise unused
// decls.
// FIXME: Extend this to all non-uses.
});
self.super_basic_block_data(block, data);
}
- fn visit_local(&mut self, l: &mut Local, _: PlaceContext<'tcx>, _: Location) {
+ fn visit_local(&mut self, l: &mut Local, _: PlaceContext, _: Location) {
*l = self.map[*l].unwrap();
}
}
fn visit_local(&mut self,
local: &Local,
- context: PlaceContext<'tcx>,
+ context: PlaceContext,
location: Location) {
let local_use = &mut self.locals_use[*local];
match context {
impl<'tcx> Visitor<'tcx> for FindLocalAssignmentVisitor {
fn visit_local(&mut self,
local: &Local,
- place_context: PlaceContext<'tcx>,
+ place_context: PlaceContext,
location: Location) {
if self.needle != *local {
return;
use rustc::mir::{Local, Location, Mir};
use rustc::mir::visit::{PlaceContext, MutVisitor, Visitor};
use rustc_data_structures::indexed_vec::IndexVec;
-use std::marker::PhantomData;
use std::mem;
-use std::slice;
-use std::iter;
-pub struct DefUseAnalysis<'tcx> {
- info: IndexVec<Local, Info<'tcx>>,
+pub struct DefUseAnalysis {
+ info: IndexVec<Local, Info>,
}
#[derive(Clone)]
-pub struct Info<'tcx> {
- pub defs_and_uses: Vec<Use<'tcx>>,
+pub struct Info {
+ pub defs_and_uses: Vec<Use>,
}
#[derive(Clone)]
-pub struct Use<'tcx> {
- pub context: PlaceContext<'tcx>,
+pub struct Use {
+ pub context: PlaceContext,
pub location: Location,
}
-impl<'tcx> DefUseAnalysis<'tcx> {
- pub fn new(mir: &Mir<'tcx>) -> DefUseAnalysis<'tcx> {
+impl DefUseAnalysis {
+ pub fn new(mir: &Mir<'_>) -> DefUseAnalysis {
DefUseAnalysis {
info: IndexVec::from_elem_n(Info::new(), mir.local_decls.len()),
}
}
- pub fn analyze(&mut self, mir: &Mir<'tcx>) {
+ pub fn analyze(&mut self, mir: &Mir<'_>) {
self.clear();
let mut finder = DefUseFinder {
}
}
- pub fn local_info(&self, local: Local) -> &Info<'tcx> {
+ pub fn local_info(&self, local: Local) -> &Info {
&self.info[local]
}
- fn mutate_defs_and_uses<F>(&self, local: Local, mir: &mut Mir<'tcx>, mut callback: F)
+ fn mutate_defs_and_uses<F>(&self, local: Local, mir: &mut Mir<'_>, mut callback: F)
where F: for<'a> FnMut(&'a mut Local,
- PlaceContext<'tcx>,
+ PlaceContext,
Location) {
for place_use in &self.info[local].defs_and_uses {
MutateUseVisitor::new(local,
// FIXME(pcwalton): this should update the def-use chains.
pub fn replace_all_defs_and_uses_with(&self,
local: Local,
- mir: &mut Mir<'tcx>,
+ mir: &mut Mir<'_>,
new_local: Local) {
self.mutate_defs_and_uses(local, mir, |local, _, _| *local = new_local)
}
}
-struct DefUseFinder<'tcx> {
- info: IndexVec<Local, Info<'tcx>>,
+struct DefUseFinder {
+ info: IndexVec<Local, Info>,
}
-impl<'tcx> Visitor<'tcx> for DefUseFinder<'tcx> {
+impl Visitor<'_> for DefUseFinder {
fn visit_local(&mut self,
&local: &Local,
- context: PlaceContext<'tcx>,
+ context: PlaceContext,
location: Location) {
self.info[local].defs_and_uses.push(Use {
context,
}
}
-impl<'tcx> Info<'tcx> {
- fn new() -> Info<'tcx> {
+impl Info {
+ fn new() -> Info {
Info {
defs_and_uses: vec![],
}
pub fn defs_not_including_drop(
&self,
- ) -> iter::Filter<slice::Iter<'_, Use<'tcx>>, fn(&&Use<'tcx>) -> bool> {
+ ) -> impl Iterator<Item=&Use> {
self.defs_and_uses.iter().filter(|place_use| {
place_use.context.is_mutating_use() && !place_use.context.is_drop()
})
}
}
-struct MutateUseVisitor<'tcx, F> {
+struct MutateUseVisitor<F> {
query: Local,
callback: F,
- phantom: PhantomData<&'tcx ()>,
}
-impl<'tcx, F> MutateUseVisitor<'tcx, F> {
- fn new(query: Local, callback: F, _: &Mir<'tcx>)
- -> MutateUseVisitor<'tcx, F>
- where F: for<'a> FnMut(&'a mut Local, PlaceContext<'tcx>, Location) {
+impl<F> MutateUseVisitor<F> {
+ fn new(query: Local, callback: F, _: &Mir<'_>)
+ -> MutateUseVisitor<F>
+ where F: for<'a> FnMut(&'a mut Local, PlaceContext, Location) {
MutateUseVisitor {
query,
callback,
- phantom: PhantomData,
}
}
}
-impl<'tcx, F> MutVisitor<'tcx> for MutateUseVisitor<'tcx, F>
- where F: for<'a> FnMut(&'a mut Local, PlaceContext<'tcx>, Location) {
+impl<F> MutVisitor<'_> for MutateUseVisitor<F>
+ where F: for<'a> FnMut(&'a mut Local, PlaceContext, Location) {
fn visit_local(&mut self,
local: &mut Local,
- context: PlaceContext<'tcx>,
+ context: PlaceContext,
location: Location) {
if *local == self.query {
(self.callback)(local, context, location)
Drop,
}
-pub fn categorize<'tcx>(context: PlaceContext<'tcx>) -> Option<DefUse> {
+pub fn categorize<'tcx>(context: PlaceContext) -> Option<DefUse> {
match context {
///////////////////////////////////////////////////////////////////////////
// DEFS
// This won't affect the results since we use this analysis for generators
// and we only care about the result at suspension points. Borrows cannot
// cross suspension points so this behavior is unproblematic.
- PlaceContext::MutatingUse(MutatingUseContext::Borrow(..)) |
- PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow(..)) |
- PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow(..)) |
- PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow(..)) |
+ PlaceContext::MutatingUse(MutatingUseContext::Borrow) |
+ PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow) |
+ PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) |
+ PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
impl<'tcx> Visitor<'tcx> for DefsUsesVisitor
{
- fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) {
+ fn visit_local(&mut self, &local: &Local, context: PlaceContext, _: Location) {
match categorize(context) {
Some(DefUse::Def) => self.defs_uses.add_def(local),
Some(DefUse::Use) | Some(DefUse::Drop) => self.defs_uses.add_use(local),