}
macro_rules! visit_place_fns {
- (mut) => (
+ (mut) => {
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
fn super_place(
) {
self.visit_place_base(&mut place.local, context, location);
- if let Some(new_projection) = self.process_projection(&place.projection) {
+ if let Some(new_projection) = self.process_projection(&place.projection, location) {
place.projection = self.tcx().intern_place_elems(&new_projection);
}
}
fn process_projection(
&mut self,
projection: &'a [PlaceElem<'tcx>],
+ location: Location,
) -> Option<Vec<PlaceElem<'tcx>>> {
let mut projection = Cow::Borrowed(projection);
for i in 0..projection.len() {
if let Some(elem) = projection.get(i) {
- if let Some(elem) = self.process_projection_elem(elem) {
+ if let Some(elem) = self.process_projection_elem(elem, location) {
// This converts the borrowed projection into `Cow::Owned(_)` and returns a
// clone of the projection so we can mutate and reintern later.
let vec = projection.to_mut();
fn process_projection_elem(
&mut self,
- _elem: &PlaceElem<'tcx>,
+ elem: &PlaceElem<'tcx>,
+ location: Location,
) -> Option<PlaceElem<'tcx>> {
- None
+ match elem {
+ PlaceElem::Index(local) => {
+ let mut new_local = *local;
+ self.visit_local(
+ &mut new_local,
+ PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
+ location,
+ );
+
+ if new_local == *local { None } else { Some(PlaceElem::Index(new_local)) }
+ }
+ PlaceElem::Deref
+ | PlaceElem::Field(..)
+ | PlaceElem::ConstantIndex { .. }
+ | PlaceElem::Subslice { .. }
+ | PlaceElem::Downcast(..) => None,
+ }
}
- );
+ };
- () => (
+ () => {
fn visit_projection(
&mut self,
local: Local,
self.super_projection_elem(local, proj_base, elem, context, location);
}
- fn super_place(
- &mut self,
- place: &Place<'tcx>,
- context: PlaceContext,
- location: Location,
- ) {
+ fn super_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
let mut context = context;
if !place.projection.is_empty() {
self.visit_place_base(&place.local, context, location);
- self.visit_projection(place.local,
- &place.projection,
- context,
- location);
+ self.visit_projection(place.local, &place.projection, context, location);
}
fn super_projection(
self.visit_local(
local,
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
- location
+ location,
);
}
- ProjectionElem::Deref |
- ProjectionElem::Subslice { from: _, to: _, from_end: _ } |
- ProjectionElem::ConstantIndex { offset: _,
- min_length: _,
- from_end: _ } |
- ProjectionElem::Downcast(_, _) => {
- }
+ ProjectionElem::Deref
+ | ProjectionElem::Subslice { from: _, to: _, from_end: _ }
+ | ProjectionElem::ConstantIndex { offset: _, min_length: _, from_end: _ }
+ | ProjectionElem::Downcast(_, _) => {}
}
}
- );
+ };
}
make_mir_visitor!(Visitor,);
self.super_place(place, context, location)
}
- fn process_projection_elem(&mut self, elem: &PlaceElem<'tcx>) -> Option<PlaceElem<'tcx>> {
- if let PlaceElem::Index(local) = elem {
- let new_local = self.make_integrate_local(*local);
-
- if new_local != *local {
- return Some(PlaceElem::Index(new_local));
- }
- }
-
- None
- }
-
fn visit_basic_block_data(&mut self, block: BasicBlock, data: &mut BasicBlockData<'tcx>) {
self.in_cleanup_block = data.is_cleanup;
self.super_basic_block_data(block, data);
use rustc_index::vec::IndexVec;
use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
-use rustc_middle::mir::{
- Body, BodyAndCache, Local, Location, PlaceElem, ReadOnlyBodyAndCache, VarDebugInfo,
-};
+use rustc_middle::mir::{Body, BodyAndCache, Local, Location, ReadOnlyBodyAndCache, VarDebugInfo};
use rustc_middle::ty::TyCtxt;
use std::mem;
*local = self.new_local;
}
}
-
- fn process_projection_elem(&mut self, elem: &PlaceElem<'tcx>) -> Option<PlaceElem<'tcx>> {
- match elem {
- PlaceElem::Index(local) if *local == self.query => {
- Some(PlaceElem::Index(self.new_local))
- }
- _ => None,
- }
- }
}