Use Cow to handle modifications of projection in preparation for interning

上级 d53fc9ca
......@@ -792,26 +792,37 @@ fn super_place(
) {
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
}
);
......
......@@ -65,12 +65,16 @@ fn visit_ty(&mut self, ty: &mut Ty<'tcx>, ty_context: TyContext) {
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) {
......
......@@ -42,12 +42,16 @@ fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, _: Location) {
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
}
}
......
......@@ -89,22 +89,16 @@ fn visit_local(&mut self,
}
}
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,
}
}
}
......
......@@ -703,12 +703,16 @@ fn visit_place(
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>) {
......
......@@ -408,12 +408,12 @@ fn visit_local(&mut self,
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,
}
}
}
......
......@@ -374,11 +374,12 @@ fn visit_local(&mut self, l: &mut Local, _: PlaceContext, _: Location) {
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
}
}
}
......@@ -141,12 +141,12 @@ fn visit_local(&mut self,
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,
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册