diff options
| author | Santiago Pastorino <spastorino@gmail.com> | 2019-10-08 23:46:14 -0300 |
|---|---|---|
| committer | Santiago Pastorino <spastorino@gmail.com> | 2019-10-18 10:06:13 -0400 |
| commit | 48349960e68a9d19b17ac54cd12e939a9a46ea7d (patch) | |
| tree | 76fbadee0b0fbf3f6090122cb1d4f10583bf65f0 | |
| parent | d53fc9cae5b17c138be09383dea8b8f10d3df3a1 (diff) | |
| download | rust-48349960e68a9d19b17ac54cd12e939a9a46ea7d.tar.gz rust-48349960e68a9d19b17ac54cd12e939a9a46ea7d.zip | |
Use Cow to handle modifications of projection in preparation for interning
| -rw-r--r-- | src/librustc/mir/visit.rs | 33 | ||||
| -rw-r--r-- | src/librustc_mir/borrow_check/nll/renumber.rs | 12 | ||||
| -rw-r--r-- | src/librustc_mir/transform/erase_regions.rs | 12 | ||||
| -rw-r--r-- | src/librustc_mir/transform/generator.rs | 24 | ||||
| -rw-r--r-- | src/librustc_mir/transform/inline.rs | 12 | ||||
| -rw-r--r-- | src/librustc_mir/transform/promote_consts.rs | 6 | ||||
| -rw-r--r-- | src/librustc_mir/transform/simplify.rs | 11 | ||||
| -rw-r--r-- | src/librustc_mir/util/def_use.rs | 6 |
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, } } } |
