Prepare def_use MutVisitor to have projections interned
This commit is contained in:
parent
39c9ed3ac1
commit
2b2e35bfc3
1 changed files with 27 additions and 9 deletions
|
@ -1,6 +1,6 @@
|
||||||
//! Def-use analysis.
|
//! Def-use analysis.
|
||||||
|
|
||||||
use rustc::mir::{Local, Location, Body};
|
use rustc::mir::{Body, Local, Location, Place, PlaceElem};
|
||||||
use rustc::mir::visit::{PlaceContext, MutVisitor, Visitor};
|
use rustc::mir::visit::{PlaceContext, MutVisitor, Visitor};
|
||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -47,13 +47,13 @@ impl DefUseAnalysis {
|
||||||
&self.info[local]
|
&self.info[local]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mutate_defs_and_uses<F>(&self, local: Local, body: &mut Body<'_>, mut callback: F)
|
fn mutate_defs_and_uses<F>(&self, local: Local, body: &mut Body<'_>, callback: F)
|
||||||
where F: for<'a> FnMut(&'a mut Local,
|
where F: for<'a> Fn(&'a Local,
|
||||||
PlaceContext,
|
PlaceContext,
|
||||||
Location) {
|
Location) -> Local {
|
||||||
for place_use in &self.info[local].defs_and_uses {
|
for place_use in &self.info[local].defs_and_uses {
|
||||||
MutateUseVisitor::new(local,
|
MutateUseVisitor::new(local,
|
||||||
&mut callback,
|
&callback,
|
||||||
body).visit_location(body, place_use.location)
|
body).visit_location(body, place_use.location)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ impl DefUseAnalysis {
|
||||||
local: Local,
|
local: Local,
|
||||||
body: &mut Body<'_>,
|
body: &mut Body<'_>,
|
||||||
new_local: Local) {
|
new_local: Local) {
|
||||||
self.mutate_defs_and_uses(local, body, |local, _, _| *local = new_local)
|
self.mutate_defs_and_uses(local, body, |_, _, _| new_local)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ struct MutateUseVisitor<F> {
|
||||||
impl<F> MutateUseVisitor<F> {
|
impl<F> MutateUseVisitor<F> {
|
||||||
fn new(query: Local, callback: F, _: &Body<'_>)
|
fn new(query: Local, callback: F, _: &Body<'_>)
|
||||||
-> MutateUseVisitor<F>
|
-> MutateUseVisitor<F>
|
||||||
where F: for<'a> FnMut(&'a mut Local, PlaceContext, Location) {
|
where F: for<'a> Fn(&'a Local, PlaceContext, Location) -> Local {
|
||||||
MutateUseVisitor {
|
MutateUseVisitor {
|
||||||
query,
|
query,
|
||||||
callback,
|
callback,
|
||||||
|
@ -134,13 +134,31 @@ impl<F> MutateUseVisitor<F> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F> MutVisitor<'_> for MutateUseVisitor<F>
|
impl<F> MutVisitor<'_> for MutateUseVisitor<F>
|
||||||
where F: for<'a> FnMut(&'a mut Local, PlaceContext, Location) {
|
where F: for<'a> Fn(&'a Local, PlaceContext, Location) -> Local {
|
||||||
fn visit_local(&mut self,
|
fn visit_local(&mut self,
|
||||||
local: &mut Local,
|
local: &mut Local,
|
||||||
context: PlaceContext,
|
context: PlaceContext,
|
||||||
location: Location) {
|
location: Location) {
|
||||||
if *local == self.query {
|
if *local == self.query {
|
||||||
(self.callback)(local, context, location)
|
*local = (self.callback)(local, context, location)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_place(&mut self,
|
||||||
|
place: &mut Place<'tcx>,
|
||||||
|
context: PlaceContext,
|
||||||
|
location: Location) {
|
||||||
|
self.visit_place_base(&mut place.base, context, location);
|
||||||
|
|
||||||
|
let new_projection: Vec<_> = place.projection.iter().map(|elem|
|
||||||
|
match elem {
|
||||||
|
PlaceElem::Index(local) if *local == self.query => {
|
||||||
|
PlaceElem::Index((self.callback)(&local, context, location))
|
||||||
|
}
|
||||||
|
_ => elem.clone(),
|
||||||
|
}
|
||||||
|
).collect();
|
||||||
|
|
||||||
|
place.projection = new_projection.into_boxed_slice();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue