Skip to content

Commit 4834996

Browse files
committed
Use Cow to handle modifications of projection in preparation for interning
1 parent d53fc9c commit 4834996

File tree

8 files changed

+67
-49
lines changed

8 files changed

+67
-49
lines changed

src/librustc/mir/visit.rs

+22-11
Original file line numberDiff line numberDiff line change
@@ -792,26 +792,37 @@ macro_rules! visit_place_fns {
792792
) {
793793
self.visit_place_base(&mut place.base, context, location);
794794

795-
place.projection = self.process_projection(&place.projection);
795+
if let Some(new_projection) = self.process_projection(&place.projection) {
796+
place.projection = new_projection;
797+
}
796798
}
797799

798800
fn process_projection(
799801
&mut self,
800-
projection: &Box<[PlaceElem<'tcx>]>,
801-
) -> Box<[PlaceElem<'tcx>]> {
802-
let new_projection: Vec<_> = projection.iter().map(|elem|
803-
self.process_projection_elem(elem)
804-
).collect();
802+
projection: &'a [PlaceElem<'tcx>],
803+
) -> Option<Box<[PlaceElem<'tcx>]>> {
804+
let mut projection = Cow::Borrowed(projection);
805+
806+
for i in 0..projection.len() {
807+
if let Some(elem) = projection.get(i) {
808+
if let Some(elem) = self.process_projection_elem(elem) {
809+
let vec = projection.to_mut();
810+
vec[i] = elem;
811+
}
812+
}
813+
}
805814

806-
new_projection.into_boxed_slice()
815+
match projection {
816+
Cow::Borrowed(_) => None,
817+
Cow::Owned(vec) => Some(vec.into_boxed_slice()),
818+
}
807819
}
808820

809821
fn process_projection_elem(
810822
&mut self,
811-
elem: &PlaceElem<'tcx>,
812-
) -> PlaceElem<'tcx> {
813-
// FIXME: avoid cloning here
814-
elem.clone()
823+
_elem: &PlaceElem<'tcx>,
824+
) -> Option<PlaceElem<'tcx>> {
825+
None
815826
}
816827
);
817828

src/librustc_mir/borrow_check/nll/renumber.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,16 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'tcx> {
6565
fn process_projection_elem(
6666
&mut self,
6767
elem: &PlaceElem<'tcx>,
68-
) -> PlaceElem<'tcx> {
68+
) -> Option<PlaceElem<'tcx>> {
6969
if let PlaceElem::Field(field, ty) = elem {
70-
PlaceElem::Field(*field, self.renumber_regions(ty))
71-
} else {
72-
elem.clone()
70+
let new_ty = self.renumber_regions(ty);
71+
72+
if new_ty != *ty {
73+
return Some(PlaceElem::Field(*field, new_ty));
74+
}
7375
}
76+
77+
None
7478
}
7579

7680
fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) {

src/librustc_mir/transform/erase_regions.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,16 @@ impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> {
4242
fn process_projection_elem(
4343
&mut self,
4444
elem: &PlaceElem<'tcx>,
45-
) -> PlaceElem<'tcx> {
45+
) -> Option<PlaceElem<'tcx>> {
4646
if let PlaceElem::Field(field, ty) = elem {
47-
PlaceElem::Field(*field, self.tcx.erase_regions(ty))
48-
} else {
49-
elem.clone()
47+
let new_ty = self.tcx.erase_regions(ty);
48+
49+
if new_ty != *ty {
50+
return Some(PlaceElem::Field(*field, new_ty));
51+
}
5052
}
53+
54+
None
5155
}
5256
}
5357

src/librustc_mir/transform/generator.rs

+9-15
Original file line numberDiff line numberDiff line change
@@ -89,22 +89,16 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor {
8989
}
9090
}
9191

92-
fn visit_place(&mut self,
93-
place: &mut Place<'tcx>,
94-
context: PlaceContext,
95-
location: Location) {
96-
self.visit_place_base(&mut place.base, context, location);
97-
98-
let new_projection: Vec<_> = place.projection.iter().map(|elem|
99-
match elem {
100-
PlaceElem::Index(local) if *local == self.from => {
101-
PlaceElem::Index(self.to)
102-
}
103-
_ => elem.clone(),
92+
fn process_projection_elem(
93+
&mut self,
94+
elem: &PlaceElem<'tcx>,
95+
) -> Option<PlaceElem<'tcx>> {
96+
match elem {
97+
PlaceElem::Index(local) if *local == self.from => {
98+
Some(PlaceElem::Index(self.to))
10499
}
105-
).collect();
106-
107-
place.projection = new_projection.into_boxed_slice();
100+
_ => None,
101+
}
108102
}
109103
}
110104

src/librustc_mir/transform/inline.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -703,12 +703,16 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
703703
fn process_projection_elem(
704704
&mut self,
705705
elem: &PlaceElem<'tcx>,
706-
) -> PlaceElem<'tcx> {
706+
) -> Option<PlaceElem<'tcx>> {
707707
if let PlaceElem::Index(local) = elem {
708-
PlaceElem::Index(self.make_integrate_local(local))
709-
} else {
710-
elem.clone()
708+
let new_local = self.make_integrate_local(local);
709+
710+
if new_local != *local {
711+
return Some(PlaceElem::Index(new_local))
712+
}
711713
}
714+
715+
None
712716
}
713717

714718
fn visit_basic_block_data(&mut self, block: BasicBlock, data: &mut BasicBlockData<'tcx>) {

src/librustc_mir/transform/promote_consts.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -408,12 +408,12 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> {
408408
fn process_projection_elem(
409409
&mut self,
410410
elem: &PlaceElem<'tcx>,
411-
) -> PlaceElem<'tcx> {
411+
) -> Option<PlaceElem<'tcx>> {
412412
match elem {
413413
PlaceElem::Index(local) if self.is_temp_kind(*local) => {
414-
PlaceElem::Index(self.promote_temp(*local))
414+
Some(PlaceElem::Index(self.promote_temp(*local)))
415415
}
416-
_ => elem.clone(),
416+
_ => None,
417417
}
418418
}
419419
}

src/librustc_mir/transform/simplify.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -374,11 +374,12 @@ impl<'tcx> MutVisitor<'tcx> for LocalUpdater {
374374
fn process_projection_elem(
375375
&mut self,
376376
elem: &PlaceElem<'tcx>,
377-
) -> PlaceElem<'tcx> {
378-
if let PlaceElem::Index(local) = elem {
379-
PlaceElem::Index(self.map[*local].unwrap())
380-
} else {
381-
elem.clone()
377+
) -> Option<PlaceElem<'tcx>> {
378+
match elem {
379+
PlaceElem::Index(local) => {
380+
Some(PlaceElem::Index(self.map[*local].unwrap()))
381+
}
382+
_ => None
382383
}
383384
}
384385
}

src/librustc_mir/util/def_use.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,12 @@ impl MutVisitor<'_> for MutateUseVisitor {
141141
fn process_projection_elem(
142142
&mut self,
143143
elem: &PlaceElem<'tcx>,
144-
) -> PlaceElem<'tcx> {
144+
) -> Option<PlaceElem<'tcx>> {
145145
match elem {
146146
PlaceElem::Index(local) if *local == self.query => {
147-
PlaceElem::Index(self.new_local)
147+
Some(PlaceElem::Index(self.new_local))
148148
}
149-
_ => elem.clone(),
149+
_ => None,
150150
}
151151
}
152152
}

0 commit comments

Comments
 (0)