about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSantiago Pastorino <spastorino@gmail.com>2019-10-08 23:46:14 -0300
committerSantiago Pastorino <spastorino@gmail.com>2019-10-18 10:06:13 -0400
commit48349960e68a9d19b17ac54cd12e939a9a46ea7d (patch)
tree76fbadee0b0fbf3f6090122cb1d4f10583bf65f0
parentd53fc9cae5b17c138be09383dea8b8f10d3df3a1 (diff)
downloadrust-48349960e68a9d19b17ac54cd12e939a9a46ea7d.tar.gz
rust-48349960e68a9d19b17ac54cd12e939a9a46ea7d.zip
Use Cow to handle modifications of projection in preparation for interning
-rw-r--r--src/librustc/mir/visit.rs33
-rw-r--r--src/librustc_mir/borrow_check/nll/renumber.rs12
-rw-r--r--src/librustc_mir/transform/erase_regions.rs12
-rw-r--r--src/librustc_mir/transform/generator.rs24
-rw-r--r--src/librustc_mir/transform/inline.rs12
-rw-r--r--src/librustc_mir/transform/promote_consts.rs6
-rw-r--r--src/librustc_mir/transform/simplify.rs11
-rw-r--r--src/librustc_mir/util/def_use.rs6
8 files changed, 67 insertions, 49 deletions
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index c8a6367899b..fef406e8987 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -792,26 +792,37 @@ macro_rules! visit_place_fns {
         ) {
             self.visit_place_base(&mut place.base, context, location);
 
-            place.projection = self.process_projection(&place.projection);
+            if let Some(new_projection) = self.process_projection(&place.projection) {
+                place.projection = new_projection;
+            }
         }
 
         fn process_projection(
             &mut self,
-            projection: &Box<[PlaceElem<'tcx>]>,
-        ) -> Box<[PlaceElem<'tcx>]> {
-            let new_projection: Vec<_> = projection.iter().map(|elem|
-                self.process_projection_elem(elem)
-            ).collect();
+            projection: &'a [PlaceElem<'tcx>],
+        ) -> Option<Box<[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) {
+                        let vec = projection.to_mut();
+                        vec[i] = elem;
+                    }
+                }
+            }
 
-            new_projection.into_boxed_slice()
+            match projection {
+                Cow::Borrowed(_) => None,
+                Cow::Owned(vec) => Some(vec.into_boxed_slice()),
+            }
         }
 
         fn process_projection_elem(
             &mut self,
-            elem: &PlaceElem<'tcx>,
-        ) -> PlaceElem<'tcx> {
-            // FIXME: avoid cloning here
-            elem.clone()
+            _elem: &PlaceElem<'tcx>,
+        ) -> Option<PlaceElem<'tcx>> {
+            None
         }
     );
 
diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs
index c4a19ce5128..9ecd6f83775 100644
--- a/src/librustc_mir/borrow_check/nll/renumber.rs
+++ b/src/librustc_mir/borrow_check/nll/renumber.rs
@@ -65,12 +65,16 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'tcx> {
     fn process_projection_elem(
         &mut self,
         elem: &PlaceElem<'tcx>,
-    ) -> PlaceElem<'tcx> {
+    ) -> Option<PlaceElem<'tcx>> {
         if let PlaceElem::Field(field, ty) = elem {
-            PlaceElem::Field(*field, self.renumber_regions(ty))
-        } else {
-            elem.clone()
+            let new_ty = self.renumber_regions(ty);
+
+            if new_ty != *ty {
+                return Some(PlaceElem::Field(*field, new_ty));
+            }
         }
+
+        None
     }
 
     fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) {
diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs
index 725a8de8fe7..439cae2093a 100644
--- a/src/librustc_mir/transform/erase_regions.rs
+++ b/src/librustc_mir/transform/erase_regions.rs
@@ -42,12 +42,16 @@ impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> {
     fn process_projection_elem(
         &mut self,
         elem: &PlaceElem<'tcx>,
-    ) -> PlaceElem<'tcx> {
+    ) -> Option<PlaceElem<'tcx>> {
         if let PlaceElem::Field(field, ty) = elem {
-            PlaceElem::Field(*field, self.tcx.erase_regions(ty))
-        } else {
-            elem.clone()
+            let new_ty = self.tcx.erase_regions(ty);
+
+            if new_ty != *ty {
+                return Some(PlaceElem::Field(*field, new_ty));
+            }
         }
+
+        None
     }
 }
 
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index a801548efab..6533e3c5ba8 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -89,22 +89,16 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor {
         }
     }
 
-    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.from => {
-                    PlaceElem::Index(self.to)
-                }
-                _ => elem.clone(),
+    fn process_projection_elem(
+        &mut self,
+        elem: &PlaceElem<'tcx>,
+    ) -> Option<PlaceElem<'tcx>> {
+        match elem {
+            PlaceElem::Index(local) if *local == self.from => {
+                Some(PlaceElem::Index(self.to))
             }
-        ).collect();
-
-        place.projection = new_projection.into_boxed_slice();
+            _ => None,
+        }
     }
 }
 
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index dd13d0c9655..0cbdcedff47 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -703,12 +703,16 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
     fn process_projection_elem(
         &mut self,
         elem: &PlaceElem<'tcx>,
-    ) -> PlaceElem<'tcx> {
+    ) -> Option<PlaceElem<'tcx>> {
         if let PlaceElem::Index(local) = elem {
-            PlaceElem::Index(self.make_integrate_local(local))
-        } else {
-            elem.clone()
+            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>) {
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index 565f260546b..ad1785417cd 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -408,12 +408,12 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> {
     fn process_projection_elem(
         &mut self,
         elem: &PlaceElem<'tcx>,
-    ) -> PlaceElem<'tcx> {
+    ) -> Option<PlaceElem<'tcx>> {
         match elem {
             PlaceElem::Index(local) if self.is_temp_kind(*local) => {
-                PlaceElem::Index(self.promote_temp(*local))
+                Some(PlaceElem::Index(self.promote_temp(*local)))
             }
-            _ => elem.clone(),
+            _ => None,
         }
     }
 }
diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs
index 7dca3e357cc..606c1a3a1cc 100644
--- a/src/librustc_mir/transform/simplify.rs
+++ b/src/librustc_mir/transform/simplify.rs
@@ -374,11 +374,12 @@ impl<'tcx> MutVisitor<'tcx> for LocalUpdater {
     fn process_projection_elem(
         &mut self,
         elem: &PlaceElem<'tcx>,
-    ) -> PlaceElem<'tcx> {
-        if let PlaceElem::Index(local) = elem {
-            PlaceElem::Index(self.map[*local].unwrap())
-        } else {
-            elem.clone()
+    ) -> Option<PlaceElem<'tcx>> {
+        match elem {
+            PlaceElem::Index(local) => {
+                Some(PlaceElem::Index(self.map[*local].unwrap()))
+            }
+            _ => None
         }
     }
 }
diff --git a/src/librustc_mir/util/def_use.rs b/src/librustc_mir/util/def_use.rs
index 25930df020a..cdd07ad4b8f 100644
--- a/src/librustc_mir/util/def_use.rs
+++ b/src/librustc_mir/util/def_use.rs
@@ -141,12 +141,12 @@ impl MutVisitor<'_> for MutateUseVisitor {
     fn process_projection_elem(
         &mut self,
         elem: &PlaceElem<'tcx>,
-    ) -> PlaceElem<'tcx> {
+    ) -> Option<PlaceElem<'tcx>> {
         match elem {
             PlaceElem::Index(local) if *local == self.query => {
-                PlaceElem::Index(self.new_local)
+                Some(PlaceElem::Index(self.new_local))
             }
-            _ => elem.clone(),
+            _ => None,
         }
     }
 }