Skip to content

Commit cdf33d9

Browse files
committed
Use Cow to handle modifications of projection in preparation for interning
1 parent 6ec12a0 commit cdf33d9

File tree

7 files changed

+65
-45
lines changed

7 files changed

+65
-45
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 Cow::Owned(elem) = self.process_projection_elem(Cow::Borrowed(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: Cow<'a, PlaceElem<'tcx>>,
824+
) -> Cow<'a, PlaceElem<'tcx>> {
825+
elem
815826
}
816827
);
817828

src/librustc_mir/borrow_check/nll/renumber.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use rustc::mir::{Body, Location, PlaceElem, Promoted};
44
use rustc::mir::visit::{MutVisitor, TyContext};
55
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
66
use rustc_index::vec::IndexVec;
7+
use std::borrow::Cow;
78

89
/// Replaces all free regions appearing in the MIR with fresh
910
/// inference variables, returning the number of variables created.
@@ -64,12 +65,13 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'tcx> {
6465

6566
fn process_projection_elem(
6667
&mut self,
67-
elem: &PlaceElem<'tcx>,
68-
) -> PlaceElem<'tcx> {
69-
if let PlaceElem::Field(field, ty) = elem {
70-
PlaceElem::Field(*field, self.renumber_regions(ty))
71-
} else {
72-
elem.clone()
68+
elem: Cow<'b, PlaceElem<'tcx>>,
69+
) -> Cow<'b, PlaceElem<'tcx>> {
70+
match elem {
71+
Cow::Borrowed(PlaceElem::Field(field, ty)) => {
72+
Cow::Owned(PlaceElem::Field(*field, self.renumber_regions(ty)))
73+
}
74+
_ => elem,
7375
}
7476
}
7577

src/librustc_mir/transform/erase_regions.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc::ty::{self, Ty, TyCtxt};
99
use rustc::mir::*;
1010
use rustc::mir::visit::{MutVisitor, TyContext};
1111
use crate::transform::{MirPass, MirSource};
12+
use std::borrow::Cow;
1213

1314
struct EraseRegionsVisitor<'tcx> {
1415
tcx: TyCtxt<'tcx>,
@@ -41,12 +42,13 @@ impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> {
4142

4243
fn process_projection_elem(
4344
&mut self,
44-
elem: &PlaceElem<'tcx>,
45-
) -> PlaceElem<'tcx> {
46-
if let PlaceElem::Field(field, ty) = elem {
47-
PlaceElem::Field(*field, self.tcx.erase_regions(ty))
48-
} else {
49-
elem.clone()
45+
elem: Cow<'a, PlaceElem<'tcx>>,
46+
) -> Cow<'a, PlaceElem<'tcx>> {
47+
match elem {
48+
Cow::Borrowed(PlaceElem::Field(field, ty)) => {
49+
Cow::Owned(PlaceElem::Field(*field, self.tcx.erase_regions(ty)))
50+
}
51+
_ => elem,
5052
}
5153
}
5254
}

src/librustc_mir/transform/inline.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc::mir::visit::*;
1111
use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
1212
use rustc::ty::subst::{Subst, SubstsRef};
1313

14+
use std::borrow::Cow;
1415
use std::collections::VecDeque;
1516
use std::iter;
1617
use crate::transform::{MirPass, MirSource};
@@ -702,12 +703,13 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
702703

703704
fn process_projection_elem(
704705
&mut self,
705-
elem: &PlaceElem<'tcx>,
706-
) -> PlaceElem<'tcx> {
707-
if let PlaceElem::Index(local) = elem {
708-
PlaceElem::Index(self.make_integrate_local(local))
709-
} else {
710-
elem.clone()
706+
elem: Cow<'b, PlaceElem<'tcx>>,
707+
) -> Cow<'b, PlaceElem<'tcx>> {
708+
match elem {
709+
Cow::Borrowed(PlaceElem::Index(local)) => {
710+
Cow::Owned(PlaceElem::Index(self.make_integrate_local(local)))
711+
}
712+
_ => elem,
711713
}
712714
}
713715

src/librustc_mir/transform/promote_consts.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use syntax_pos::Span;
2323
use rustc_index::vec::{IndexVec, Idx};
2424

2525
use std::{iter, mem, usize};
26+
use std::borrow::Cow;
2627

2728
/// State of a temporary during collection and promotion.
2829
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
@@ -407,13 +408,13 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> {
407408

408409
fn process_projection_elem(
409410
&mut self,
410-
elem: &PlaceElem<'tcx>,
411-
) -> PlaceElem<'tcx> {
411+
elem: Cow<'b, PlaceElem<'tcx>>,
412+
) -> Cow<'b, PlaceElem<'tcx>> {
412413
match elem {
413-
PlaceElem::Index(local) if self.is_temp_kind(*local) => {
414-
PlaceElem::Index(self.promote_temp(*local))
414+
Cow::Borrowed(PlaceElem::Index(local)) if self.is_temp_kind(*local) => {
415+
Cow::Owned(PlaceElem::Index(self.promote_temp(*local)))
415416
}
416-
_ => elem.clone(),
417+
_ => elem,
417418
}
418419
}
419420
}

src/librustc_mir/transform/simplify.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -373,12 +373,13 @@ impl<'tcx> MutVisitor<'tcx> for LocalUpdater {
373373

374374
fn process_projection_elem(
375375
&mut self,
376-
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()
376+
elem: Cow<'a, PlaceElem<'tcx>>,
377+
) -> Cow<'a, PlaceElem<'tcx>> {
378+
match elem {
379+
Cow::Borrowed(PlaceElem::Index(local)) => {
380+
Cow::Owned(PlaceElem::Index(self.map[*local].unwrap()))
381+
}
382+
_ => elem,
382383
}
383384
}
384385
}

src/librustc_mir/util/def_use.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use rustc::mir::{Body, Local, Location, PlaceElem};
44
use rustc::mir::visit::{PlaceContext, MutVisitor, Visitor};
55
use rustc_index::vec::IndexVec;
6+
use std::borrow::Cow;
67
use std::mem;
78

89
pub struct DefUseAnalysis {
@@ -140,13 +141,13 @@ impl MutVisitor<'_> for MutateUseVisitor {
140141

141142
fn process_projection_elem(
142143
&mut self,
143-
elem: &PlaceElem<'tcx>,
144-
) -> PlaceElem<'tcx> {
144+
elem: Cow<'a, PlaceElem<'tcx>>,
145+
) -> Cow<'a, PlaceElem<'tcx>> {
145146
match elem {
146-
PlaceElem::Index(local) if *local == self.query => {
147-
PlaceElem::Index(self.new_local)
147+
Cow::Borrowed(PlaceElem::Index(local)) if *local == self.query => {
148+
Cow::Owned(PlaceElem::Index(self.new_local))
148149
}
149-
_ => elem.clone(),
150+
_ => elem,
150151
}
151152
}
152153
}

0 commit comments

Comments
 (0)