about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorSantiago Pastorino <spastorino@gmail.com>2019-10-08 00:24:18 -0300
committerSantiago Pastorino <spastorino@gmail.com>2019-10-17 22:06:56 -0400
commit2b2e35bfc34618cff7b62a7726ee3a97101d3fa2 (patch)
tree1ab7246a0f68f3770923c031c785603a5857554a /src
parent39c9ed3ac19b3f6c79069d32a317daa763371369 (diff)
downloadrust-2b2e35bfc34618cff7b62a7726ee3a97101d3fa2.tar.gz
rust-2b2e35bfc34618cff7b62a7726ee3a97101d3fa2.zip
Prepare def_use MutVisitor to have projections interned
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/util/def_use.rs36
1 files changed, 27 insertions, 9 deletions
diff --git a/src/librustc_mir/util/def_use.rs b/src/librustc_mir/util/def_use.rs
index 3aea25fa876..d90be90bd9d 100644
--- a/src/librustc_mir/util/def_use.rs
+++ b/src/librustc_mir/util/def_use.rs
@@ -1,6 +1,6 @@
 //! 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_index::vec::IndexVec;
 use std::mem;
@@ -47,13 +47,13 @@ impl DefUseAnalysis {
         &self.info[local]
     }
 
-    fn mutate_defs_and_uses<F>(&self, local: Local, body: &mut Body<'_>, mut callback: F)
-                               where F: for<'a> FnMut(&'a mut Local,
+    fn mutate_defs_and_uses<F>(&self, local: Local, body: &mut Body<'_>, callback: F)
+                               where F: for<'a> Fn(&'a Local,
                                                       PlaceContext,
-                                                      Location) {
+                                                      Location) -> Local {
         for place_use in &self.info[local].defs_and_uses {
             MutateUseVisitor::new(local,
-                                  &mut callback,
+                                  &callback,
                                   body).visit_location(body, place_use.location)
         }
     }
@@ -63,7 +63,7 @@ impl DefUseAnalysis {
                                           local: Local,
                                           body: &mut Body<'_>,
                                           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> {
     fn new(query: Local, callback: F, _: &Body<'_>)
            -> MutateUseVisitor<F>
-           where F: for<'a> FnMut(&'a mut Local, PlaceContext, Location) {
+           where F: for<'a> Fn(&'a Local, PlaceContext, Location) -> Local {
         MutateUseVisitor {
             query,
             callback,
@@ -134,13 +134,31 @@ impl<F> 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,
                     local: &mut Local,
                     context: PlaceContext,
                     location: Location) {
         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();
+    }
 }