about summary refs log tree commit diff
path: root/compiler/rustc_borrowck/src/util/collect_writes.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_borrowck/src/util/collect_writes.rs')
-rw-r--r--compiler/rustc_borrowck/src/util/collect_writes.rs36
1 files changed, 36 insertions, 0 deletions
diff --git a/compiler/rustc_borrowck/src/util/collect_writes.rs b/compiler/rustc_borrowck/src/util/collect_writes.rs
new file mode 100644
index 00000000000..8d92bb35938
--- /dev/null
+++ b/compiler/rustc_borrowck/src/util/collect_writes.rs
@@ -0,0 +1,36 @@
+use rustc_middle::mir::visit::PlaceContext;
+use rustc_middle::mir::visit::Visitor;
+use rustc_middle::mir::{Body, Local, Location};
+
+pub trait FindAssignments {
+    // Finds all statements that assign directly to local (i.e., X = ...)
+    // and returns their locations.
+    fn find_assignments(&self, local: Local) -> Vec<Location>;
+}
+
+impl<'tcx> FindAssignments for Body<'tcx> {
+    fn find_assignments(&self, local: Local) -> Vec<Location> {
+        let mut visitor = FindLocalAssignmentVisitor { needle: local, locations: vec![] };
+        visitor.visit_body(self);
+        visitor.locations
+    }
+}
+
+// The Visitor walks the MIR to return the assignment statements corresponding
+// to a Local.
+struct FindLocalAssignmentVisitor {
+    needle: Local,
+    locations: Vec<Location>,
+}
+
+impl<'tcx> Visitor<'tcx> for FindLocalAssignmentVisitor {
+    fn visit_local(&mut self, local: Local, place_context: PlaceContext, location: Location) {
+        if self.needle != local {
+            return;
+        }
+
+        if place_context.is_place_assignment() {
+            self.locations.push(location);
+        }
+    }
+}