1
Fork 0

Move Place::elem methods and friends to TyCtxt

This commit is contained in:
Santiago Pastorino 2019-10-20 21:04:59 -04:00
parent d32c2865d6
commit 180fc413fb
No known key found for this signature in database
GPG key ID: 88C941CDA1D46432
13 changed files with 139 additions and 124 deletions

View file

@ -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. /// Returns `true` if this `Place` contains a `Deref` projection.
/// ///
/// If `Place::is_indirect` returns false, the caller knows that the `Place` refers to the /// If `Place::is_indirect` returns false, the caller knows that the `Place` refers to the

View file

@ -21,7 +21,7 @@ use crate::middle::cstore::EncodedMetadata;
use crate::middle::lang_items; use crate::middle::lang_items;
use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault}; use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault};
use crate::middle::stability; 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::mir::interpret::{ConstValue, Allocation, Scalar};
use crate::ty::subst::{GenericArg, InternalSubsts, SubstsRef, Subst}; use crate::ty::subst::{GenericArg, InternalSubsts, SubstsRef, Subst};
use crate::ty::ReprOptions; use crate::ty::ReprOptions;
@ -2597,6 +2597,48 @@ impl<'tcx> TyCtxt<'tcx> {
self.mk_ty(Opaque(def_id, substs)) 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>]) pub fn intern_existential_predicates(self, eps: &[ExistentialPredicate<'tcx>])
-> &'tcx List<ExistentialPredicate<'tcx>> { -> &'tcx List<ExistentialPredicate<'tcx>> {
assert!(!eps.is_empty()); assert!(!eps.is_empty());

View file

@ -139,7 +139,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// initialize the box contents: // initialize the box contents:
unpack!( unpack!(
block = this.into( block = this.into(
&Place::from(result).deref(this.hir.tcx()), &this.hir.tcx().mk_place_deref(Place::from(result)),
block, value block, value
) )
); );
@ -296,10 +296,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.zip(field_types.into_iter()) .zip(field_types.into_iter())
.map(|(n, ty)| match fields_map.get(&n) { .map(|(n, ty)| match fields_map.get(&n) {
Some(v) => v.clone(), 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, n,
ty, ty,
this.hir.tcx(),
)), )),
}) })
.collect() .collect()
@ -402,8 +402,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let val_fld = Field::new(0); let val_fld = Field::new(0);
let of_fld = Field::new(1); let of_fld = Field::new(1);
let val = result_value.clone().field(val_fld, ty, self.hir.tcx()); let tcx = self.hir.tcx();
let of = result_value.field(of_fld, bool_ty, 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); let err = PanicInfo::Overflow(op);

View file

@ -235,7 +235,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}); });
let ptr_temp = Place::from(ptr_temp); let ptr_temp = Place::from(ptr_temp);
let block = unpack!(this.into(&ptr_temp, block, ptr)); 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 { } else {
let args: Vec<_> = args let args: Vec<_> = args
.into_iter() .into_iter()

View file

@ -166,7 +166,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} }
}); });
if irrefutable { 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)); candidate.match_pairs.extend(self.field_match_pairs(place, subpatterns));
Ok(()) Ok(())
} else { } else {
@ -191,7 +191,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} }
PatKind::Deref { ref subpattern } => { 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)); candidate.match_pairs.push(MatchPair::new(place, subpattern));
Ok(()) Ok(())
} }

View file

@ -743,23 +743,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
candidate: &mut Candidate<'pat, 'tcx>, candidate: &mut Candidate<'pat, 'tcx>,
) { ) {
let match_pair = candidate.match_pairs.remove(match_pair_index); 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)`, // So, if we have a match-pattern like `x @ Enum::Variant(P1, P2)`,
// we want to create a set of derived match-patterns like // we want to create a set of derived match-patterns like
// `(x as Variant).0 @ P1` and `(x as Variant).1 @ P1`. // `(x as Variant).0 @ P1` and `(x as Variant).1 @ P1`.
let elem = ProjectionElem::Downcast( let elem = ProjectionElem::Downcast(
Some(adt_def.variants[variant_index].ident.name), variant_index); 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 downcast_place = tcx.mk_place_elem(match_pair.place, elem); // `(x as Variant)`
let consequent_match_pairs = let consequent_match_pairs = subpatterns.iter().map(|subpattern| {
subpatterns.iter() // e.g., `(x as Variant).0`
.map(|subpattern| { let place =
// e.g., `(x as Variant).0` tcx.mk_place_field(downcast_place.clone(), subpattern.field, subpattern.pattern.ty);
let place = downcast_place.clone().field(subpattern.field, // e.g., `(x as Variant).0 @ P1`
subpattern.pattern.ty, MatchPair::new(place, &subpattern.pattern)
self.hir.tcx()); });
// e.g., `(x as Variant).0 @ P1`
MatchPair::new(place, &subpattern.pattern)
});
candidate.match_pairs.extend(consequent_match_pairs); candidate.match_pairs.extend(consequent_match_pairs);
} }

View file

@ -6,18 +6,22 @@ use std::u32;
use std::convert::TryInto; use std::convert::TryInto;
impl<'a, 'tcx> Builder<'a, 'tcx> { impl<'a, 'tcx> Builder<'a, 'tcx> {
pub fn field_match_pairs<'pat>(&mut self, pub fn field_match_pairs<'pat>(
place: Place<'tcx>, &mut self,
subpatterns: &'pat [FieldPat<'tcx>]) place: Place<'tcx>,
-> Vec<MatchPair<'pat, 'tcx>> { subpatterns: &'pat [FieldPat<'tcx>],
subpatterns.iter() ) -> Vec<MatchPair<'pat, 'tcx>> {
.map(|fieldpat| { subpatterns
let place = place.clone().field(fieldpat.field, .iter()
fieldpat.pattern.ty, .map(|fieldpat| {
self.hir.tcx()); let place = self.hir.tcx().mk_place_field(
MatchPair::new(place, &fieldpat.pattern) place.clone(),
}) fieldpat.field,
.collect() fieldpat.pattern.ty,
);
MatchPair::new(place, &fieldpat.pattern)
})
.collect()
} }
pub fn prefix_slice_suffix<'pat>(&mut self, pub fn prefix_slice_suffix<'pat>(&mut self,
@ -28,6 +32,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
suffix: &'pat [Pat<'tcx>]) { suffix: &'pat [Pat<'tcx>]) {
let min_length = prefix.len() + suffix.len(); let min_length = prefix.len() + suffix.len();
let min_length = min_length.try_into().unwrap(); let min_length = min_length.try_into().unwrap();
let tcx = self.hir.tcx();
match_pairs.extend( match_pairs.extend(
prefix.iter() prefix.iter()
@ -38,16 +43,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
min_length, min_length,
from_end: false, 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) MatchPair::new(place, subpattern)
}) })
); );
if let Some(subslice_pat) = opt_slice { 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, from: prefix.len() as u32,
to: suffix.len() as u32 to: suffix.len() as u32
}, self.hir.tcx()); });
match_pairs.push(MatchPair::new(subslice, subslice_pat)); match_pairs.push(MatchPair::new(subslice, subslice_pat));
} }
@ -61,7 +66,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
min_length, min_length,
from_end: true, 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) MatchPair::new(place, subpattern)
}) })
); );

View file

@ -274,7 +274,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
// Box starts out uninitialized - need to create a separate // Box starts out uninitialized - need to create a separate
// move-path for the interior so it will be separate from // move-path for the interior so it will be separate from
// the exterior. // 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); self.gather_init(place.as_ref(), InitKind::Shallow);
} else { } else {
self.gather_init(place.as_ref(), InitKind::Deep); self.gather_init(place.as_ref(), InitKind::Deep);

View file

@ -231,7 +231,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
tcx, tcx,
param_env param_env
}; };
let dropee = dropee_ptr.deref(tcx); let dropee = tcx.mk_place_deref(dropee_ptr);
let resume_block = elaborator.patch.resume_block(); let resume_block = elaborator.patch.resume_block();
elaborate_drops::elaborate_drop( elaborate_drops::elaborate_drop(
&mut elaborator, &mut elaborator,
@ -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 is_copy = self_ty.is_copy_modulo_regions(tcx, param_env, builder.span);
let dest = Place::return_place(); 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 { match self_ty.kind {
_ if is_copy => builder.copy_shim(), _ if is_copy => builder.copy_shim(),
@ -415,7 +415,7 @@ impl CloneShimBuilder<'tcx> {
} }
fn copy_shim(&mut self) { 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( let ret_statement = self.make_statement(
StatementKind::Assign( StatementKind::Assign(
box( box(
@ -561,8 +561,8 @@ impl CloneShimBuilder<'tcx> {
// BB #2 // BB #2
// `dest[i] = Clone::clone(src[beg])`; // `dest[i] = Clone::clone(src[beg])`;
// Goto #3 if ok, #5 if unwinding happens. // Goto #3 if ok, #5 if unwinding happens.
let dest_field = dest.clone().index(beg, self.tcx); let dest_field = self.tcx.mk_place_index(dest.clone(), beg);
let src_field = src.index(beg, self.tcx); let src_field = self.tcx.mk_place_index(src, beg);
self.make_clone_call(dest_field, src_field, ty, BasicBlock::new(3), self.make_clone_call(dest_field, src_field, ty, BasicBlock::new(3),
BasicBlock::new(5)); BasicBlock::new(5));
@ -616,7 +616,7 @@ impl CloneShimBuilder<'tcx> {
// BB #7 (cleanup) // BB #7 (cleanup)
// `drop(dest[beg])`; // `drop(dest[beg])`;
self.block(vec![], TerminatorKind::Drop { self.block(vec![], TerminatorKind::Drop {
location: dest.index(beg, self.tcx), location: self.tcx.mk_place_index(dest, beg),
target: BasicBlock::new(8), target: BasicBlock::new(8),
unwind: None, unwind: None,
}, true); }, true);
@ -648,9 +648,9 @@ impl CloneShimBuilder<'tcx> {
let mut previous_field = None; let mut previous_field = None;
for (i, ity) in tys.enumerate() { for (i, ity) in tys.enumerate() {
let field = Field::new(i); 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 // #(2i + 1) is the cleanup block for the previous clone operation
let cleanup_block = self.block_index_offset(1); let cleanup_block = self.block_index_offset(1);
@ -721,14 +721,14 @@ fn build_call_shim<'tcx>(
let rcvr = match rcvr_adjustment { let rcvr = match rcvr_adjustment {
Adjustment::Identity => Operand::Move(rcvr_l), 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 => { Adjustment::DerefMove => {
// fn(Self, ...) -> fn(*mut Self, ...) // fn(Self, ...) -> fn(*mut Self, ...)
let arg_ty = local_decls[rcvr_arg].ty; let arg_ty = local_decls[rcvr_arg].ty;
debug_assert!(tcx.generics_of(def_id).has_self && arg_ty == tcx.types.self_param); 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); 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 => { Adjustment::RefMut => {
// let rcvr = &mut rcvr; // let rcvr = &mut rcvr;
@ -772,7 +772,7 @@ fn build_call_shim<'tcx>(
if let Some(untuple_args) = untuple_args { if let Some(untuple_args) = untuple_args {
args.extend(untuple_args.iter().enumerate().map(|(i, ity)| { args.extend(untuple_args.iter().enumerate().map(|(i, ity)| {
let arg_place = Place::from(Local::new(1+1)); 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 { } else {
args.extend((1..sig.inputs().len()).map(|i| { args.extend((1..sig.inputs().len()).map(|i| {

View file

@ -246,7 +246,7 @@ impl TransformVisitor<'tcx> {
// Create a Place referencing a generator struct field // Create a Place referencing a generator struct field
fn make_field(&self, variant_index: VariantIdx, idx: usize, ty: Ty<'tcx>) -> Place<'tcx> { fn make_field(&self, variant_index: VariantIdx, idx: usize, ty: Ty<'tcx>) -> Place<'tcx> {
let self_place = Place::from(self_arg()); 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(); let mut projection = base.projection.to_vec();
projection.push(ProjectionElem::Field(Field::new(idx), ty)); projection.push(ProjectionElem::Field(Field::new(idx), ty));

View file

@ -461,7 +461,7 @@ impl Inliner<'tcx> {
}; };
caller_body[callsite.bb] caller_body[callsite.bb]
.statements.push(stmt); .statements.push(stmt);
tmp.deref(self.tcx) self.tcx.mk_place_deref(tmp)
} else { } else {
destination.0 destination.0
}; };
@ -560,10 +560,10 @@ impl Inliner<'tcx> {
let tuple_tmp_args = let tuple_tmp_args =
tuple_tys.iter().enumerate().map(|(i, ty)| { tuple_tys.iter().enumerate().map(|(i, ty)| {
// This is e.g., `tuple_tmp.0` in our example above. // This is e.g., `tuple_tmp.0` in our example above.
let tuple_field = Operand::Move(tuple.clone().field( let tuple_field = Operand::Move(tcx.mk_place_field(
tuple.clone(),
Field::new(i), Field::new(i),
ty.expect_ty(), ty.expect_ty(),
tcx,
)); ));
// Spill to a local to make e.g., `tmp0`. // Spill to a local to make e.g., `tmp0`.

View file

@ -30,7 +30,7 @@ pub fn expand_aggregate<'tcx>(
}, },
source_info, source_info,
}); });
lhs = lhs.downcast(adt_def, variant_index, tcx); lhs = tcx.mk_place_downcast(lhs, adt_def, variant_index);
} }
active_field_index active_field_index
} }
@ -59,15 +59,15 @@ pub fn expand_aggregate<'tcx>(
// FIXME(eddyb) `offset` should be u64. // FIXME(eddyb) `offset` should be u64.
let offset = i as u32; let offset = i as u32;
assert_eq!(offset as usize, i); assert_eq!(offset as usize, i);
lhs.clone().elem(ProjectionElem::ConstantIndex { tcx.mk_place_elem(lhs.clone(), ProjectionElem::ConstantIndex {
offset, offset,
// FIXME(eddyb) `min_length` doesn't appear to be used. // FIXME(eddyb) `min_length` doesn't appear to be used.
min_length: offset + 1, min_length: offset + 1,
from_end: false from_end: false
}, tcx) })
} else { } else {
let field = Field::new(active_field_index.unwrap_or(i)); let field = Field::new(active_field_index.unwrap_or(i));
lhs.clone().field(field, ty, tcx) tcx.mk_place_field(lhs.clone(), field, ty)
}; };
Statement { Statement {
source_info, source_info,

View file

@ -200,13 +200,14 @@ where
variant.fields.iter().enumerate().map(|(i, f)| { variant.fields.iter().enumerate().map(|(i, f)| {
let field = Field::new(i); let field = Field::new(i);
let subpath = self.elaborator.field_subpath(variant_path, field); let subpath = self.elaborator.field_subpath(variant_path, field);
let tcx = self.tcx();
assert_eq!(self.elaborator.param_env().reveal, Reveal::All); assert_eq!(self.elaborator.param_env().reveal, Reveal::All);
let field_ty = self.tcx().normalize_erasing_regions( let field_ty = tcx.normalize_erasing_regions(
self.elaborator.param_env(), self.elaborator.param_env(),
f.ty(self.tcx(), substs), f.ty(tcx, substs),
); );
(base_place.clone().field(field, field_ty, self.tcx()), subpath) (tcx.mk_place_field(base_place.clone(), field, field_ty), subpath)
}).collect() }).collect()
} }
@ -323,7 +324,7 @@ where
debug!("open_drop_for_tuple({:?}, {:?})", self, tys); debug!("open_drop_for_tuple({:?}, {:?})", self, tys);
let fields = tys.iter().enumerate().map(|(i, &ty)| { let fields = tys.iter().enumerate().map(|(i, &ty)| {
(self.place.clone().field(Field::new(i), ty, self.tcx()), (self.tcx().mk_place_field(self.place.clone(), Field::new(i), ty),
self.elaborator.field_subpath(self.path, Field::new(i))) self.elaborator.field_subpath(self.path, Field::new(i)))
}).collect(); }).collect();
@ -334,7 +335,7 @@ where
fn open_drop_for_box(&mut self, adt: &'tcx ty::AdtDef, substs: SubstsRef<'tcx>) -> BasicBlock { fn open_drop_for_box(&mut self, adt: &'tcx ty::AdtDef, substs: SubstsRef<'tcx>) -> BasicBlock {
debug!("open_drop_for_box({:?}, {:?}, {:?})", self, adt, substs); debug!("open_drop_for_box({:?}, {:?}, {:?})", self, adt, substs);
let interior = self.place.clone().deref(self.tcx()); let interior = self.tcx().mk_place_deref(self.place.clone());
let interior_path = self.elaborator.deref_subpath(self.path); let interior_path = self.elaborator.deref_subpath(self.path);
let succ = self.succ; // FIXME(#43234) let succ = self.succ; // FIXME(#43234)
@ -406,14 +407,19 @@ where
}; };
let mut have_otherwise = false; let mut have_otherwise = false;
let tcx = self.tcx();
for (variant_index, discr) in adt.discriminants(self.tcx()) { for (variant_index, discr) in adt.discriminants(tcx) {
let subpath = self.elaborator.downcast_subpath( let subpath = self.elaborator.downcast_subpath(
self.path, variant_index); self.path, variant_index);
if let Some(variant_path) = subpath { if let Some(variant_path) = subpath {
let base_place = self.place.clone().elem( let base_place = tcx.mk_place_elem(
ProjectionElem::Downcast(Some(adt.variants[variant_index].ident.name), self.place.clone(),
variant_index), self.tcx()); ProjectionElem::Downcast(
Some(adt.variants[variant_index].ident.name),
variant_index,
),
);
let fields = self.move_paths_for_fields( let fields = self.move_paths_for_fields(
&base_place, &base_place,
variant_path, variant_path,
@ -586,7 +592,7 @@ where
BorrowKind::Mut { allow_two_phase_borrow: false }, BorrowKind::Mut { allow_two_phase_borrow: false },
Place { Place {
base: PlaceBase::Local(cur), base: PlaceBase::Local(cur),
projection: self.tcx().intern_place_elems(&vec![ProjectionElem::Deref]), projection: tcx.intern_place_elems(&vec![ProjectionElem::Deref]),
} }
), ),
Rvalue::BinaryOp(BinOp::Offset, move_(&Place::from(cur)), one)) Rvalue::BinaryOp(BinOp::Offset, move_(&Place::from(cur)), one))
@ -594,7 +600,7 @@ where
(Rvalue::Ref( (Rvalue::Ref(
tcx.lifetimes.re_erased, tcx.lifetimes.re_erased,
BorrowKind::Mut { allow_two_phase_borrow: false }, BorrowKind::Mut { allow_two_phase_borrow: false },
self.place.clone().index(cur, self.tcx())), tcx.mk_place_index(self.place.clone(), cur)),
Rvalue::BinaryOp(BinOp::Add, move_(&Place::from(cur)), one)) Rvalue::BinaryOp(BinOp::Add, move_(&Place::from(cur)), one))
}; };
@ -627,7 +633,7 @@ where
let loop_block = self.elaborator.patch().new_block(loop_block); let loop_block = self.elaborator.patch().new_block(loop_block);
self.elaborator.patch().patch_terminator(drop_block, TerminatorKind::Drop { self.elaborator.patch().patch_terminator(drop_block, TerminatorKind::Drop {
location: ptr.clone().deref(tcx), location: tcx.mk_place_deref(ptr.clone()),
target: loop_block, target: loop_block,
unwind: unwind.into_option() unwind: unwind.into_option()
}); });
@ -644,18 +650,27 @@ where
// ptr_based_loop // ptr_based_loop
// } // }
let tcx = self.tcx();
if let Some(size) = opt_size { if let Some(size) = opt_size {
let size: u32 = size.try_into().unwrap_or_else(|_| { let size: u32 = size.try_into().unwrap_or_else(|_| {
bug!("move out check isn't implemented for array sizes bigger than u32::MAX"); bug!("move out check isn't implemented for array sizes bigger than u32::MAX");
}); });
let fields: Vec<(Place<'tcx>, Option<D::Path>)> = (0..size).map(|i| { let fields: Vec<(Place<'tcx>, Option<D::Path>)> = (0..size)
(self.place.clone().elem(ProjectionElem::ConstantIndex{ .map(|i| {
offset: i, (
min_length: size, tcx.mk_place_elem(
from_end: false self.place.clone(),
}, self.tcx()), ProjectionElem::ConstantIndex {
self.elaborator.array_subpath(self.path, i, size)) offset: i,
}).collect(); min_length: size,
from_end: false,
},
),
self.elaborator.array_subpath(self.path, i, size),
)
})
.collect();
if fields.iter().any(|(_,path)| path.is_some()) { if fields.iter().any(|(_,path)| path.is_some()) {
let (succ, unwind) = self.drop_ladder_bottom(); let (succ, unwind) = self.drop_ladder_bottom();
@ -664,7 +679,6 @@ where
} }
let move_ = |place: &Place<'tcx>| Operand::Move(place.clone()); let move_ = |place: &Place<'tcx>| Operand::Move(place.clone());
let tcx = self.tcx();
let elem_size = &Place::from(self.new_temp(tcx.types.usize)); let elem_size = &Place::from(self.new_temp(tcx.types.usize));
let len = &Place::from(self.new_temp(tcx.types.usize)); let len = &Place::from(self.new_temp(tcx.types.usize));
@ -900,8 +914,8 @@ where
); );
let args = adt.variants[VariantIdx::new(0)].fields.iter().enumerate().map(|(i, f)| { let args = adt.variants[VariantIdx::new(0)].fields.iter().enumerate().map(|(i, f)| {
let field = Field::new(i); let field = Field::new(i);
let field_ty = f.ty(self.tcx(), substs); let field_ty = f.ty(tcx, substs);
Operand::Move(self.place.clone().field(field, field_ty, self.tcx())) Operand::Move(tcx.mk_place_field(self.place.clone(), field, field_ty))
}).collect(); }).collect();
let call = TerminatorKind::Call { let call = TerminatorKind::Call {