Skip to content

Commit

Permalink
Use Cow to handle modifications of projection in preparation for inte…
Browse files Browse the repository at this point in the history
…rning
  • Loading branch information
spastorino committed Oct 18, 2019
1 parent d53fc9c commit 4834996
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 49 deletions.
33 changes: 22 additions & 11 deletions src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
);

Expand Down
12 changes: 8 additions & 4 deletions src/librustc_mir/borrow_check/nll/renumber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
12 changes: 8 additions & 4 deletions src/librustc_mir/transform/erase_regions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down
24 changes: 9 additions & 15 deletions src/librustc_mir/transform/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
}

Expand Down
12 changes: 8 additions & 4 deletions src/librustc_mir/transform/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>) {
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_mir/transform/promote_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
}
Expand Down
11 changes: 6 additions & 5 deletions src/librustc_mir/transform/simplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
}
6 changes: 3 additions & 3 deletions src/librustc_mir/util/def_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
}

0 comments on commit 4834996

Please sign in to comment.