diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 6e509f5175417..7db5dac3882d2 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -15,8 +15,7 @@ use crate::ty::layout::VariantIdx; use crate::ty::print::{FmtPrinter, Printer}; use crate::ty::subst::{Subst, SubstsRef}; use crate::ty::{ - self, AdtDef, CanonicalUserTypeAnnotations, Region, Ty, TyCtxt, - UserTypeAnnotationIndex, + self, AdtDef, CanonicalUserTypeAnnotations, List, Region, Ty, TyCtxt, UserTypeAnnotationIndex, }; use polonius_engine::Atom; @@ -1712,15 +1711,17 @@ impl Debug for Statement<'_> { /// A path to a value; something that can be evaluated without /// changing or disturbing program state. #[derive( - Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable, + Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, HashStable, )] pub struct Place<'tcx> { pub base: PlaceBase<'tcx>, /// projection out of a place (access a field, deref a pointer, etc) - pub projection: Box<[PlaceElem<'tcx>]>, + pub projection: &'tcx List>, } +impl<'tcx> rustc_serialize::UseSpecializedDecodable for Place<'tcx> {} + #[derive( Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable, )] @@ -1848,50 +1849,56 @@ pub struct PlaceRef<'a, 'tcx> { } impl<'tcx> Place<'tcx> { - // FIXME change this back to a const when projection is a shared slice. - // - // pub const RETURN_PLACE: Place<'tcx> = Place { - // base: PlaceBase::Local(RETURN_PLACE), - // projection: &[], - // }; + // FIXME change this to a const fn by also making List::empty a const fn. pub fn return_place() -> Place<'tcx> { Place { base: PlaceBase::Local(RETURN_PLACE), - projection: Box::new([]), + projection: List::empty(), } } - pub fn field(self, f: Field, ty: Ty<'tcx>) -> Place<'tcx> { - self.elem(ProjectionElem::Field(f, ty)) + 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) -> Place<'tcx> { - self.elem(ProjectionElem::Deref) + 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) -> Place<'tcx> { - self.elem(ProjectionElem::Downcast( - Some(adt_def.variants[variant_index].ident.name), - variant_index, - )) + 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) -> Place<'tcx> { - self.elem(ProjectionElem::Downcast(None, variant_index)) + 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) -> Place<'tcx> { - self.elem(ProjectionElem::Index(index)) + pub fn index(self, index: Local, tcx: TyCtxt<'tcx>) -> Place<'tcx> { + self.elem(ProjectionElem::Index(index), tcx) } - pub fn elem(self, elem: PlaceElem<'tcx>) -> Place<'tcx> { - // FIXME(spastorino): revisit this again once projection is not a Box<[T]> anymore - let mut projection = self.projection.into_vec(); + /// 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: projection.into_boxed_slice(), + projection: tcx.intern_place_elems(&projection), } } @@ -1939,7 +1946,7 @@ impl From for Place<'_> { fn from(local: Local) -> Self { Place { base: local.into(), - projection: Box::new([]), + projection: List::empty(), } } } @@ -3190,6 +3197,17 @@ impl<'tcx> TypeFoldable<'tcx> for PlaceBase<'tcx> { } } +impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { + fn super_fold_with>(&self, folder: &mut F) -> Self { + let v = self.iter().map(|t| t.fold_with(folder)).collect::>(); + folder.tcx().intern_place_elems(&v) + } + + fn super_visit_with>(&self, visitor: &mut V) -> bool { + self.iter().any(|t| t.visit_with(visitor)) + } +} + impl<'tcx> TypeFoldable<'tcx> for Static<'tcx> { fn super_fold_with>(&self, folder: &mut F) -> Self { Static { diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index fef406e898783..e5cf555b3fa8e 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -784,6 +784,8 @@ macro_rules! make_mir_visitor { macro_rules! visit_place_fns { (mut) => ( + fn tcx<'a>(&'a self) -> TyCtxt<'tcx>; + fn super_place( &mut self, place: &mut Place<'tcx>, @@ -793,19 +795,21 @@ macro_rules! visit_place_fns { self.visit_place_base(&mut place.base, context, location); if let Some(new_projection) = self.process_projection(&place.projection) { - place.projection = new_projection; + place.projection = self.tcx().intern_place_elems(&new_projection); } } fn process_projection( &mut self, projection: &'a [PlaceElem<'tcx>], - ) -> Option]>> { + ) -> Option>> { 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) { + // This converts the borrowed projection into `Cow::Owned(_)` and returns a + // clone of the projection so we can mutate and reintern later. let vec = projection.to_mut(); vec[i] = elem; } @@ -814,7 +818,7 @@ macro_rules! visit_place_fns { match projection { Cow::Borrowed(_) => None, - Cow::Owned(vec) => Some(vec.into_boxed_slice()), + Cow::Owned(vec) => Some(vec), } } diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs index 03cb4775bd83f..d5e7ac19263a0 100644 --- a/src/librustc/ty/codec.rs +++ b/src/librustc/ty/codec.rs @@ -13,9 +13,9 @@ use rustc_data_structures::fx::FxHashMap; use rustc_serialize::{Decodable, Decoder, Encoder, Encodable, opaque}; use std::hash::Hash; use std::intrinsics; -use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{self, List, Ty, TyCtxt}; use crate::ty::subst::SubstsRef; -use crate::mir::interpret::Allocation; +use crate::mir::{self, interpret::Allocation}; use syntax_pos::Span; /// The shorthand encoding uses an enum's variant index `usize` @@ -218,6 +218,18 @@ where Ok(tcx.mk_substs((0..len).map(|_| Decodable::decode(decoder)))?) } +#[inline] +pub fn decode_place(decoder: &mut D) -> Result, D::Error> +where + D: TyDecoder<'tcx>, +{ + let base: mir::PlaceBase<'tcx> = Decodable::decode(decoder)?; + let len = decoder.read_usize()?; + let projection: &'tcx List> = + decoder.tcx().mk_place_elems((0..len).map(|_| Decodable::decode(decoder)))?; + Ok(mir::Place { base, projection }) +} + #[inline] pub fn decode_region(decoder: &mut D) -> Result, D::Error> where @@ -413,6 +425,15 @@ macro_rules! implement_ty_decoder { } } + impl<$($typaram),*> SpecializedDecoder<$crate::mir::Place<'tcx>> + for $DecoderName<$($typaram),*> { + fn specialized_decode( + &mut self + ) -> Result<$crate::mir::Place<'tcx>, Self::Error> { + decode_place(self) + } + } + impl<$($typaram),*> SpecializedDecoder> for $DecoderName<$($typaram),*> { fn specialized_decode(&mut self) -> Result, Self::Error> { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index da86335345c1d..3269591c7455b 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2711,6 +2711,11 @@ impl<'tcx> TyCtxt<'tcx> { iter.intern_with(|xs| self.intern_substs(xs)) } + pub fn mk_place_elems], + &'tcx List>>>(self, iter: I) -> I::Output { + iter.intern_with(|xs| self.intern_place_elems(xs)) + } + pub fn mk_substs_trait(self, self_ty: Ty<'tcx>, rest: &[GenericArg<'tcx>]) diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs index 9b7a5caa6d913..36db68a3372eb 100644 --- a/src/librustc_mir/borrow_check/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/conflict_errors.rs @@ -707,10 +707,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { _ => drop_span, }; + let root_place_projection = self.infcx.tcx.intern_place_elems(root_place.projection); + if self.access_place_error_reported .contains(&(Place { base: root_place.base.clone(), - projection: root_place.projection.to_vec().into_boxed_slice(), + projection: root_place_projection, }, borrow_span)) { debug!( @@ -723,7 +725,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.access_place_error_reported .insert((Place { base: root_place.base.clone(), - projection: root_place.projection.to_vec().into_boxed_slice(), + projection: root_place_projection, }, borrow_span)); if let StorageDeadOrDrop::Destructor(dropped_ty) = diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs index 9ecd6f837750e..d949c7e01aab7 100644 --- a/src/librustc_mir/borrow_check/nll/renumber.rs +++ b/src/librustc_mir/borrow_check/nll/renumber.rs @@ -1,5 +1,5 @@ use rustc::ty::subst::SubstsRef; -use rustc::ty::{self, Ty, TypeFoldable}; +use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::mir::{Body, Location, PlaceElem, Promoted}; use rustc::mir::visit::{MutVisitor, TyContext}; use rustc::infer::{InferCtxt, NLLRegionVariableOrigin}; @@ -54,6 +54,10 @@ impl<'a, 'tcx> NLLVisitor<'a, 'tcx> { } impl<'a, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.infcx.tcx + } + fn visit_ty(&mut self, ty: &mut Ty<'tcx>, ty_context: TyContext) { debug!("visit_ty(ty={:?}, ty_context={:?})", ty, ty_context); diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 60fe37e26e9ad..8d2bef39bed42 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -6,7 +6,7 @@ use crate::build::{BlockAnd, BlockAndExtension, Builder}; use crate::hair::*; use rustc::mir::interpret::{PanicInfo::BoundsCheck}; use rustc::mir::*; -use rustc::ty::{CanonicalUserTypeAnnotation, Ty, Variance}; +use rustc::ty::{CanonicalUserTypeAnnotation, Ty, TyCtxt, Variance}; use rustc_index::vec::Idx; @@ -23,10 +23,10 @@ struct PlaceBuilder<'tcx> { } impl PlaceBuilder<'tcx> { - fn into_place(self) -> Place<'tcx> { + fn into_place(self, tcx: TyCtxt<'tcx>) -> Place<'tcx> { Place { base: self.base, - projection: self.projection.into_boxed_slice(), + projection: tcx.intern_place_elems(&self.projection), } } @@ -73,7 +73,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { M: Mirror<'tcx, Output = Expr<'tcx>>, { let place_builder = unpack!(block = self.as_place_builder(block, expr)); - block.and(place_builder.into_place()) + block.and(place_builder.into_place(self.hir.tcx())) } /// This is used when constructing a compound `Place`, so that we can avoid creating @@ -96,7 +96,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { M: Mirror<'tcx, Output = Expr<'tcx>>, { let place_builder = unpack!(block = self.as_read_only_place_builder(block, expr)); - block.and(place_builder.into_place()) + block.and(place_builder.into_place(self.hir.tcx())) } /// This is used when constructing a compound `Place`, so that we can avoid creating @@ -165,7 +165,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Mutability::Not, )); - let slice = place_builder.clone().into_place(); + let slice = place_builder.clone().into_place(this.hir.tcx()); // bounds check: let (len, lt) = ( this.temp(usize_ty.clone(), expr_span), @@ -225,7 +225,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } ); - let place = place_builder.clone().into_place(); + let place = place_builder.clone().into_place(this.hir.tcx()); this.cfg.push( block, Statement { diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 43ee6557634fb..916e919e399eb 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -139,7 +139,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // initialize the box contents: unpack!( block = this.into( - &Place::from(result).deref(), + &Place::from(result).deref(this.hir.tcx()), block, value ) ); @@ -296,8 +296,13 @@ 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(n, ty)), - }).collect() + None => this.consume_by_copy_or_move(base.clone().field( + n, + ty, + this.hir.tcx(), + )), + }) + .collect() } else { field_names .iter() @@ -397,8 +402,8 @@ 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); - let of = result_value.field(of_fld, bool_ty); + 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 err = PanicInfo::Overflow(op); diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 8a6bc5a2a764e..634b9c61ec691 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -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(), block, val) + this.into(&ptr_temp.deref(this.hir.tcx()), block, val) } else { let args: Vec<_> = args .into_iter() diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index b86bb21f6e390..667b37bbd80c8 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -948,7 +948,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fake_borrows.insert(Place { base: source.base.clone(), - projection: proj_base.to_vec().into_boxed_slice(), + projection: self.hir.tcx().intern_place_elems(proj_base), }); } } @@ -1488,7 +1488,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { BorrowKind::Shallow, Place { base: place.base.clone(), - projection: place.projection.to_vec().into_boxed_slice(), + projection: tcx.intern_place_elems(place.projection), }, ); self.cfg.push_assign( diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index 3826e5e3ba5e6..df97ad8574812 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -166,7 +166,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } }); if irrefutable { - let place = match_pair.place.downcast(adt_def, variant_index); + let place = match_pair.place.downcast(adt_def, variant_index, tcx); candidate.match_pairs.extend(self.field_match_pairs(place, subpatterns)); Ok(()) } else { @@ -191,7 +191,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } PatKind::Deref { ref subpattern } => { - let place = match_pair.place.deref(); + let place = match_pair.place.deref(tcx); candidate.match_pairs.push(MatchPair::new(place, subpattern)); Ok(()) } diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index a04c989e6e0de..125d9e5eeb539 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -749,13 +749,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // `(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); // `(x as Variant)` + 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); + subpattern.pattern.ty, + self.hir.tcx()); // e.g., `(x as Variant).0 @ P1` MatchPair::new(place, &subpattern.pattern) }); diff --git a/src/librustc_mir/build/matches/util.rs b/src/librustc_mir/build/matches/util.rs index 83fb924af6381..c993dafe00e7c 100644 --- a/src/librustc_mir/build/matches/util.rs +++ b/src/librustc_mir/build/matches/util.rs @@ -13,7 +13,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { subpatterns.iter() .map(|fieldpat| { let place = place.clone().field(fieldpat.field, - fieldpat.pattern.ty); + fieldpat.pattern.ty, + self.hir.tcx()); MatchPair::new(place, &fieldpat.pattern) }) .collect() @@ -37,7 +38,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { min_length, from_end: false, }; - let place = place.clone().elem(elem); + let place = place.clone().elem(elem, self.hir.tcx()); MatchPair::new(place, subpattern) }) ); @@ -46,7 +47,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let subslice = place.clone().elem(ProjectionElem::Subslice { from: prefix.len() as u32, to: suffix.len() as u32 - }); + }, self.hir.tcx()); match_pairs.push(MatchPair::new(subslice, subslice_pat)); } @@ -60,7 +61,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { min_length, from_end: true, }; - let place = place.clone().elem(elem); + let place = place.clone().elem(elem, self.hir.tcx()); MatchPair::new(place, subpattern) }) ); diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index 53b18e4364b95..55da1e61f3c9d 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -114,7 +114,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { BorrowedContent { target_place: Place { base: place.base.clone(), - projection: proj.to_vec().into_boxed_slice(), + projection: tcx.intern_place_elems(proj), }, }, )); @@ -172,7 +172,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { Some(base), Place { base: place.base.clone(), - projection: proj.to_vec().into_boxed_slice(), + projection: tcx.intern_place_elems(proj), }, ); ent.insert(path); @@ -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.create_move_path(&place.clone().deref(self.builder.tcx)); self.gather_init(place.as_ref(), InitKind::Shallow); } else { self.gather_init(place.as_ref(), InitKind::Deep); diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index f532a18072fbd..09c0b1ab7b965 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -117,7 +117,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx run_passes(tcx, &mut result, instance, None, MirPhase::Const, &[ &add_moves_for_packed_drops::AddMovesForPackedDrops, - &no_landing_pads::NoLandingPads, + &no_landing_pads::NoLandingPads::new(tcx), &remove_noop_landing_pads::RemoveNoopLandingPads, &simplify::SimplifyCfg::new("make_shim"), &add_call_guards::CriticalCallEdges, @@ -231,7 +231,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) tcx, param_env }; - let dropee = dropee_ptr.deref(); + let dropee = dropee_ptr.deref(tcx); let resume_block = elaborator.patch.resume_block(); elaborate_drops::elaborate_drop( &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 dest = Place::return_place(); - let src = Place::from(Local::new(1+0)).deref(); + let src = Place::from(Local::new(1+0)).deref(tcx); match self_ty.kind { _ if is_copy => builder.copy_shim(), @@ -415,7 +415,7 @@ impl CloneShimBuilder<'tcx> { } fn copy_shim(&mut self) { - let rcvr = Place::from(Local::new(1+0)).deref(); + let rcvr = Place::from(Local::new(1+0)).deref(self.tcx); let ret_statement = self.make_statement( StatementKind::Assign( box( @@ -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); - let src_field = src.index(beg); + let dest_field = dest.clone().index(beg, self.tcx); + let src_field = src.index(beg, self.tcx); self.make_clone_call(dest_field, src_field, ty, BasicBlock::new(3), BasicBlock::new(5)); @@ -616,7 +616,7 @@ impl CloneShimBuilder<'tcx> { // BB #7 (cleanup) // `drop(dest[beg])`; self.block(vec![], TerminatorKind::Drop { - location: dest.index(beg), + location: dest.index(beg, self.tcx), target: BasicBlock::new(8), unwind: None, }, true); @@ -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); + let src_field = src.clone().field(field, ity, self.tcx); - let dest_field = dest.clone().field(field, ity); + let dest_field = dest.clone().field(field, ity, self.tcx); // #(2i + 1) is the cleanup block for the previous clone operation let cleanup_block = self.block_index_offset(1); @@ -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()), + Adjustment::Deref => Operand::Copy(rcvr_l.deref(tcx)), 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()) + Operand::Move(rcvr_l.deref(tcx)) } Adjustment::RefMut => { // let rcvr = &mut rcvr; @@ -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)) + Operand::Move(arg_place.field(Field::new(i), *ity, tcx)) })); } else { args.extend((1..sig.inputs().len()).map(|i| { @@ -901,6 +901,7 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &Body<'_> { )), AggregateKind::Adt(adt_def, variant_index, substs, None, None), source_info, + tcx, ).collect(); let start_block = BasicBlockData { diff --git a/src/librustc_mir/transform/cleanup_post_borrowck.rs b/src/librustc_mir/transform/cleanup_post_borrowck.rs index ea173279aa073..4fd4fe45cd4f1 100644 --- a/src/librustc_mir/transform/cleanup_post_borrowck.rs +++ b/src/librustc_mir/transform/cleanup_post_borrowck.rs @@ -24,16 +24,22 @@ use crate::transform::{MirPass, MirSource}; pub struct CleanupNonCodegenStatements; -pub struct DeleteNonCodegenStatements; +pub struct DeleteNonCodegenStatements<'tcx> { + tcx: TyCtxt<'tcx>, +} impl<'tcx> MirPass<'tcx> for CleanupNonCodegenStatements { - fn run_pass(&self, _tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body: &mut Body<'tcx>) { - let mut delete = DeleteNonCodegenStatements; + fn run_pass(&self, tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body: &mut Body<'tcx>) { + let mut delete = DeleteNonCodegenStatements { tcx }; delete.visit_body(body); } } -impl<'tcx> MutVisitor<'tcx> for DeleteNonCodegenStatements { +impl<'tcx> MutVisitor<'tcx> for DeleteNonCodegenStatements<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) { diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index dc6cb9650f05e..13097a2156167 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -687,6 +687,10 @@ impl<'tcx> Visitor<'tcx> for CanConstProp { } impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_constant( &mut self, constant: &mut Constant<'tcx>, diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs index c20726eceba9a..4c26feac4af79 100644 --- a/src/librustc_mir/transform/copy_prop.rs +++ b/src/librustc_mir/transform/copy_prop.rs @@ -126,7 +126,8 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation { } } - changed = action.perform(body, &def_use_analysis, dest_local, location) || changed; + changed = + action.perform(body, &def_use_analysis, dest_local, location, tcx) || changed; // FIXME(pcwalton): Update the use-def chains to delete the instructions instead of // regenerating the chains. break @@ -244,7 +245,8 @@ impl<'tcx> Action<'tcx> { body: &mut Body<'tcx>, def_use_analysis: &DefUseAnalysis, dest_local: Local, - location: Location) + location: Location, + tcx: TyCtxt<'tcx>) -> bool { match self { Action::PropagateLocalCopy(src_local) => { @@ -268,7 +270,7 @@ impl<'tcx> Action<'tcx> { } // Replace all uses of the destination local with the source local. - def_use_analysis.replace_all_defs_and_uses_with(dest_local, body, src_local); + def_use_analysis.replace_all_defs_and_uses_with(dest_local, body, src_local, tcx); // Finally, zap the now-useless assignment instruction. debug!(" Deleting assignment"); @@ -292,7 +294,8 @@ impl<'tcx> Action<'tcx> { // Replace all uses of the destination local with the constant. let mut visitor = ConstantPropagationVisitor::new(dest_local, - src_constant); + src_constant, + tcx); for dest_place_use in &dest_local_info.defs_and_uses { visitor.visit_location(body, dest_place_use.location) } @@ -324,21 +327,27 @@ impl<'tcx> Action<'tcx> { struct ConstantPropagationVisitor<'tcx> { dest_local: Local, constant: Constant<'tcx>, + tcx: TyCtxt<'tcx>, uses_replaced: usize, } impl<'tcx> ConstantPropagationVisitor<'tcx> { - fn new(dest_local: Local, constant: Constant<'tcx>) + fn new(dest_local: Local, constant: Constant<'tcx>, tcx: TyCtxt<'tcx>) -> ConstantPropagationVisitor<'tcx> { ConstantPropagationVisitor { dest_local, constant, + tcx, uses_replaced: 0, } } } impl<'tcx> MutVisitor<'tcx> for ConstantPropagationVisitor<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) { self.super_operand(operand, location); diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs index c1224be6324e2..cdde9e12edcbb 100644 --- a/src/librustc_mir/transform/deaggregator.rs +++ b/src/librustc_mir/transform/deaggregator.rs @@ -45,6 +45,7 @@ impl<'tcx> MirPass<'tcx> for Deaggregator { }), *kind, source_info, + tcx, )) }); } diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs index 439cae2093ae5..b30e2de4ca0bc 100644 --- a/src/librustc_mir/transform/erase_regions.rs +++ b/src/librustc_mir/transform/erase_regions.rs @@ -23,6 +23,10 @@ impl EraseRegionsVisitor<'tcx> { } impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) { *ty = self.tcx.erase_regions(ty); } diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index d0cb1b8297a59..51e4d34fb1174 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -74,12 +74,17 @@ use crate::util::liveness; pub struct StateTransform; -struct RenameLocalVisitor { +struct RenameLocalVisitor<'tcx> { from: Local, to: Local, + tcx: TyCtxt<'tcx>, } -impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor { +impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_local(&mut self, local: &mut Local, _: PlaceContext, @@ -102,9 +107,15 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor { } } -struct DerefArgVisitor; +struct DerefArgVisitor<'tcx> { + tcx: TyCtxt<'tcx>, +} + +impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } -impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor { fn visit_local(&mut self, local: &mut Local, _: PlaceContext, @@ -119,8 +130,8 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor { if place.base == PlaceBase::Local(self_arg()) { replace_base(place, Place { base: PlaceBase::Local(self_arg()), - projection: Box::new([ProjectionElem::Deref]), - }); + projection: self.tcx().intern_place_elems(&vec![ProjectionElem::Deref]), + }, self.tcx); } else { self.visit_place_base(&mut place.base, context, location); @@ -135,9 +146,14 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor { struct PinArgVisitor<'tcx> { ref_gen_ty: Ty<'tcx>, + tcx: TyCtxt<'tcx>, } impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_local(&mut self, local: &mut Local, _: PlaceContext, @@ -145,15 +161,19 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> { assert_ne!(*local, self_arg()); } - fn visit_place(&mut self, - place: &mut Place<'tcx>, - context: PlaceContext, - location: Location) { + fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) { if place.base == PlaceBase::Local(self_arg()) { - replace_base(place, Place { - base: PlaceBase::Local(self_arg()), - projection: Box::new([ProjectionElem::Field(Field::new(0), self.ref_gen_ty)]), - }); + replace_base( + place, + Place { + base: PlaceBase::Local(self_arg()), + projection: self.tcx().intern_place_elems(&vec![ProjectionElem::Field( + Field::new(0), + self.ref_gen_ty, + )]), + }, + self.tcx, + ); } else { self.visit_place_base(&mut place.base, context, location); @@ -166,13 +186,13 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> { } } -fn replace_base(place: &mut Place<'tcx>, new_base: Place<'tcx>) { +fn replace_base<'tcx>(place: &mut Place<'tcx>, new_base: Place<'tcx>, tcx: TyCtxt<'tcx>) { place.base = new_base.base; let mut new_projection = new_base.projection.to_vec(); new_projection.append(&mut place.projection.to_vec()); - place.projection = new_projection.into_boxed_slice(); + place.projection = tcx.intern_place_elems(&new_projection); } fn self_arg() -> Local { @@ -226,13 +246,13 @@ 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); + let base = self_place.downcast_unnamed(variant_index, self.tcx); let mut projection = base.projection.to_vec(); projection.push(ProjectionElem::Field(Field::new(idx), ty)); Place { base: base.base, - projection: projection.into_boxed_slice(), + projection: self.tcx.intern_place_elems(&projection), } } @@ -264,6 +284,10 @@ impl TransformVisitor<'tcx> { } impl MutVisitor<'tcx> for TransformVisitor<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_local(&mut self, local: &mut Local, _: PlaceContext, @@ -280,7 +304,7 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> { if let PlaceBase::Local(l) = place.base { // Replace an Local in the remap with a generator struct access if let Some(&(ty, variant_index, idx)) = self.remap.get(&l) { - replace_base(place, self.make_field(variant_index, idx, ty)); + replace_base(place, self.make_field(variant_index, idx, ty), self.tcx); } } else { self.visit_place_base(&mut place.base, context, location); @@ -375,7 +399,7 @@ fn make_generator_state_argument_indirect<'tcx>( body.local_decls.raw[1].ty = ref_gen_ty; // Add a deref to accesses of the generator state - DerefArgVisitor.visit_body(body); + DerefArgVisitor { tcx }.visit_body(body); } fn make_generator_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { @@ -390,12 +414,13 @@ fn make_generator_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body body.local_decls.raw[1].ty = pin_ref_gen_ty; // Add the Pin field access to accesses of the generator state - PinArgVisitor { ref_gen_ty }.visit_body(body); + PinArgVisitor { ref_gen_ty, tcx }.visit_body(body); } fn replace_result_variable<'tcx>( ret_ty: Ty<'tcx>, body: &mut Body<'tcx>, + tcx: TyCtxt<'tcx>, ) -> Local { let source_info = source_info(body); let new_ret = LocalDecl { @@ -416,6 +441,7 @@ fn replace_result_variable<'tcx>( RenameLocalVisitor { from: RETURN_PLACE, to: new_ret_local, + tcx, }.visit_body(body); new_ret_local @@ -1182,7 +1208,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform { // We rename RETURN_PLACE which has type mir.return_ty to new_ret_local // RETURN_PLACE then is a fresh unused local with type ret_ty. - let new_ret_local = replace_result_variable(ret_ty, body); + let new_ret_local = replace_result_variable(ret_ty, body, tcx); // Extract locals which are live across suspension point into `layout` // `remap` gives a mapping from local indices onto generator struct indices diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 353d89cf08663..c92025812f946 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -461,7 +461,7 @@ impl Inliner<'tcx> { }; caller_body[callsite.bb] .statements.push(stmt); - tmp.deref() + tmp.deref(self.tcx) } else { destination.0 }; @@ -481,6 +481,7 @@ impl Inliner<'tcx> { return_block, cleanup_block: cleanup, in_cleanup_block: false, + tcx: self.tcx, }; @@ -562,6 +563,7 @@ impl Inliner<'tcx> { let tuple_field = Operand::Move(tuple.clone().field( Field::new(i), ty.expect_ty(), + tcx, )); // Spill to a local to make e.g., `tmp0`. @@ -638,6 +640,7 @@ struct Integrator<'a, 'tcx> { return_block: BasicBlock, cleanup_block: Option, in_cleanup_block: bool, + tcx: TyCtxt<'tcx>, } impl<'a, 'tcx> Integrator<'a, 'tcx> { @@ -665,6 +668,10 @@ impl<'a, 'tcx> Integrator<'a, 'tcx> { } impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_local( &mut self, local: &mut Local, diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs index 08668716fee11..a567ed668bfa5 100644 --- a/src/librustc_mir/transform/instcombine.rs +++ b/src/librustc_mir/transform/instcombine.rs @@ -29,29 +29,32 @@ impl<'tcx> MirPass<'tcx> for InstCombine { }; // Then carry out those optimizations. - MutVisitor::visit_body(&mut InstCombineVisitor { optimizations }, body); + MutVisitor::visit_body(&mut InstCombineVisitor { optimizations, tcx }, body); } } pub struct InstCombineVisitor<'tcx> { optimizations: OptimizationList<'tcx>, + tcx: TyCtxt<'tcx>, } impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) { if self.optimizations.and_stars.remove(&location) { debug!("replacing `&*`: {:?}", rvalue); let new_place = match rvalue { Rvalue::Ref(_, _, place) => { if let &[ref proj_l @ .., proj_r] = place.projection.as_ref() { - let new_projection = proj_l.to_vec().into_boxed_slice(); - - place.projection = vec![proj_r.clone()].into_boxed_slice(); + place.projection = self.tcx().intern_place_elems(&vec![proj_r.clone()]); Place { // Replace with dummy base: mem::replace(&mut place.base, PlaceBase::Local(Local::new(0))), - projection: new_projection, + projection: self.tcx().intern_place_elems(proj_l), } } else { unreachable!(); diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 7e06729c2c742..dbe6c7845926d 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -228,7 +228,7 @@ fn run_optimization_passes<'tcx>( ) { run_passes(tcx, body, InstanceDef::Item(def_id), promoted, MirPhase::Optimized, &[ // Remove all things only needed by analysis - &no_landing_pads::NoLandingPads, + &no_landing_pads::NoLandingPads::new(tcx), &simplify_branches::SimplifyBranches::new("initial"), &remove_noop_landing_pads::RemoveNoopLandingPads, &cleanup_post_borrowck::CleanupNonCodegenStatements, @@ -238,7 +238,7 @@ fn run_optimization_passes<'tcx>( // These next passes must be executed together &add_call_guards::CriticalCallEdges, &elaborate_drops::ElaborateDrops, - &no_landing_pads::NoLandingPads, + &no_landing_pads::NoLandingPads::new(tcx), // AddMovesForPackedDrops needs to run after drop // elaboration. &add_moves_for_packed_drops::AddMovesForPackedDrops, @@ -257,7 +257,7 @@ fn run_optimization_passes<'tcx>( // Optimizations begin. - &uniform_array_move_out::RestoreSubsliceArrayMoveOut, + &uniform_array_move_out::RestoreSubsliceArrayMoveOut::new(tcx), &inline::Inline, // Lowering generator control-flow and variables diff --git a/src/librustc_mir/transform/no_landing_pads.rs b/src/librustc_mir/transform/no_landing_pads.rs index 762bb5d44839f..fbd14d9ef6170 100644 --- a/src/librustc_mir/transform/no_landing_pads.rs +++ b/src/librustc_mir/transform/no_landing_pads.rs @@ -6,9 +6,17 @@ use rustc::mir::*; use rustc::mir::visit::MutVisitor; use crate::transform::{MirPass, MirSource}; -pub struct NoLandingPads; +pub struct NoLandingPads<'tcx> { + tcx: TyCtxt<'tcx>, +} + +impl<'tcx> NoLandingPads<'tcx> { + pub fn new(tcx: TyCtxt<'tcx>) -> Self { + NoLandingPads { tcx } + } +} -impl<'tcx> MirPass<'tcx> for NoLandingPads { +impl<'tcx> MirPass<'tcx> for NoLandingPads<'tcx> { fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) { no_landing_pads(tcx, body) } @@ -16,11 +24,15 @@ impl<'tcx> MirPass<'tcx> for NoLandingPads { pub fn no_landing_pads<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { if tcx.sess.no_landing_pads() { - NoLandingPads.visit_body(body); + NoLandingPads::new(tcx).visit_body(body); } } -impl<'tcx> MutVisitor<'tcx> for NoLandingPads { +impl<'tcx> MutVisitor<'tcx> for NoLandingPads<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_terminator_kind(&mut self, kind: &mut TerminatorKind<'tcx>, location: Location) { diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index f13d49e3f54fe..7a9c489fa791e 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -17,7 +17,7 @@ use rustc::mir::*; use rustc::mir::visit::{PlaceContext, MutatingUseContext, MutVisitor, Visitor}; use rustc::mir::traversal::ReversePostorder; use rustc::ty::subst::InternalSubsts; -use rustc::ty::TyCtxt; +use rustc::ty::{List, TyCtxt}; use syntax_pos::Span; use rustc_index::vec::{IndexVec, Idx}; @@ -321,7 +321,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { ty, def_id, }), - projection: box [], + projection: List::empty(), } }; let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut(); @@ -339,7 +339,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { &mut place.base, promoted_place(ty, span).base, ), - projection: box [], + projection: List::empty(), }) } _ => bug!() @@ -396,6 +396,10 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { /// Replaces all temporaries with their promoted counterparts. impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_local(&mut self, local: &mut Local, _: PlaceContext, diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index e41b4678dbd0d..1b90ea78c6450 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -319,7 +319,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyLocals { let map = make_local_map(&mut body.local_decls, locals); // Update references to all vars and tmps now - LocalUpdater { map }.visit_body(body); + LocalUpdater { map, tcx }.visit_body(body); body.local_decls.shrink_to_fit(); } } @@ -374,11 +374,16 @@ impl<'a, 'tcx> Visitor<'tcx> for DeclMarker<'a, 'tcx> { } } -struct LocalUpdater { +struct LocalUpdater<'tcx> { map: IndexVec>, + tcx: TyCtxt<'tcx>, } -impl<'tcx> MutVisitor<'tcx> for LocalUpdater { +impl<'tcx> MutVisitor<'tcx> for LocalUpdater<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_basic_block_data(&mut self, block: BasicBlock, data: &mut BasicBlockData<'tcx>) { // Remove unnecessary StorageLive and StorageDead annotations. data.statements.retain(|stmt| { diff --git a/src/librustc_mir/transform/uniform_array_move_out.rs b/src/librustc_mir/transform/uniform_array_move_out.rs index 07a7def3ea256..e4c2f7d389b50 100644 --- a/src/librustc_mir/transform/uniform_array_move_out.rs +++ b/src/librustc_mir/transform/uniform_array_move_out.rs @@ -116,16 +116,13 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> { min_length: size, from_end: false, }); - self.patch.add_assign(location, - Place::from(temp), - Rvalue::Use( - Operand::Move( - Place { - base: base.clone(), - projection: projection.into_boxed_slice(), - } - ) - ) + self.patch.add_assign( + location, + Place::from(temp), + Rvalue::Use(Operand::Move(Place { + base: base.clone(), + projection: self.tcx.intern_place_elems(&projection), + })), ); temp }).collect(); @@ -153,16 +150,13 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> { min_length: size, from_end: false, }); - self.patch.add_assign(location, - dst_place.clone(), - Rvalue::Use( - Operand::Move( - Place { - base: base.clone(), - projection: projection.into_boxed_slice(), - } - ) - ) + self.patch.add_assign( + location, + dst_place.clone(), + Rvalue::Use(Operand::Move(Place { + base: base.clone(), + projection: self.tcx.intern_place_elems(&projection), + })), ); } _ => {} @@ -185,9 +179,11 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> { // // replaced by _10 = move _2[:-1]; -pub struct RestoreSubsliceArrayMoveOut; +pub struct RestoreSubsliceArrayMoveOut<'tcx> { + tcx: TyCtxt<'tcx> +} -impl<'tcx> MirPass<'tcx> for RestoreSubsliceArrayMoveOut { +impl<'tcx> MirPass<'tcx> for RestoreSubsliceArrayMoveOut<'tcx> { fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) { let mut patch = MirPatch::new(body); let param_env = tcx.param_env(src.def_id()); @@ -229,7 +225,9 @@ impl<'tcx> MirPass<'tcx> for RestoreSubsliceArrayMoveOut { None } }); - Self::check_and_patch(*candidate, &items, opt_size, &mut patch, dst_place); + let restore_subslice = RestoreSubsliceArrayMoveOut { tcx }; + restore_subslice + .check_and_patch(*candidate, &items, opt_size, &mut patch, dst_place); } } } @@ -238,15 +236,20 @@ impl<'tcx> MirPass<'tcx> for RestoreSubsliceArrayMoveOut { } } -impl RestoreSubsliceArrayMoveOut { +impl RestoreSubsliceArrayMoveOut<'tcx> { + pub fn new(tcx: TyCtxt<'tcx>) -> Self { + RestoreSubsliceArrayMoveOut { tcx } + } + // Checks that source has size, all locals are inited from same source place and // indices is an integer interval. If all checks pass do the replacent. // items are Vec> - fn check_and_patch<'tcx>(candidate: Location, - items: &[Option<(&LocalUse, u32, PlaceRef<'_, 'tcx>)>], - opt_size: Option, - patch: &mut MirPatch<'tcx>, - dst_place: &Place<'tcx>) { + fn check_and_patch(&self, + candidate: Location, + items: &[Option<(&LocalUse, u32, PlaceRef<'_, 'tcx>)>], + opt_size: Option, + patch: &mut MirPatch<'tcx>, + dst_place: &Place<'tcx>) { let opt_src_place = items.first().and_then(|x| *x).map(|x| x.2); if opt_size.is_some() && items.iter().all( @@ -279,14 +282,14 @@ impl RestoreSubsliceArrayMoveOut { dst_place.clone(), Rvalue::Use(Operand::Move(Place { base: src_place.base.clone(), - projection: projection.into_boxed_slice(), + projection: self.tcx.intern_place_elems(&projection), })), ); } } - fn try_get_item_source<'a, 'tcx>(local_use: &LocalUse, - body: &'a Body<'tcx>) -> Option<(u32, PlaceRef<'a, 'tcx>)> { + fn try_get_item_source<'a>(local_use: &LocalUse, + body: &'a Body<'tcx>) -> Option<(u32, PlaceRef<'a, 'tcx>)> { if let Some(location) = local_use.first_use { let block = &body[location.block]; if block.statements.len() > location.statement_index { diff --git a/src/librustc_mir/util/aggregate.rs b/src/librustc_mir/util/aggregate.rs index c0f9218574556..f972069b677e5 100644 --- a/src/librustc_mir/util/aggregate.rs +++ b/src/librustc_mir/util/aggregate.rs @@ -1,5 +1,5 @@ use rustc::mir::*; -use rustc::ty::Ty; +use rustc::ty::{Ty, TyCtxt}; use rustc::ty::layout::VariantIdx; use rustc_index::vec::Idx; @@ -17,6 +17,7 @@ pub fn expand_aggregate<'tcx>( operands: impl Iterator, Ty<'tcx>)> + TrustedLen, kind: AggregateKind<'tcx>, source_info: SourceInfo, + tcx: TyCtxt<'tcx>, ) -> impl Iterator> + TrustedLen { let mut set_discriminant = None; let active_field_index = match kind { @@ -29,7 +30,7 @@ pub fn expand_aggregate<'tcx>( }, source_info, }); - lhs = lhs.downcast(adt_def, variant_index); + lhs = lhs.downcast(adt_def, variant_index, tcx); } active_field_index } @@ -63,10 +64,10 @@ pub fn expand_aggregate<'tcx>( // FIXME(eddyb) `min_length` doesn't appear to be used. min_length: offset + 1, from_end: false - }) + }, tcx) } else { let field = Field::new(active_field_index.unwrap_or(i)); - lhs.clone().field(field, ty) + lhs.clone().field(field, ty, tcx) }; Statement { source_info, diff --git a/src/librustc_mir/util/def_use.rs b/src/librustc_mir/util/def_use.rs index cdd07ad4b8ff4..725ec84ca6237 100644 --- a/src/librustc_mir/util/def_use.rs +++ b/src/librustc_mir/util/def_use.rs @@ -2,6 +2,7 @@ use rustc::mir::{Body, Local, Location, PlaceElem}; use rustc::mir::visit::{PlaceContext, MutVisitor, Visitor}; +use rustc::ty::TyCtxt; use rustc_index::vec::IndexVec; use std::mem; @@ -47,20 +48,26 @@ impl DefUseAnalysis { &self.info[local] } - fn mutate_defs_and_uses(&self, local: Local, body: &mut Body<'_>, new_local: Local) { + fn mutate_defs_and_uses( + &self, + local: Local, + body: &mut Body<'tcx>, + new_local: Local, + tcx: TyCtxt<'tcx>, + ) { for place_use in &self.info[local].defs_and_uses { - MutateUseVisitor::new(local, - new_local, - body).visit_location(body, place_use.location) + MutateUseVisitor::new(local, new_local, body, tcx) + .visit_location(body, place_use.location) } } // FIXME(pcwalton): this should update the def-use chains. pub fn replace_all_defs_and_uses_with(&self, local: Local, - body: &mut Body<'_>, - new_local: Local) { - self.mutate_defs_and_uses(local, body, new_local) + body: &mut Body<'tcx>, + new_local: Local, + tcx: TyCtxt<'tcx>) { + self.mutate_defs_and_uses(local, body, new_local, tcx) } } @@ -114,21 +121,28 @@ impl Info { } } -struct MutateUseVisitor { +struct MutateUseVisitor<'tcx> { query: Local, new_local: Local, + tcx: TyCtxt<'tcx>, } -impl MutateUseVisitor { - fn new(query: Local, new_local: Local, _: &Body<'_>) -> MutateUseVisitor { - MutateUseVisitor { - query, - new_local, - } +impl MutateUseVisitor<'tcx> { + fn new( + query: Local, + new_local: Local, + _: &Body<'tcx>, + tcx: TyCtxt<'tcx>, + ) -> MutateUseVisitor<'tcx> { + MutateUseVisitor { query, new_local, tcx } } } -impl MutVisitor<'_> for MutateUseVisitor { +impl MutVisitor<'tcx> for MutateUseVisitor<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + fn visit_local(&mut self, local: &mut Local, _context: PlaceContext, diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index f7ba6f1ec6993..4eb35022b59e1 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -206,7 +206,7 @@ where self.elaborator.param_env(), f.ty(self.tcx(), substs), ); - (base_place.clone().field(field, field_ty), subpath) + (base_place.clone().field(field, field_ty, self.tcx()), subpath) }).collect() } @@ -323,7 +323,7 @@ where debug!("open_drop_for_tuple({:?}, {:?})", self, tys); let fields = tys.iter().enumerate().map(|(i, &ty)| { - (self.place.clone().field(Field::new(i), ty), + (self.place.clone().field(Field::new(i), ty, self.tcx()), self.elaborator.field_subpath(self.path, Field::new(i))) }).collect(); @@ -334,7 +334,7 @@ where fn open_drop_for_box(&mut self, adt: &'tcx ty::AdtDef, substs: SubstsRef<'tcx>) -> BasicBlock { debug!("open_drop_for_box({:?}, {:?}, {:?})", self, adt, substs); - let interior = self.place.clone().deref(); + let interior = self.place.clone().deref(self.tcx()); let interior_path = self.elaborator.deref_subpath(self.path); let succ = self.succ; // FIXME(#43234) @@ -413,7 +413,7 @@ where if let Some(variant_path) = subpath { let base_place = self.place.clone().elem( ProjectionElem::Downcast(Some(adt.variants[variant_index].ident.name), - variant_index)); + variant_index), self.tcx()); let fields = self.move_paths_for_fields( &base_place, variant_path, @@ -586,7 +586,7 @@ where BorrowKind::Mut { allow_two_phase_borrow: false }, Place { base: PlaceBase::Local(cur), - projection: Box::new([ProjectionElem::Deref]), + projection: self.tcx().intern_place_elems(&vec![ProjectionElem::Deref]), } ), Rvalue::BinaryOp(BinOp::Offset, move_(&Place::from(cur)), one)) @@ -594,7 +594,7 @@ where (Rvalue::Ref( tcx.lifetimes.re_erased, BorrowKind::Mut { allow_two_phase_borrow: false }, - self.place.clone().index(cur)), + self.place.clone().index(cur, self.tcx())), Rvalue::BinaryOp(BinOp::Add, move_(&Place::from(cur)), one)) }; @@ -627,7 +627,7 @@ where let loop_block = self.elaborator.patch().new_block(loop_block); self.elaborator.patch().patch_terminator(drop_block, TerminatorKind::Drop { - location: ptr.clone().deref(), + location: ptr.clone().deref(tcx), target: loop_block, unwind: unwind.into_option() }); @@ -653,7 +653,7 @@ where offset: i, min_length: size, from_end: false - }), + }, self.tcx()), self.elaborator.array_subpath(self.path, i, size)) }).collect(); @@ -901,7 +901,7 @@ where let args = adt.variants[VariantIdx::new(0)].fields.iter().enumerate().map(|(i, f)| { let field = Field::new(i); let field_ty = f.ty(self.tcx(), substs); - Operand::Move(self.place.clone().field(field, field_ty)) + Operand::Move(self.place.clone().field(field, field_ty, self.tcx())) }).collect(); let call = TerminatorKind::Call {