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 11, 2019
1 parent 6ec12a0 commit cdf33d9
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 45 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 Cow::Owned(elem) = self.process_projection_elem(Cow::Borrowed(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: Cow<'a, PlaceElem<'tcx>>,
) -> Cow<'a, PlaceElem<'tcx>> {
elem
}
);

Expand Down
14 changes: 8 additions & 6 deletions src/librustc_mir/borrow_check/nll/renumber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use rustc::mir::{Body, Location, PlaceElem, Promoted};
use rustc::mir::visit::{MutVisitor, TyContext};
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
use rustc_index::vec::IndexVec;
use std::borrow::Cow;

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

fn process_projection_elem(
&mut self,
elem: &PlaceElem<'tcx>,
) -> PlaceElem<'tcx> {
if let PlaceElem::Field(field, ty) = elem {
PlaceElem::Field(*field, self.renumber_regions(ty))
} else {
elem.clone()
elem: Cow<'b, PlaceElem<'tcx>>,
) -> Cow<'b, PlaceElem<'tcx>> {
match elem {
Cow::Borrowed(PlaceElem::Field(field, ty)) => {
Cow::Owned(PlaceElem::Field(*field, self.renumber_regions(ty)))
}
_ => elem,
}
}

Expand Down
14 changes: 8 additions & 6 deletions src/librustc_mir/transform/erase_regions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use rustc::ty::{self, Ty, TyCtxt};
use rustc::mir::*;
use rustc::mir::visit::{MutVisitor, TyContext};
use crate::transform::{MirPass, MirSource};
use std::borrow::Cow;

struct EraseRegionsVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
Expand Down Expand Up @@ -41,12 +42,13 @@ impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> {

fn process_projection_elem(
&mut self,
elem: &PlaceElem<'tcx>,
) -> PlaceElem<'tcx> {
if let PlaceElem::Field(field, ty) = elem {
PlaceElem::Field(*field, self.tcx.erase_regions(ty))
} else {
elem.clone()
elem: Cow<'a, PlaceElem<'tcx>>,
) -> Cow<'a, PlaceElem<'tcx>> {
match elem {
Cow::Borrowed(PlaceElem::Field(field, ty)) => {
Cow::Owned(PlaceElem::Field(*field, self.tcx.erase_regions(ty)))
}
_ => elem,
}
}
}
Expand Down
14 changes: 8 additions & 6 deletions src/librustc_mir/transform/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use rustc::mir::visit::*;
use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
use rustc::ty::subst::{Subst, SubstsRef};

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

fn process_projection_elem(
&mut self,
elem: &PlaceElem<'tcx>,
) -> PlaceElem<'tcx> {
if let PlaceElem::Index(local) = elem {
PlaceElem::Index(self.make_integrate_local(local))
} else {
elem.clone()
elem: Cow<'b, PlaceElem<'tcx>>,
) -> Cow<'b, PlaceElem<'tcx>> {
match elem {
Cow::Borrowed(PlaceElem::Index(local)) => {
Cow::Owned(PlaceElem::Index(self.make_integrate_local(local)))
}
_ => elem,
}
}

Expand Down
11 changes: 6 additions & 5 deletions src/librustc_mir/transform/promote_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use syntax_pos::Span;
use rustc_index::vec::{IndexVec, Idx};

use std::{iter, mem, usize};
use std::borrow::Cow;

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

fn process_projection_elem(
&mut self,
elem: &PlaceElem<'tcx>,
) -> PlaceElem<'tcx> {
elem: Cow<'b, PlaceElem<'tcx>>,
) -> Cow<'b, PlaceElem<'tcx>> {
match elem {
PlaceElem::Index(local) if self.is_temp_kind(*local) => {
PlaceElem::Index(self.promote_temp(*local))
Cow::Borrowed(PlaceElem::Index(local)) if self.is_temp_kind(*local) => {
Cow::Owned(PlaceElem::Index(self.promote_temp(*local)))
}
_ => elem.clone(),
_ => elem,
}
}
}
Expand Down
13 changes: 7 additions & 6 deletions src/librustc_mir/transform/simplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,12 +373,13 @@ 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()
elem: Cow<'a, PlaceElem<'tcx>>,
) -> Cow<'a, PlaceElem<'tcx>> {
match elem {
Cow::Borrowed(PlaceElem::Index(local)) => {
Cow::Owned(PlaceElem::Index(self.map[*local].unwrap()))
}
_ => elem,
}
}
}
11 changes: 6 additions & 5 deletions src/librustc_mir/util/def_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use rustc::mir::{Body, Local, Location, PlaceElem};
use rustc::mir::visit::{PlaceContext, MutVisitor, Visitor};
use rustc_index::vec::IndexVec;
use std::borrow::Cow;
use std::mem;

pub struct DefUseAnalysis {
Expand Down Expand Up @@ -140,13 +141,13 @@ impl MutVisitor<'_> for MutateUseVisitor {

fn process_projection_elem(
&mut self,
elem: &PlaceElem<'tcx>,
) -> PlaceElem<'tcx> {
elem: Cow<'a, PlaceElem<'tcx>>,
) -> Cow<'a, PlaceElem<'tcx>> {
match elem {
PlaceElem::Index(local) if *local == self.query => {
PlaceElem::Index(self.new_local)
Cow::Borrowed(PlaceElem::Index(local)) if *local == self.query => {
Cow::Owned(PlaceElem::Index(self.new_local))
}
_ => elem.clone(),
_ => elem,
}
}
}

0 comments on commit cdf33d9

Please sign in to comment.