2020-03-29 16:41:09 +02:00
|
|
|
use rustc_middle::mir::visit::PlaceContext;
|
|
|
|
|
use rustc_middle::mir::visit::Visitor;
|
|
|
|
|
use rustc_middle::mir::{Body, Local, Location};
|
2018-03-03 01:49:55 +05:30
|
|
|
|
2020-12-30 18:48:40 +01:00
|
|
|
pub trait FindAssignments {
|
2018-03-14 23:51:54 +05:30
|
|
|
// Finds all statements that assign directly to local (i.e., X = ...)
|
|
|
|
|
// and returns their locations.
|
|
|
|
|
fn find_assignments(&self, local: Local) -> Vec<Location>;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-26 16:02:10 -07:00
|
|
|
impl<'tcx> FindAssignments for Body<'tcx> {
|
2018-03-14 23:51:54 +05:30
|
|
|
fn find_assignments(&self, local: Local) -> Vec<Location> {
|
|
|
|
|
let mut visitor = FindLocalAssignmentVisitor { needle: local, locations: vec![] };
|
2020-03-26 16:02:10 -07:00
|
|
|
visitor.visit_body(self);
|
2018-03-14 23:51:54 +05:30
|
|
|
visitor.locations
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-10 20:24:59 +05:30
|
|
|
// The Visitor walks the MIR to return the assignment statements corresponding
|
|
|
|
|
// to a Local.
|
2018-03-14 23:51:54 +05:30
|
|
|
struct FindLocalAssignmentVisitor {
|
2018-03-03 01:49:55 +05:30
|
|
|
needle: Local,
|
|
|
|
|
locations: Vec<Location>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'tcx> Visitor<'tcx> for FindLocalAssignmentVisitor {
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_local(&mut self, local: Local, place_context: PlaceContext, location: Location) {
|
|
|
|
|
if self.needle != local {
|
2018-03-03 01:49:55 +05:30
|
|
|
return;
|
2018-03-10 20:24:59 +05:30
|
|
|
}
|
2018-03-03 01:49:55 +05:30
|
|
|
|
2018-10-26 13:22:45 +02:00
|
|
|
if place_context.is_place_assignment() {
|
2018-06-21 14:12:26 +02:00
|
|
|
self.locations.push(location);
|
2018-03-03 01:49:55 +05:30
|
|
|
}
|
|
|
|
|
}
|
2018-06-21 14:12:26 +02:00
|
|
|
}
|