Skip to content

Commit

Permalink
Move Place::elem methods and friends to TyCtxt
Browse files Browse the repository at this point in the history
  • Loading branch information
spastorino committed Oct 22, 2019
1 parent d32c286 commit 180fc41
Show file tree
Hide file tree
Showing 13 changed files with 139 additions and 124 deletions.
45 changes: 0 additions & 45 deletions src/librustc/mir/mod.rs
Expand Up @@ -1857,51 +1857,6 @@ impl<'tcx> Place<'tcx> {
}
}

pub fn field(self, f: Field, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Place<'tcx> {
self.elem(ProjectionElem::Field(f, ty), tcx)
}

pub fn deref(self, tcx: TyCtxt<'tcx>) -> Place<'tcx> {
self.elem(ProjectionElem::Deref, tcx)
}

pub fn downcast(
self,
adt_def: &'tcx AdtDef,
variant_index: VariantIdx,
tcx: TyCtxt<'tcx>,
) -> Place<'tcx> {
self.elem(
ProjectionElem::Downcast(
Some(adt_def.variants[variant_index].ident.name),
variant_index,
),
tcx,
)
}

pub fn downcast_unnamed(self, variant_index: VariantIdx, tcx: TyCtxt<'tcx>) -> Place<'tcx> {
self.elem(ProjectionElem::Downcast(None, variant_index), tcx)
}

pub fn index(self, index: Local, tcx: TyCtxt<'tcx>) -> Place<'tcx> {
self.elem(ProjectionElem::Index(index), tcx)
}

/// This method copies `Place`'s projection, add an element and reintern it. Should not be used
/// to build a full `Place` it's just a convenient way to grab a projection and modify it in
/// flight.
// FIXME: It may be a better idea to move all these methods to `PlaceBuilder`
pub fn elem(self, elem: PlaceElem<'tcx>, tcx: TyCtxt<'tcx>) -> Place<'tcx> {
let mut projection = self.projection.to_vec();
projection.push(elem);

Place {
base: self.base,
projection: tcx.intern_place_elems(&projection),
}
}

/// Returns `true` if this `Place` contains a `Deref` projection.
///
/// If `Place::is_indirect` returns false, the caller knows that the `Place` refers to the
Expand Down
44 changes: 43 additions & 1 deletion src/librustc/ty/context.rs
Expand Up @@ -21,7 +21,7 @@ use crate::middle::cstore::EncodedMetadata;
use crate::middle::lang_items;
use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault};
use crate::middle::stability;
use crate::mir::{Body, interpret, PlaceElem, ProjectionKind, Promoted};
use crate::mir::{Body, Field, interpret, Local, Place, PlaceElem, ProjectionKind, Promoted};
use crate::mir::interpret::{ConstValue, Allocation, Scalar};
use crate::ty::subst::{GenericArg, InternalSubsts, SubstsRef, Subst};
use crate::ty::ReprOptions;
Expand Down Expand Up @@ -2597,6 +2597,48 @@ impl<'tcx> TyCtxt<'tcx> {
self.mk_ty(Opaque(def_id, substs))
}

pub fn mk_place_field(self, place: Place<'tcx>, f: Field, ty: Ty<'tcx>) -> Place<'tcx> {
self.mk_place_elem(place, PlaceElem::Field(f, ty))
}

pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> {
self.mk_place_elem(place, PlaceElem::Deref)
}

pub fn mk_place_downcast(
self,
place: Place<'tcx>,
adt_def: &'tcx AdtDef,
variant_index: VariantIdx,
) -> Place<'tcx> {
self.mk_place_elem(
place,
PlaceElem::Downcast(Some(adt_def.variants[variant_index].ident.name), variant_index),
)
}

pub fn mk_place_downcast_unnamed(
self,
place: Place<'tcx>,
variant_index: VariantIdx,
) -> Place<'tcx> {
self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index))
}

pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
self.mk_place_elem(place, PlaceElem::Index(index))
}

/// This method copies `Place`'s projection, add an element and reintern it. Should not be used
/// to build a full `Place` it's just a convenient way to grab a projection and modify it in
/// flight.
pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> {
let mut projection = place.projection.to_vec();
projection.push(elem);

Place { base: place.base, projection: self.intern_place_elems(&projection) }
}

pub fn intern_existential_predicates(self, eps: &[ExistentialPredicate<'tcx>])
-> &'tcx List<ExistentialPredicate<'tcx>> {
assert!(!eps.is_empty());
Expand Down
11 changes: 6 additions & 5 deletions src/librustc_mir/build/expr/as_rvalue.rs
Expand Up @@ -139,7 +139,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// initialize the box contents:
unpack!(
block = this.into(
&Place::from(result).deref(this.hir.tcx()),
&this.hir.tcx().mk_place_deref(Place::from(result)),
block, value
)
);
Expand Down Expand Up @@ -296,10 +296,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.zip(field_types.into_iter())
.map(|(n, ty)| match fields_map.get(&n) {
Some(v) => v.clone(),
None => this.consume_by_copy_or_move(base.clone().field(
None => this.consume_by_copy_or_move(this.hir.tcx().mk_place_field(
base.clone(),
n,
ty,
this.hir.tcx(),
)),
})
.collect()
Expand Down Expand Up @@ -402,8 +402,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let val_fld = Field::new(0);
let of_fld = Field::new(1);

let val = result_value.clone().field(val_fld, ty, self.hir.tcx());
let of = result_value.field(of_fld, bool_ty, self.hir.tcx());
let tcx = self.hir.tcx();
let val = tcx.mk_place_field(result_value.clone(), val_fld, ty);
let of = tcx.mk_place_field(result_value, of_fld, bool_ty);

let err = PanicInfo::Overflow(op);

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/build/expr/into.rs
Expand Up @@ -235,7 +235,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
});
let ptr_temp = Place::from(ptr_temp);
let block = unpack!(this.into(&ptr_temp, block, ptr));
this.into(&ptr_temp.deref(this.hir.tcx()), block, val)
this.into(&this.hir.tcx().mk_place_deref(ptr_temp), block, val)
} else {
let args: Vec<_> = args
.into_iter()
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/build/matches/simplify.rs
Expand Up @@ -166,7 +166,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
});
if irrefutable {
let place = match_pair.place.downcast(adt_def, variant_index, tcx);
let place = tcx.mk_place_downcast(match_pair.place, adt_def, variant_index);
candidate.match_pairs.extend(self.field_match_pairs(place, subpatterns));
Ok(())
} else {
Expand All @@ -191,7 +191,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}

PatKind::Deref { ref subpattern } => {
let place = match_pair.place.deref(tcx);
let place = tcx.mk_place_deref(match_pair.place);
candidate.match_pairs.push(MatchPair::new(place, subpattern));
Ok(())
}
Expand Down
20 changes: 9 additions & 11 deletions src/librustc_mir/build/matches/test.rs
Expand Up @@ -743,23 +743,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
candidate: &mut Candidate<'pat, 'tcx>,
) {
let match_pair = candidate.match_pairs.remove(match_pair_index);
let tcx = self.hir.tcx();

// So, if we have a match-pattern like `x @ Enum::Variant(P1, P2)`,
// we want to create a set of derived match-patterns like
// `(x as Variant).0 @ P1` and `(x as Variant).1 @ P1`.
let elem = ProjectionElem::Downcast(
Some(adt_def.variants[variant_index].ident.name), variant_index);
let downcast_place = match_pair.place.elem(elem, self.hir.tcx()); // `(x as Variant)`
let consequent_match_pairs =
subpatterns.iter()
.map(|subpattern| {
// e.g., `(x as Variant).0`
let place = downcast_place.clone().field(subpattern.field,
subpattern.pattern.ty,
self.hir.tcx());
// e.g., `(x as Variant).0 @ P1`
MatchPair::new(place, &subpattern.pattern)
});
let downcast_place = tcx.mk_place_elem(match_pair.place, elem); // `(x as Variant)`
let consequent_match_pairs = subpatterns.iter().map(|subpattern| {
// e.g., `(x as Variant).0`
let place =
tcx.mk_place_field(downcast_place.clone(), subpattern.field, subpattern.pattern.ty);
// e.g., `(x as Variant).0 @ P1`
MatchPair::new(place, &subpattern.pattern)
});

candidate.match_pairs.extend(consequent_match_pairs);
}
Expand Down
37 changes: 21 additions & 16 deletions src/librustc_mir/build/matches/util.rs
Expand Up @@ -6,18 +6,22 @@ use std::u32;
use std::convert::TryInto;

impl<'a, 'tcx> Builder<'a, 'tcx> {
pub fn field_match_pairs<'pat>(&mut self,
place: Place<'tcx>,
subpatterns: &'pat [FieldPat<'tcx>])
-> Vec<MatchPair<'pat, 'tcx>> {
subpatterns.iter()
.map(|fieldpat| {
let place = place.clone().field(fieldpat.field,
fieldpat.pattern.ty,
self.hir.tcx());
MatchPair::new(place, &fieldpat.pattern)
})
.collect()
pub fn field_match_pairs<'pat>(
&mut self,
place: Place<'tcx>,
subpatterns: &'pat [FieldPat<'tcx>],
) -> Vec<MatchPair<'pat, 'tcx>> {
subpatterns
.iter()
.map(|fieldpat| {
let place = self.hir.tcx().mk_place_field(
place.clone(),
fieldpat.field,
fieldpat.pattern.ty,
);
MatchPair::new(place, &fieldpat.pattern)
})
.collect()
}

pub fn prefix_slice_suffix<'pat>(&mut self,
Expand All @@ -28,6 +32,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
suffix: &'pat [Pat<'tcx>]) {
let min_length = prefix.len() + suffix.len();
let min_length = min_length.try_into().unwrap();
let tcx = self.hir.tcx();

match_pairs.extend(
prefix.iter()
Expand All @@ -38,16 +43,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
min_length,
from_end: false,
};
let place = place.clone().elem(elem, self.hir.tcx());
let place = tcx.mk_place_elem(place.clone(), elem);
MatchPair::new(place, subpattern)
})
);

if let Some(subslice_pat) = opt_slice {
let subslice = place.clone().elem(ProjectionElem::Subslice {
let subslice = tcx.mk_place_elem(place.clone(),ProjectionElem::Subslice {
from: prefix.len() as u32,
to: suffix.len() as u32
}, self.hir.tcx());
});
match_pairs.push(MatchPair::new(subslice, subslice_pat));
}

Expand All @@ -61,7 +66,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
min_length,
from_end: true,
};
let place = place.clone().elem(elem, self.hir.tcx());
let place = tcx.mk_place_elem(place.clone(), elem);
MatchPair::new(place, subpattern)
})
);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/dataflow/move_paths/builder.rs
Expand Up @@ -274,7 +274,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
// Box starts out uninitialized - need to create a separate
// move-path for the interior so it will be separate from
// the exterior.
self.create_move_path(&place.clone().deref(self.builder.tcx));
self.create_move_path(&self.builder.tcx.mk_place_deref(place.clone()));
self.gather_init(place.as_ref(), InitKind::Shallow);
} else {
self.gather_init(place.as_ref(), InitKind::Deep);
Expand Down
22 changes: 11 additions & 11 deletions src/librustc_mir/shim.rs
Expand Up @@ -231,7 +231,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
tcx,
param_env
};
let dropee = dropee_ptr.deref(tcx);
let dropee = tcx.mk_place_deref(dropee_ptr);
let resume_block = elaborator.patch.resume_block();
elaborate_drops::elaborate_drop(
&mut elaborator,
Expand Down Expand Up @@ -312,7 +312,7 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -
let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env, builder.span);

let dest = Place::return_place();
let src = Place::from(Local::new(1+0)).deref(tcx);
let src = tcx.mk_place_deref(Place::from(Local::new(1+0)));

match self_ty.kind {
_ if is_copy => builder.copy_shim(),
Expand Down Expand Up @@ -415,7 +415,7 @@ impl CloneShimBuilder<'tcx> {
}

fn copy_shim(&mut self) {
let rcvr = Place::from(Local::new(1+0)).deref(self.tcx);
let rcvr = self.tcx.mk_place_deref(Place::from(Local::new(1+0)));
let ret_statement = self.make_statement(
StatementKind::Assign(
box(
Expand Down Expand Up @@ -561,8 +561,8 @@ impl CloneShimBuilder<'tcx> {
// BB #2
// `dest[i] = Clone::clone(src[beg])`;
// Goto #3 if ok, #5 if unwinding happens.
let dest_field = dest.clone().index(beg, self.tcx);
let src_field = src.index(beg, self.tcx);
let dest_field = self.tcx.mk_place_index(dest.clone(), beg);
let src_field = self.tcx.mk_place_index(src, beg);
self.make_clone_call(dest_field, src_field, ty, BasicBlock::new(3),
BasicBlock::new(5));

Expand Down Expand Up @@ -616,7 +616,7 @@ impl CloneShimBuilder<'tcx> {
// BB #7 (cleanup)
// `drop(dest[beg])`;
self.block(vec![], TerminatorKind::Drop {
location: dest.index(beg, self.tcx),
location: self.tcx.mk_place_index(dest, beg),
target: BasicBlock::new(8),
unwind: None,
}, true);
Expand Down Expand Up @@ -648,9 +648,9 @@ impl CloneShimBuilder<'tcx> {
let mut previous_field = None;
for (i, ity) in tys.enumerate() {
let field = Field::new(i);
let src_field = src.clone().field(field, ity, self.tcx);
let src_field = self.tcx.mk_place_field(src.clone(), field, ity);

let dest_field = dest.clone().field(field, ity, self.tcx);
let dest_field = self.tcx.mk_place_field(dest.clone(), field, ity);

// #(2i + 1) is the cleanup block for the previous clone operation
let cleanup_block = self.block_index_offset(1);
Expand Down Expand Up @@ -721,14 +721,14 @@ fn build_call_shim<'tcx>(

let rcvr = match rcvr_adjustment {
Adjustment::Identity => Operand::Move(rcvr_l),
Adjustment::Deref => Operand::Copy(rcvr_l.deref(tcx)),
Adjustment::Deref => Operand::Copy(tcx.mk_place_deref(rcvr_l)),
Adjustment::DerefMove => {
// fn(Self, ...) -> fn(*mut Self, ...)
let arg_ty = local_decls[rcvr_arg].ty;
debug_assert!(tcx.generics_of(def_id).has_self && arg_ty == tcx.types.self_param);
local_decls[rcvr_arg].ty = tcx.mk_mut_ptr(arg_ty);

Operand::Move(rcvr_l.deref(tcx))
Operand::Move(tcx.mk_place_deref(rcvr_l))
}
Adjustment::RefMut => {
// let rcvr = &mut rcvr;
Expand Down Expand Up @@ -772,7 +772,7 @@ fn build_call_shim<'tcx>(
if let Some(untuple_args) = untuple_args {
args.extend(untuple_args.iter().enumerate().map(|(i, ity)| {
let arg_place = Place::from(Local::new(1+1));
Operand::Move(arg_place.field(Field::new(i), *ity, tcx))
Operand::Move(tcx.mk_place_field(arg_place, Field::new(i), *ity))
}));
} else {
args.extend((1..sig.inputs().len()).map(|i| {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/transform/generator.rs
Expand Up @@ -246,7 +246,7 @@ impl TransformVisitor<'tcx> {
// Create a Place referencing a generator struct field
fn make_field(&self, variant_index: VariantIdx, idx: usize, ty: Ty<'tcx>) -> Place<'tcx> {
let self_place = Place::from(self_arg());
let base = self_place.downcast_unnamed(variant_index, self.tcx);
let base = self.tcx.mk_place_downcast_unnamed(self_place, variant_index);
let mut projection = base.projection.to_vec();
projection.push(ProjectionElem::Field(Field::new(idx), ty));

Expand Down

0 comments on commit 180fc41

Please sign in to comment.