From 222abfc311b7342c3d215bd8ba99fc8745c27afa Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 1 Feb 2019 23:56:31 +0100 Subject: [PATCH] Make StatementKind::Assign carry a NeoPlace instead of a Place --- src/librustc/mir/mod.rs | 2 +- src/librustc/mir/visit.rs | 28 +++++--- src/librustc_codegen_ssa/mir/analyze.rs | 6 +- src/librustc_codegen_ssa/mir/statement.rs | 4 +- src/librustc_mir/borrow_check/borrow_set.rs | 9 ++- .../borrow_check/error_reporting.rs | 15 ++-- src/librustc_mir/borrow_check/mod.rs | 3 +- src/librustc_mir/borrow_check/move_errors.rs | 3 +- .../borrow_check/nll/constraint_generation.rs | 8 +-- .../borrow_check/nll/explain_borrow/mod.rs | 22 ++++-- .../borrow_check/nll/invalidation.rs | 2 +- .../borrow_check/nll/type_check/mod.rs | 39 +++++------ src/librustc_mir/borrow_check/used_muts.rs | 3 +- src/librustc_mir/build/block.rs | 3 +- src/librustc_mir/build/cfg.rs | 6 +- src/librustc_mir/build/expr/as_place.rs | 6 +- src/librustc_mir/build/expr/as_rvalue.rs | 22 +++--- src/librustc_mir/build/expr/into.rs | 23 ++++--- src/librustc_mir/build/expr/stmt.rs | 5 +- src/librustc_mir/build/matches/mod.rs | 11 ++- src/librustc_mir/build/matches/test.rs | 25 ++++--- src/librustc_mir/build/misc.rs | 3 +- src/librustc_mir/dataflow/impls/borrows.rs | 2 +- .../dataflow/move_paths/builder.rs | 7 +- src/librustc_mir/interpret/step.rs | 3 +- src/librustc_mir/shim.rs | 23 ++++--- .../transform/add_moves_for_packed_drops.rs | 2 +- src/librustc_mir/transform/add_retag.rs | 5 +- .../transform/cleanup_post_borrowck.rs | 7 +- src/librustc_mir/transform/const_prop.rs | 5 +- src/librustc_mir/transform/copy_prop.rs | 20 ++++-- src/librustc_mir/transform/deaggregator.rs | 3 +- src/librustc_mir/transform/elaborate_drops.rs | 11 ++- src/librustc_mir/transform/generator.rs | 4 +- src/librustc_mir/transform/inline.rs | 8 +-- src/librustc_mir/transform/lower_128bit.rs | 6 +- src/librustc_mir/transform/promote_consts.rs | 13 +++- src/librustc_mir/transform/qualify_consts.rs | 68 ++++++++++++++++++- .../transform/qualify_min_const_fn.rs | 2 +- .../transform/remove_noop_landing_pads.rs | 5 +- src/librustc_mir/transform/rustc_peek.rs | 4 +- .../transform/uniform_array_move_out.rs | 21 +++--- src/librustc_mir/util/elaborate_drops.rs | 40 ++++++----- src/librustc_mir/util/patch.rs | 2 +- 44 files changed, 339 insertions(+), 170 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 58edc2268b21b..429877cf35bbb 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1753,7 +1753,7 @@ impl<'tcx> Statement<'tcx> { #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] pub enum StatementKind<'tcx> { /// Write the RHS Rvalue to the LHS Place. - Assign(Place<'tcx>, Box>), + Assign(NeoPlace<'tcx>, Box>), /// This represents all the reading that a pattern match may do /// (e.g., inspecting constants and discriminant values), and the diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 250625ee0dc8b..e455d9b1f1a46 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -96,7 +96,7 @@ macro_rules! make_mir_visitor { fn visit_assign(&mut self, block: BasicBlock, - place: & $($mutability)* Place<'tcx>, + place: & $($mutability)* NeoPlace<'tcx>, rvalue: & $($mutability)* Rvalue<'tcx>, location: Location) { self.super_assign(block, place, rvalue, location); @@ -441,10 +441,10 @@ macro_rules! make_mir_visitor { fn super_assign(&mut self, _block: BasicBlock, - place: &$($mutability)* Place<'tcx>, + place: &$($mutability)* NeoPlace<'tcx>, rvalue: &$($mutability)* Rvalue<'tcx>, location: Location) { - self.visit_place( + self.visit_neoplace( place, PlaceContext::MutatingUse(MutatingUseContext::Store), location @@ -771,6 +771,16 @@ macro_rules! make_mir_visitor { base, elems, } = place; + + let mut context = context; + + if !elems.is_empty() { + context = if context.is_mutating_use() { + PlaceContext::MutatingUse(MutatingUseContext::Projection) + } else { + PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) + }; + } match base { PlaceBase::Local(local) => { @@ -784,13 +794,11 @@ macro_rules! make_mir_visitor { } } - if !elems.is_empty() { - for elem in elems.iter().cloned().rev() { - self.visit_projection_elem( - &$($mutability)* elem.clone(), - location - ); - } + for elem in elems.iter().cloned().rev() { + self.visit_projection_elem( + &$($mutability)* elem.clone(), + location + ); } } diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index a1230982913b3..6235778ff61bf 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -98,18 +98,18 @@ impl<'mir, 'a: 'mir, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx, Bx> { fn visit_assign(&mut self, block: mir::BasicBlock, - place: &mir::Place<'tcx>, + place: &mir::NeoPlace<'tcx>, rvalue: &mir::Rvalue<'tcx>, location: Location) { debug!("visit_assign(block={:?}, place={:?}, rvalue={:?})", block, place, rvalue); - if let mir::Place::Local(index) = *place { + if let Some(index) = place.as_local() { self.assign(index, location); if !self.fx.rvalue_creates_operand(rvalue) { self.not_ssa(index); } } else { - self.visit_place( + self.visit_neoplace( place, PlaceContext::MutatingUse(MutatingUseContext::Store), location diff --git a/src/librustc_codegen_ssa/mir/statement.rs b/src/librustc_codegen_ssa/mir/statement.rs index 9561a57d0a7de..c485b4820f271 100644 --- a/src/librustc_codegen_ssa/mir/statement.rs +++ b/src/librustc_codegen_ssa/mir/statement.rs @@ -17,7 +17,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.set_debug_loc(&mut bx, statement.source_info); match statement.kind { mir::StatementKind::Assign(ref place, ref rvalue) => { - if let mir::Place::Local(index) = *place { + if let Some(index) = place.as_local() { match self.locals[index] { LocalRef::Place(cg_dest) => { self.codegen_rvalue(bx, cg_dest, rvalue) @@ -43,7 +43,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } } else { - let cg_dest = self.codegen_place(&mut bx, place); + let cg_dest = self.codegen_place(&mut bx, &place.clone().into_tree()); self.codegen_rvalue(bx, cg_dest, rvalue) } } diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index 5ba2dd6f52e51..522e452f53cf9 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -187,7 +187,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> { fn visit_assign( &mut self, block: mir::BasicBlock, - assigned_place: &mir::Place<'tcx>, + assigned_place: &mir::NeoPlace<'tcx>, rvalue: &mir::Rvalue<'tcx>, location: mir::Location, ) { @@ -206,15 +206,14 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> { reserve_location: location, activation_location: TwoPhaseActivation::NotTwoPhase, borrowed_place: borrowed_place.clone(), - assigned_place: assigned_place.clone(), + assigned_place: assigned_place.clone().into_tree(), }; let idx = self.idx_vec.push(borrow); self.location_map.insert(location, idx); - self.insert_as_pending_if_two_phase(location, &assigned_place, kind, idx); + self.insert_as_pending_if_two_phase(location, &assigned_place.clone().into_tree(), kind, idx); - let neo_place = self.tcx.as_new_place(borrowed_place); - if let mir::PlaceBase::Local(local) = neo_place.base { + if let mir::PlaceBase::Local(local) = borrowed_neo_place.base { self.local_map.entry(local).or_default().insert(idx); } } diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index a4b72b494b851..55cdeea2dc1d3 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -1495,8 +1495,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { target == neo_place.base_local() } => { - let neo_into = self.infcx.tcx.as_new_place(into); - target = neo_into.base_local(); + target = into.base_local(); } _ => {}, } @@ -1931,7 +1930,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { "annotate_argument_and_return_for_borrow: reservation={:?}", reservation ); - let reservation = self.infcx.tcx.as_new_place(reservation); // Check that the initial assignment of the reserve location is into a temporary. let mut target = match reservation.as_local() { Some(local) if self.mir.local_kind(local) == LocalKind::Temp => local, @@ -1946,7 +1944,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { "annotate_argument_and_return_for_borrow: target={:?} stmt={:?}", target, stmt ); - if let StatementKind::Assign(Place::Local(assigned_to), box rvalue) = &stmt.kind + if let StatementKind::Assign( + NeoPlace { + base: PlaceBase::Local(assigned_to), + elems: &[], + }, box rvalue) = &stmt.kind { debug!( "annotate_argument_and_return_for_borrow: assigned_to={:?} \ @@ -2513,7 +2515,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { .get(location.statement_index) { Some(&Statement { - kind: StatementKind::Assign(Place::Local(local), _), + kind: StatementKind::Assign(NeoPlace { + base: PlaceBase::Local(local), + elems: &[], + }, _), .. }) => local, _ => return OtherUse(use_span), diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index f2a1fe45c77c1..c06843fba9123 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -503,9 +503,10 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx flow_state, ); + let lhs = lhs.clone().into_tree(); self.mutate_place( ContextKind::AssignLhs.new(location), - (lhs, span), + (&lhs, span), Shallow(None), JustWrite, flow_state, diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs index a8f05dc41d062..5028c88134d8a 100644 --- a/src/librustc_mir/borrow_check/move_errors.rs +++ b/src/librustc_mir/borrow_check/move_errors.rs @@ -118,8 +118,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { .get(location.statement_index) .map(|stmt| &stmt.kind) { - let neo_place = self.infcx.tcx.as_new_place(&place); - if let Some(PlaceBase::Local(local)) = neo_place.as_place_base() { + if let Some(PlaceBase::Local(local)) = place.as_place_base() { let local_decl = &self.mir.local_decls[*local]; // opt_match_place is the // match_span is the span of the expression being matched on diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs index 588f46cb77fe2..af973100ce4bc 100644 --- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs @@ -6,7 +6,7 @@ use borrow_check::nll::region_infer::values::LivenessValues; use rustc::infer::InferCtxt; use rustc::mir::visit::TyContext; use rustc::mir::visit::Visitor; -use rustc::mir::{BasicBlock, BasicBlockData, Location, Mir, Place, Rvalue}; +use rustc::mir::{BasicBlock, BasicBlockData, Location, Mir, Place, NeoPlace, Rvalue}; use rustc::mir::{SourceInfo, Statement, Terminator}; use rustc::mir::UserTypeProjection; use rustc::ty::fold::TypeFoldable; @@ -123,15 +123,15 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx fn visit_assign( &mut self, block: BasicBlock, - place: &Place<'tcx>, + place: &NeoPlace<'tcx>, rvalue: &Rvalue<'tcx>, location: Location, ) { // When we see `X = ...`, then kill borrows of // `(*X).foo` and so forth. if let Some(all_facts) = self.all_facts { - if let Place::Local(temp) = place { - if let Some(borrow_indices) = self.borrow_set.local_map.get(temp) { + if let Some(temp) = place.as_local() { + if let Some(borrow_indices) = self.borrow_set.local_map.get(&temp) { all_facts.killed.reserve(borrow_indices.len()); for &borrow_index in borrow_indices { let location_index = self.location_table.mid_index(location); diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index 968c0f53a4852..c51f7ef5fef06 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -6,7 +6,7 @@ use borrow_check::{Context, MirBorrowckCtxt, WriteKind}; use rustc::ty::{self, TyCtxt}; use rustc::mir::{ CastKind, ConstraintCategory, FakeReadCause, Local, Location, Mir, Operand, - Place, Projection, ProjectionElem, Rvalue, Statement, StatementKind, + Place, NeoPlace, PlaceBase, ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind }; use rustc_errors::DiagnosticBuilder; @@ -422,7 +422,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // it which simplifies the termination logic. let mut queue = vec![location]; let mut target = if let Some(&Statement { - kind: StatementKind::Assign(Place::Local(local), _), + kind: StatementKind::Assign(NeoPlace { + base: PlaceBase::Local(local), + elems: &[], + }, _), .. }) = stmt { local @@ -446,11 +449,16 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { box rvalue, ) = &stmt.kind { let into = match place { - Place::Local(into) => into, - Place::Projection(box Projection { - base: Place::Local(into), - elem: ProjectionElem::Deref, - }) => into, + NeoPlace { + base: PlaceBase::Local(into), + elems: &[], + } => into, + + NeoPlace { + base: PlaceBase::Local(into), + elems, + } if elems.last().unwrap() == &ProjectionElem::Deref => into, + _ => { // Continue at the next location. queue.push(current_location.successor_within_block()); diff --git a/src/librustc_mir/borrow_check/nll/invalidation.rs b/src/librustc_mir/borrow_check/nll/invalidation.rs index 4af004f437fcf..b173b2c619256 100644 --- a/src/librustc_mir/borrow_check/nll/invalidation.rs +++ b/src/librustc_mir/borrow_check/nll/invalidation.rs @@ -73,7 +73,7 @@ impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> { self.mutate_place( ContextKind::AssignLhs.new(location), - lhs, + &lhs.clone().into_tree(), Shallow(None), JustWrite ); diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index a553bf1cd2225..3581a71f52c24 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -1234,32 +1234,33 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { // they are not caused by the user, but rather artifacts // of lowering. Assignments to other sorts of places *are* interesting // though. - let category = match *place { - Place::Local(RETURN_PLACE) => if let Some(BorrowCheckContext { - universal_regions: - UniversalRegions { - defining_ty: DefiningTy::Const(def_id, _), + let category = match place.as_local() { + Some(RETURN_PLACE) => + if let Some(BorrowCheckContext { + universal_regions: + UniversalRegions { + defining_ty: DefiningTy::Const(def_id, _), + .. + }, .. - }, - .. - }) = self.borrowck_context - { - if tcx.is_static(*def_id).is_some() { - ConstraintCategory::UseAsStatic + }) = self.borrowck_context { + if tcx.is_static(*def_id).is_some() { + ConstraintCategory::UseAsStatic + } else { + ConstraintCategory::UseAsConst + } } else { - ConstraintCategory::UseAsConst - } - } else { - ConstraintCategory::Return - }, - Place::Local(l) if !mir.local_decls[l].is_user_variable.is_some() => { + ConstraintCategory::Return + }, + + Some(l) if !mir.local_decls[l].is_user_variable.is_some() => { ConstraintCategory::Boring } + _ => ConstraintCategory::Assignment, }; - let neo_place = tcx.as_new_place(place); - let place_ty = neo_place.ty(mir, tcx).to_ty(tcx); + let place_ty = place.ty(mir, tcx).to_ty(tcx); let rv_ty = rv.ty(mir, tcx); if let Err(terr) = self.sub_types_or_anon(rv_ty, place_ty, location.to_locations(), category) diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs index c43e80749d6b5..ce39219fdd206 100644 --- a/src/librustc_mir/borrow_check/used_muts.rs +++ b/src/librustc_mir/borrow_check/used_muts.rs @@ -88,8 +88,7 @@ impl<'visit, 'cx, 'gcx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'c // be those that were never initialized - we will consider those as being used as // they will either have been removed by unreachable code optimizations; or linted // as unused variables. - let neo_into = self.mbcx.infcx.tcx.as_new_place(into); - if let Some(local) = neo_into.base_local() { + if let Some(local) = into.base_local() { debug!( "visit_statement: statement={:?} local={:?} \ never_initialized_mut_locals={:?}", diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index 49ed5705dee85..9aed2f7e72429 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -184,7 +184,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { if destination_ty.is_unit() { // We only want to assign an implicit `()` as the return value of the block if the // block does not diverge. (Otherwise, we may try to assign a unit to a `!`-type.) - this.cfg.push_assign_unit(block, source_info, destination); + let destination = tcx.as_new_place(destination); + this.cfg.push_assign_unit(block, source_info, &destination); } } // Finally, we pop all the let scopes before exiting out from the scope of block diff --git a/src/librustc_mir/build/cfg.rs b/src/librustc_mir/build/cfg.rs index a9e468db1d1b7..83a4477b1b6e4 100644 --- a/src/librustc_mir/build/cfg.rs +++ b/src/librustc_mir/build/cfg.rs @@ -33,7 +33,7 @@ impl<'tcx> CFG<'tcx> { pub fn push_assign(&mut self, block: BasicBlock, source_info: SourceInfo, - place: &Place<'tcx>, + place: &NeoPlace<'tcx>, rvalue: Rvalue<'tcx>) { self.push(block, Statement { source_info, @@ -44,7 +44,7 @@ impl<'tcx> CFG<'tcx> { pub fn push_assign_constant(&mut self, block: BasicBlock, source_info: SourceInfo, - temp: &Place<'tcx>, + temp: &NeoPlace<'tcx>, constant: Constant<'tcx>) { self.push_assign(block, source_info, temp, Rvalue::Use(Operand::Constant(box constant))); @@ -53,7 +53,7 @@ impl<'tcx> CFG<'tcx> { pub fn push_assign_unit(&mut self, block: BasicBlock, source_info: SourceInfo, - place: &Place<'tcx>) { + place: &NeoPlace<'tcx>) { self.push_assign(block, source_info, place, Rvalue::Aggregate( box AggregateKind::Tuple, vec![] )); diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 6bd61ab53fd21..960aff3e0b35e 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -86,16 +86,18 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { this.temp(usize_ty.clone(), expr_span), this.temp(bool_ty, expr_span), ); + let neo_len = this.hir.tcx().as_new_place(&len); this.cfg.push_assign( block, source_info, // len = len(slice) - &len, + &neo_len, Rvalue::Len(slice.clone()), ); + let neo_lt = this.hir.tcx().as_new_place(<); this.cfg.push_assign( block, source_info, // lt = idx < len - <, + &neo_lt, Rvalue::BinaryOp( BinOp::Lt, Operand::Copy(Place::Local(idx)), diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 3de2f47578650..bec70efe8f0ea 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -90,10 +90,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let minval = this.minval_literal(expr_span, expr.ty); let is_min = this.temp(bool_ty, expr_span); + let neo_is_min = this.hir.tcx().as_new_place(&is_min); this.cfg.push_assign( block, source_info, - &is_min, + &neo_is_min, Rvalue::BinaryOp(BinOp::Eq, arg.to_copy(), minval), ); @@ -135,7 +136,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // malloc some memory of suitable type (thus far, uninitialized): let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty); this.cfg - .push_assign(block, source_info, &Place::Local(result), box_); + .push_assign(block, source_info, &NeoPlace::local(result), box_); // initialize the box contents: unpack!(block = this.into(&Place::Local(result).deref(), block, value)); @@ -414,10 +415,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let result_tup = self.hir.tcx().intern_tup(&[ty, bool_ty]); let result_value = self.temp(result_tup, span); + let neo_result_value = self.hir.tcx().as_new_place(&result_value); self.cfg.push_assign( block, source_info, - &result_value, + &neo_result_value, Rvalue::CheckedBinaryOp(op, lhs, rhs), ); let val_fld = Field::new(0); @@ -445,10 +447,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // Check for / 0 let is_zero = self.temp(bool_ty, span); let zero = self.zero_literal(span, ty); + let neo_is_zero = self.hir.tcx().as_new_place(&is_zero); self.cfg.push_assign( block, source_info, - &is_zero, + &neo_is_zero, Rvalue::BinaryOp(BinOp::Eq, rhs.to_copy(), zero), ); @@ -466,25 +469,28 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // this does (rhs == -1) & (lhs == MIN). It could short-circuit instead + let neo_is_neg_1 = self.hir.tcx().as_new_place(&is_neg_1); self.cfg.push_assign( block, source_info, - &is_neg_1, + &neo_is_neg_1, Rvalue::BinaryOp(BinOp::Eq, rhs.to_copy(), neg_1), ); + let neo_is_min = self.hir.tcx().as_new_place(&is_min); self.cfg.push_assign( block, source_info, - &is_min, + &neo_is_min, Rvalue::BinaryOp(BinOp::Eq, lhs.to_copy(), min), ); let is_neg_1 = Operand::Move(is_neg_1); let is_min = Operand::Move(is_min); + let neo_of = self.hir.tcx().as_new_place(&of); self.cfg.push_assign( block, source_info, - &of, + &neo_of, Rvalue::BinaryOp(BinOp::BitAnd, is_neg_1, is_min), ); @@ -583,7 +589,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { this.cfg.push_assign( block, source_info, - &Place::Local(temp), + &NeoPlace::local(temp), Rvalue::Ref(this.hir.tcx().types.re_erased, borrow_kind, arg_place), ); diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 2ffff68137dd2..e962ff8c6ec43 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -94,8 +94,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } else { // Body of the `if` expression without an `else` clause must return `()`, thus // we implicitly generate a `else {}` if it is not specified. + let destination = this.hir.tcx().as_new_place(destination); this.cfg - .push_assign_unit(else_block, source_info, destination); + .push_assign_unit(else_block, source_info, &destination); else_block }; @@ -140,10 +141,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let term = TerminatorKind::if_(this.hir.tcx(), lhs, blocks.0, blocks.1); this.cfg.terminate(block, source_info, term); + let destination = this.hir.tcx().as_new_place(destination); this.cfg.push_assign_constant( shortcircuit_block, source_info, - destination, + &destination, Constant { span: expr_span, ty: this.hir.bool_ty(), @@ -164,7 +166,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { this.cfg.push_assign( else_block, source_info, - destination, + &destination, Rvalue::Use(rhs), ); this.cfg.terminate( @@ -228,8 +230,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // if the test is false, there's no `break` to assign `destination`, so // we have to do it; this overwrites any `break`-assigned value but it's // always `()` anyway + let destination = this.hir.tcx().as_new_place(destination); this.cfg - .push_assign_unit(exit_block, source_info, destination); + .push_assign_unit(exit_block, source_info, &destination); } else { body_block = this.cfg.start_new_block(); let diverge_cleanup = this.diverge_cleanup(); @@ -336,7 +339,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { | ExprKind::InlineAsm { .. } | ExprKind::Return { .. } => { unpack!(block = this.stmt_expr(block, expr, None)); - this.cfg.push_assign_unit(block, source_info, destination); + let destination = this.hir.tcx().as_new_place(destination); + this.cfg.push_assign_unit(block, source_info, &destination); block.unit() } @@ -350,8 +354,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let place = unpack!(block = this.as_place(block, expr)); let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place)); + let destination = this.hir.tcx().as_new_place(destination); this.cfg - .push_assign(block, source_info, destination, rvalue); + .push_assign(block, source_info, &destination, rvalue); block.unit() } ExprKind::Index { .. } | ExprKind::Deref { .. } | ExprKind::Field { .. } => { @@ -369,8 +374,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let place = unpack!(block = this.as_place(block, expr)); let rvalue = Rvalue::Use(this.consume_by_copy_or_move(place)); + let destination = this.hir.tcx().as_new_place(destination); this.cfg - .push_assign(block, source_info, destination, rvalue); + .push_assign(block, source_info, &destination, rvalue); block.unit() } @@ -405,7 +411,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }); let rvalue = unpack!(block = this.as_local_rvalue(block, expr)); - this.cfg.push_assign(block, source_info, destination, rvalue); + let destination = this.hir.tcx().as_new_place(destination); + this.cfg.push_assign(block, source_info, &destination, rvalue); block.unit() } }; diff --git a/src/librustc_mir/build/expr/stmt.rs b/src/librustc_mir/build/expr/stmt.rs index 1cbc60586c356..b24c4d8d432c8 100644 --- a/src/librustc_mir/build/expr/stmt.rs +++ b/src/librustc_mir/build/expr/stmt.rs @@ -54,6 +54,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } else { let rhs = unpack!(block = this.as_local_rvalue(block, rhs)); let lhs = unpack!(block = this.as_place(block, lhs)); + let lhs = this.hir.tcx().as_new_place(&lhs); this.cfg.push_assign(block, source_info, &lhs, rhs); } @@ -92,6 +93,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { rhs ) ); + let lhs = this.hir.tcx().as_new_place(&lhs); this.cfg.push_assign(block, source_info, &lhs, result); this.block_context.pop(); @@ -129,6 +131,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { unpack!(block = this.into(&destination, block, value)); this.block_context.pop(); } else { + let destination = this.hir.tcx().as_new_place(&destination); this.cfg.push_assign_unit(block, source_info, &destination) } this.exit_scope(expr_span, (region_scope, source_info), block, break_block); @@ -145,7 +148,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } None => { this.cfg - .push_assign_unit(block, source_info, &Place::Local(RETURN_PLACE)); + .push_assign_unit(block, source_info, &NeoPlace::local(RETURN_PLACE)); block } }; diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 1815dda5a4b37..3fa66761578cb 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -1396,8 +1396,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { match binding.binding_mode { BindingMode::ByValue => { let rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, binding.source.clone()); + let neo_ref_for_guard = self.hir.tcx().as_new_place(&ref_for_guard); self.cfg - .push_assign(block, source_info, &ref_for_guard, rvalue); + .push_assign(block, source_info, &neo_ref_for_guard, rvalue); } BindingMode::ByRef(borrow_kind) => { // Tricky business: For `ref id` and `ref mut id` @@ -1440,9 +1441,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }, }; let rvalue = Rvalue::Ref(re_erased, borrow_kind, binding.source.clone()); + let neo_val_for_guard = self.hir.tcx().as_new_place(&val_for_guard); self.cfg - .push_assign(block, source_info, &val_for_guard, rvalue); + .push_assign(block, source_info, &neo_val_for_guard, rvalue); let rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, val_for_guard); + let ref_for_guard = self.hir.tcx().as_new_place(&ref_for_guard); self.cfg .push_assign(block, source_info, &ref_for_guard, rvalue); } @@ -1476,6 +1479,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { Rvalue::Ref(re_erased, borrow_kind, binding.source.clone()) } }; + let local = self.hir.tcx().as_new_place(&local); self.cfg.push_assign(block, source_info, &local, rvalue); } } @@ -1629,10 +1633,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { Rvalue::Ref(tcx.types.re_erased, borrow_kind, matched_place.clone()); let borrowed_input_ty = borrowed_input.ty(&self.local_decls, tcx); let borrowed_input_temp = self.temp(borrowed_input_ty, source_info.span); + let neo_borrowed_input_temp = tcx.as_new_place(&borrowed_input_temp); self.cfg.push_assign( start_block, source_info, - &borrowed_input_temp, + &neo_borrowed_input_temp, borrowed_input ); borrowed_input_temps.push(borrowed_input_temp); diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index e0c1f438def36..c769a6ee78196 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -207,7 +207,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { num_enum_variants, values, variants); let discr_ty = adt_def.repr.discr_type().to_ty(tcx); let discr = self.temp(discr_ty, test.span); - self.cfg.push_assign(block, source_info, &discr, + let neo_discr = self.hir.tcx().as_new_place(&discr); + self.cfg.push_assign(block, source_info, &neo_discr, Rvalue::Discriminant(place.clone())); assert_eq!(values.len() + 1, targets.len()); self.cfg.terminate(block, source_info, TerminatorKind::SwitchInt { @@ -284,6 +285,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ty = tcx.mk_imm_ref(region, tcx.mk_slice(elem_ty)); if opt_ref_ty.is_some() { place = self.temp(ty, test.span); + let place = tcx.as_new_place(&place); self.cfg.push_assign(block, source_info, &place, Rvalue::Cast(CastKind::Unsize, val, ty)); } @@ -295,7 +297,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ); let slice = self.temp(ty, test.span); - self.cfg.push_assign(block, source_info, &slice, + let neo_slice = tcx.as_new_place(&slice); + self.cfg.push_assign(block, source_info, &neo_slice, Rvalue::Cast(CastKind::Unsize, array, ty)); expect = Operand::Move(slice); } @@ -316,17 +319,20 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // let lhs_ref_place = &lhs; let ref_rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, place); let lhs_ref_place = self.temp(ref_ty, test.span); - self.cfg.push_assign(block, source_info, &lhs_ref_place, ref_rvalue); + let neo_lhs_ref_place = self.hir.tcx().as_new_place(&lhs_ref_place); + self.cfg.push_assign(block, source_info, &neo_lhs_ref_place, ref_rvalue); let val = Operand::Move(lhs_ref_place); // let rhs_place = rhs; let rhs_place = self.temp(ty, test.span); - self.cfg.push_assign(block, source_info, &rhs_place, Rvalue::Use(expect)); + let neo_rhs_place = self.hir.tcx().as_new_place(&rhs_place); + self.cfg.push_assign(block, source_info, &neo_rhs_place, Rvalue::Use(expect)); // let rhs_ref_place = &rhs_place; let ref_rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, rhs_place); let rhs_ref_place = self.temp(ref_ty, test.span); - self.cfg.push_assign(block, source_info, &rhs_ref_place, ref_rvalue); + let neo_rhs_ref_place = self.hir.tcx().as_new_place(&rhs_ref_place); + self.cfg.push_assign(block, source_info, &neo_rhs_ref_place, ref_rvalue); let expect = Operand::Move(rhs_ref_place); let bool_ty = self.hir.bool_ty(); @@ -389,14 +395,16 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { self.temp(bool_ty, test.span)); // actual = len(place) + let neo_actual = self.hir.tcx().as_new_place(&actual); self.cfg.push_assign(block, source_info, - &actual, Rvalue::Len(place.clone())); + &neo_actual, Rvalue::Len(place.clone())); // expected = let expected = self.push_usize(block, source_info, len); // result = actual == expected OR result = actual < expected - self.cfg.push_assign(block, source_info, &result, + let neo_result = self.hir.tcx().as_new_place(&result); + self.cfg.push_assign(block, source_info, &neo_result, Rvalue::BinaryOp(op, Operand::Move(actual), Operand::Move(expected))); @@ -424,7 +432,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // result = op(left, right) let source_info = self.source_info(span); - self.cfg.push_assign(block, source_info, &result, + let neo_result = self.hir.tcx().as_new_place(&result); + self.cfg.push_assign(block, source_info, &neo_result, Rvalue::BinaryOp(op, left, right)); // branch based on result diff --git a/src/librustc_mir/build/misc.rs b/src/librustc_mir/build/misc.rs index 62ec46bb2eed1..dbb9b0b7e52c0 100644 --- a/src/librustc_mir/build/misc.rs +++ b/src/librustc_mir/build/misc.rs @@ -57,8 +57,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { -> Place<'tcx> { let usize_ty = self.hir.usize_ty(); let temp = self.temp(usize_ty, source_info.span); + let neo_temp = self.hir.tcx().as_new_place(&temp); self.cfg.push_assign_constant( - block, source_info, &temp, + block, source_info, &neo_temp, Constant { span: source_info.span, ty: self.hir.usize_ty(), diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 9cfcca1edd972..cebdda392ccd5 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -266,7 +266,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for Borrows<'a, 'gcx, 'tcx> { mir::StatementKind::Assign(lhs, rhs) => { // Make sure there are no remaining borrows for variables // that are assigned over. - self.kill_borrows_on_place(sets, lhs); + self.kill_borrows_on_place(sets, &lhs.clone().into_tree()); if let box mir::Rvalue::Ref(_, _, place) = rhs { let neo_place = self.tcx.as_new_place(place); diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index a5e936d4b9e54..e895fa3e41780 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -259,15 +259,16 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> { fn gather_statement(&mut self, stmt: &Statement<'tcx>) { match stmt.kind { StatementKind::Assign(ref place, ref rval) => { - self.create_move_path(place); + let place = place.clone().into_tree(); + self.create_move_path(&place); if let RvalueInitializationState::Shallow = rval.initialization_state() { // 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.gather_init(place, InitKind::Shallow); + self.gather_init(&place, InitKind::Shallow); } else { - self.gather_init(place, InitKind::Deep); + self.gather_init(&place, InitKind::Deep); } self.gather_rvalue(rval); } diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index 25f3e4c1f771d..c7600ecfbedf7 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -82,7 +82,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> self.memory.tcx.span = stmt.source_info.span; match stmt.kind { - Assign(ref place, ref rvalue) => self.eval_rvalue_into_place(rvalue, place)?, + Assign(ref place, ref rvalue) => + self.eval_rvalue_into_place(rvalue, &place.clone().into_tree())?, SetDiscriminant { ref place, diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 751815eab287b..988b03293e98a 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -422,7 +422,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { let rcvr = Place::Local(Local::new(1+0)).deref(); let ret_statement = self.make_statement( StatementKind::Assign( - Place::Local(RETURN_PLACE), + NeoPlace::local(RETURN_PLACE), box Rvalue::Use(Operand::Copy(rcvr)) ) ); @@ -473,9 +473,10 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { ); // `let ref_loc: &ty = &src;` + let neo_ref_loc = tcx.as_new_place(&ref_loc); let statement = self.make_statement( StatementKind::Assign( - ref_loc.clone(), + neo_ref_loc.clone(), box Rvalue::Ref(tcx.types.re_erased, BorrowKind::Shared, src) ) ); @@ -501,9 +502,10 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { let tcx = self.tcx; let cond = self.make_place(Mutability::Mut, tcx.types.bool); + let neo_cond = tcx.as_new_place(&cond); let compute_cond = self.make_statement( StatementKind::Assign( - cond.clone(), + neo_cond.clone(), box Rvalue::BinaryOp(BinOp::Ne, Operand::Copy(end), Operand::Copy(beg)) ) ); @@ -538,16 +540,17 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { // `let mut beg = 0;` // `let end = len;` // `goto #1;` + let neo_end = tcx.as_new_place(&end); let inits = vec![ self.make_statement( StatementKind::Assign( - Place::Local(beg), + NeoPlace::local(beg), box Rvalue::Use(Operand::Constant(self.make_usize(0))) ) ), self.make_statement( StatementKind::Assign( - end.clone(), + neo_end.clone(), box Rvalue::Use(Operand::Constant(self.make_usize(len))) ) ) @@ -575,7 +578,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { let statements = vec![ self.make_statement( StatementKind::Assign( - Place::Local(beg), + NeoPlace::local(beg), box Rvalue::BinaryOp( BinOp::Add, Operand::Copy(Place::Local(beg)), @@ -598,7 +601,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { let beg = self.local_decls.push(temp_decl(Mutability::Mut, tcx.types.usize, span)); let init = self.make_statement( StatementKind::Assign( - Place::Local(beg), + NeoPlace::local(beg), box Rvalue::Use(Operand::Constant(self.make_usize(0))) ) ); @@ -625,7 +628,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { // `goto #6;` let statement = self.make_statement( StatementKind::Assign( - Place::Local(beg), + NeoPlace::local(beg), box Rvalue::BinaryOp( BinOp::Add, Operand::Copy(Place::Local(beg)), @@ -743,7 +746,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, statements.push(Statement { source_info, kind: StatementKind::Assign( - Place::Local(ref_rcvr), + NeoPlace::local(ref_rcvr), box Rvalue::Ref(tcx.types.re_erased, borrow_kind, rcvr_l) ) }); @@ -887,7 +890,7 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>, statements: vec![Statement { source_info, kind: StatementKind::Assign( - Place::Local(RETURN_PLACE), + NeoPlace::local(RETURN_PLACE), box Rvalue::Aggregate( box AggregateKind::Adt(adt_def, variant_no, substs, None, None), (1..sig.inputs().len()+1).map(|i| { diff --git a/src/librustc_mir/transform/add_moves_for_packed_drops.rs b/src/librustc_mir/transform/add_moves_for_packed_drops.rs index 2a78dfe473ddd..d00743eb53dd2 100644 --- a/src/librustc_mir/transform/add_moves_for_packed_drops.rs +++ b/src/librustc_mir/transform/add_moves_for_packed_drops.rs @@ -122,7 +122,7 @@ fn add_move_for_packed_drop<'a, 'tcx>( patch.add_statement( loc, StatementKind::StorageLive(temp)); - patch.add_assign(loc, Place::Local(temp), + patch.add_assign(loc, NeoPlace::local(temp), Rvalue::Use(Operand::Move(location.clone()))); patch.patch_terminator(loc.block, TerminatorKind::Drop { location: Place::Local(temp), diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs index 8726829fdf77c..b47b3b75ef6e8 100644 --- a/src/librustc_mir/transform/add_retag.rs +++ b/src/librustc_mir/transform/add_retag.rs @@ -175,7 +175,8 @@ impl MirPass for AddRetag { // Assignments of reference or ptr type are the ones where we may have // to update tags. This includes `x = &[mut] ...` and hence // we also retag after taking a reference! - StatementKind::Assign(ref place, box ref rvalue) if needs_retag(place) => { + StatementKind::Assign(ref place, box ref rvalue) if + needs_retag(&place.clone().into_tree()) => { let kind = match rvalue { Rvalue::Ref(_, borrow_kind, _) if borrow_kind.allows_two_phase_borrow() @@ -193,7 +194,7 @@ impl MirPass for AddRetag { let source_info = block_data.statements[i].source_info; block_data.statements.insert(i+1, Statement { source_info, - kind: StatementKind::Retag(retag_kind, place.clone()), + kind: StatementKind::Retag(retag_kind, place.clone().into_tree()), }); } } diff --git a/src/librustc_mir/transform/cleanup_post_borrowck.rs b/src/librustc_mir/transform/cleanup_post_borrowck.rs index e6df6b7fd2724..d6e33bf6d070e 100644 --- a/src/librustc_mir/transform/cleanup_post_borrowck.rs +++ b/src/librustc_mir/transform/cleanup_post_borrowck.rs @@ -22,7 +22,7 @@ use rustc_data_structures::fx::FxHashSet; -use rustc::mir::{BasicBlock, FakeReadCause, Local, Location, Mir, Place}; +use rustc::mir::{BasicBlock, FakeReadCause, Local, Location, Mir, Place, NeoPlace, PlaceBase}; use rustc::mir::{Statement, StatementKind}; use rustc::mir::visit::MutVisitor; use rustc::ty::TyCtxt; @@ -103,7 +103,10 @@ impl<'tcx> MutVisitor<'tcx> for DeleteFakeBorrows { block: BasicBlock, statement: &mut Statement<'tcx>, location: Location) { - if let StatementKind::Assign(Place::Local(local), _) = statement.kind { + if let StatementKind::Assign(NeoPlace { + base: PlaceBase::Local(local), + elems: &[], + }, _) = statement.kind { if self.fake_borrow_temporaries.contains(&local) { statement.make_nop(); } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index b63d1f4cc335c..08ec3a8704246 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -553,13 +553,12 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> { ) { trace!("visit_statement: {:?}", statement); if let StatementKind::Assign(ref place, ref rval) = statement.kind { - let neo_place = self.tcx.as_new_place(place); - let place_ty: ty::Ty<'tcx> = neo_place + let place_ty: ty::Ty<'tcx> = place .ty(&self.mir.local_decls, self.tcx) .to_ty(self.tcx); if let Ok(place_layout) = self.tcx.layout_of(self.param_env.and(place_ty)) { if let Some(value) = self.const_prop(rval, place_layout, statement.source_info) { - if let Place::Local(local) = *place { + if let Some(local) = place.as_local() { trace!("checking whether {:?} can be stored to {:?}", value, local); if self.can_const_prop[local] { trace!("storing {:?} to {:?}", value, local); diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs index 55e14077c3ed0..8a6e1b8e89f75 100644 --- a/src/librustc_mir/transform/copy_prop.rs +++ b/src/librustc_mir/transform/copy_prop.rs @@ -19,7 +19,10 @@ //! (non-mutating) use of `SRC`. These restrictions are conservative and may be relaxed in the //! future. -use rustc::mir::{Constant, Local, LocalKind, Location, Place, Mir, Operand, Rvalue, StatementKind}; +use rustc::mir::{ + Constant, Local, LocalKind, Location, Place, NeoPlace, PlaceBase, + Mir, Operand, Rvalue, StatementKind +}; use rustc::mir::visit::MutVisitor; use rustc::ty::TyCtxt; use transform::{MirPass, MirSource}; @@ -94,7 +97,10 @@ impl MirPass for CopyPropagation { // That use of the source must be an assignment. match statement.kind { - StatementKind::Assign(Place::Local(local), box Rvalue::Use(ref operand)) if + StatementKind::Assign(NeoPlace { + base: PlaceBase::Local(local), + elems: &[], + }, box Rvalue::Use(ref operand)) if local == dest_local => { let maybe_action = match *operand { Operand::Copy(ref src_place) | @@ -144,11 +150,17 @@ fn eliminate_self_assignments<'tcx>( if let Some(stmt) = mir[location.block].statements.get(location.statement_index) { match stmt.kind { StatementKind::Assign( - Place::Local(local), + NeoPlace { + base: PlaceBase::Local(local), + elems: &[], + }, box Rvalue::Use(Operand::Copy(Place::Local(src_local))), ) | StatementKind::Assign( - Place::Local(local), + NeoPlace { + base: PlaceBase::Local(local), + elems: &[], + }, box Rvalue::Use(Operand::Move(Place::Local(src_local))), ) if local == dest_local && dest_local == src_local => {} _ => { diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs index a2fe9def8eeba..e3c5e4ad87852 100644 --- a/src/librustc_mir/transform/deaggregator.rs +++ b/src/librustc_mir/transform/deaggregator.rs @@ -33,7 +33,7 @@ impl MirPass for Deaggregator { let (mut lhs, kind, operands) = match stmt.kind { StatementKind::Assign(lhs, box rvalue) => { match rvalue { - Rvalue::Aggregate(kind, operands) => (lhs, kind, operands), + Rvalue::Aggregate(kind, operands) => (lhs.into_tree(), kind, operands), _ => bug!() } } @@ -74,6 +74,7 @@ impl MirPass for Deaggregator { let field = Field::new(active_field_index.unwrap_or(i)); lhs.clone().field(field, ty) }; + let lhs_field = tcx.as_new_place(&lhs_field); Statement { source_info, kind: StatementKind::Assign(lhs_field, box Rvalue::Use(op)), diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index 06e16de8b43bc..78b769b59f088 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -469,7 +469,8 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { assert!(!data.is_cleanup, "DropAndReplace in unwind path not supported"); let assign = Statement { - kind: StatementKind::Assign(location.clone(), box Rvalue::Use(value.clone())), + kind: StatementKind::Assign(self.tcx.as_new_place(&location.clone()), + box Rvalue::Use(value.clone())), source_info: terminator.source_info }; @@ -543,7 +544,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { if let Some(&flag) = self.drop_flags.get(&path) { let span = self.patch.source_info_for_location(self.mir, loc).span; let val = self.constant_bool(span, val.value()); - self.patch.add_assign(loc, Place::Local(flag), val); + self.patch.add_assign(loc, + self.tcx.as_new_place(&Place::Local(flag)), + val); } } @@ -552,7 +555,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { let span = self.patch.source_info_for_location(self.mir, loc).span; let false_ = self.constant_bool(span, false); for flag in self.drop_flags.values() { - self.patch.add_assign(loc, Place::Local(*flag), false_.clone()); + self.patch.add_assign(loc, + self.tcx.as_new_place(&Place::Local(*flag)), + false_.clone()); } } diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index ec0c118634d0f..06f4efa9faa38 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -177,6 +177,7 @@ impl<'a, 'tcx> TransformVisitor<'a, 'tcx> { ty::ParamEnv::empty().and(self.tcx.types.u32) ))), }); + let state = self.tcx.as_new_place(&state); Statement { source_info, kind: StatementKind::Assign(state, box Rvalue::Use(val)), @@ -234,9 +235,10 @@ impl<'a, 'tcx> MutVisitor<'tcx> for TransformVisitor<'a, 'tcx> { if let Some((state_idx, resume, v, drop)) = ret_val { let source_info = data.terminator().source_info; // We must assign the value first in case it gets declared dead below + let place = NeoPlace::local(RETURN_PLACE); data.statements.push(Statement { source_info, - kind: StatementKind::Assign(Place::Local(RETURN_PLACE), + kind: StatementKind::Assign(place, box self.make_state(state_idx, v)), }); let state = if let Some(resume) = resume { // Yield diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index b5b950fba0297..cd16ebca7e5cc 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -455,15 +455,14 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { let temp = LocalDecl::new_temp(ty, callsite.location.span); let tmp = caller_mir.local_decls.push(temp); - let tmp = Place::Local(tmp); - + let tmp = NeoPlace::local(tmp); let stmt = Statement { source_info: callsite.location, kind: StatementKind::Assign(tmp.clone(), box dest) }; caller_mir[callsite.bb] .statements.push(stmt); - tmp.deref() + tmp.into_tree().deref() } else { destination.0 }; @@ -605,9 +604,10 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { let arg_tmp = LocalDecl::new_temp(ty, callsite.location.span); let arg_tmp = caller_mir.local_decls.push(arg_tmp); + let place = NeoPlace::local(arg_tmp); let stmt = Statement { source_info: callsite.location, - kind: StatementKind::Assign(Place::Local(arg_tmp), box arg), + kind: StatementKind::Assign(place, box arg), }; caller_mir[callsite.bb].statements.push(stmt); arg_tmp diff --git a/src/librustc_mir/transform/lower_128bit.rs b/src/librustc_mir/transform/lower_128bit.rs index a1a26fecb9d0a..d32fcfb218e37 100644 --- a/src/librustc_mir/transform/lower_128bit.rs +++ b/src/librustc_mir/transform/lower_128bit.rs @@ -87,7 +87,7 @@ impl Lower128Bit { block.statements.push(Statement { source_info: source_info, kind: StatementKind::Assign( - Place::Local(local), + NeoPlace::local(local), box Rvalue::Cast( CastKind::Misc, rhs, @@ -97,7 +97,7 @@ impl Lower128Bit { } let call_did = check_lang_item_type( - lang_item, &place, &lhs, &rhs, local_decls, tcx); + lang_item, &place.clone().into_tree(), &lhs, &rhs, local_decls, tcx); let bb = BasicBlock::new(cur_len + new_blocks.len()); new_blocks.push(after_call); @@ -109,7 +109,7 @@ impl Lower128Bit { func: Operand::function_handle(tcx, call_did, List::empty(), source_info.span), args: vec![lhs, rhs], - destination: Some((place, bb)), + destination: Some((place.into_tree(), bb)), cleanup: None, from_hir_call: false, }, diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index f2bc9025670c9..98976ad1ca5dd 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -172,12 +172,13 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { fn assign(&mut self, dest: Local, rvalue: Rvalue<'tcx>, span: Span) { let last = self.promoted.basic_blocks().last().unwrap(); let data = &mut self.promoted[last]; + let place = NeoPlace::local(dest); data.statements.push(Statement { source_info: SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE }, - kind: StatementKind::Assign(Place::Local(dest), box rvalue) + kind: StatementKind::Assign(place, box rvalue) }); } @@ -373,7 +374,10 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>, match candidate { Candidate::Ref(Location { block, statement_index }) => { match mir[block].statements[statement_index].kind { - StatementKind::Assign(Place::Local(local), _) => { + StatementKind::Assign(NeoPlace { + base: PlaceBase::Local(local), + elems: &[], + }, _) => { if temps[local] == TempState::PromotedOut { // Already promoted. continue; @@ -420,7 +424,10 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>, for block in mir.basic_blocks_mut() { block.statements.retain(|statement| { match statement.kind { - StatementKind::Assign(Place::Local(index), _) | + StatementKind::Assign(NeoPlace { + base: PlaceBase::Local(index), + elems: &[], + }, _) | StatementKind::StorageLive(index) | StatementKind::StorageDead(index) => { !promoted(index) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 2e55dce4ea93c..b9e42e1c09eb9 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -187,6 +187,70 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { self.add(original); } + /// Assign the current qualification to the given destination. + fn neo_assign(&mut self, dest: &NeoPlace<'tcx>, location: Location) { + trace!("assign: {:?}", dest); + let qualif = self.qualif; + let span = self.span; + let store = |slot: &mut Option| { + if slot.is_some() { + span_bug!(span, "multiple assignments to {:?}", dest); + } + *slot = Some(qualif); + }; + + // Only handle promotable temps in non-const functions. + if self.mode == Mode::Fn { + if let Some(index) = dest.as_local() { + if self.mir.local_kind(index) == LocalKind::Temp + && self.temp_promotion_state[index].is_promotable() { + debug!("store to promotable temp {:?} ({:?})", index, qualif); + store(&mut self.local_qualif[index]); + } + } + return; + } + + // projections are transparent for assignments + // we qualify the entire destination at once, even if just a field would have + // stricter qualification + if !dest.elems.is_empty() { + // Catch more errors in the destination. `visit_place` also checks various + // projection rules like union field access and raw pointer deref + self.visit_neoplace( + dest, + PlaceContext::MutatingUse(MutatingUseContext::Store), + location + ); + } + + let index = match dest.base { + // We treat all locals equal in constants + PlaceBase::Local(index) => index, + PlaceBase::Promoted(..) => bug!("promoteds don't exist yet during promotion"), + PlaceBase::Static(..) => { + // Catch more errors in the destination. `visit_place` also checks that we + // do not try to access statics from constants or try to mutate statics + self.visit_neoplace( + dest, + PlaceContext::MutatingUse(MutatingUseContext::Store), + location + ); + return; + } + }; + debug!("store to var {:?}", index); + match &mut self.local_qualif[index] { + // this is overly restrictive, because even full assignments do not clear the qualif + // While we could special case full assignments, this would be inconsistent with + // aggregates where we overwrite all fields via assignments, which would not get + // that feature. + Some(ref mut qualif) => *qualif = *qualif | self.qualif, + // insert new qualification + qualif @ None => *qualif = Some(self.qualif), + } + } + /// Assign the current qualification to the given destination. fn assign(&mut self, dest: &Place<'tcx>, location: Location) { trace!("assign: {:?}", dest); @@ -1069,13 +1133,13 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { fn visit_assign(&mut self, _: BasicBlock, - dest: &Place<'tcx>, + dest: &NeoPlace<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) { debug!("visit_assign: dest={:?} rvalue={:?} location={:?}", dest, rvalue, location); self.visit_rvalue(rvalue, location); - self.assign(dest, location); + self.neo_assign(dest, location); } fn visit_source_info(&mut self, source_info: &SourceInfo) { diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 85bf1e70ebf42..31ebd9e15fd25 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -209,7 +209,7 @@ fn check_statement( let span = statement.source_info.span; match &statement.kind { StatementKind::Assign(place, rval) => { - check_place(tcx, mir, place, span)?; + check_place(tcx, mir, &place.clone().into_tree(), span)?; check_rvalue(tcx, mir, rval, span) } diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs index c8ef2decf2606..e57aba77e0e20 100644 --- a/src/librustc_mir/transform/remove_noop_landing_pads.rs +++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs @@ -47,7 +47,10 @@ impl RemoveNoopLandingPads { // These are all nops in a landing pad } - StatementKind::Assign(Place::Local(_), box Rvalue::Use(_)) => { + StatementKind::Assign(NeoPlace { + base: PlaceBase::Local(_), + elems: &[], + }, box Rvalue::Use(_)) => { // Writing to a local (e.g., a drop flag) does not // turn a landing pad to a non-nop } diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index 36a6279e50320..2d88a58aed3ab 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -159,7 +159,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, "sanity_check should run before Deaggregator inserts SetDiscriminant"), }; - if place == peek_arg_place { + if &place.clone().into_tree() == peek_arg_place { if let mir::Rvalue::Ref(_, mir::BorrowKind::Shared, ref peeking_at_place) = **rvalue { // Okay, our search is over. match move_data.rev_lookup.find(peeking_at_place) { @@ -186,7 +186,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } - let lhs_mpi = move_data.rev_lookup.find(place); + let lhs_mpi = move_data.rev_lookup.find(&place.clone().into_tree()); debug!("rustc_peek: computing effect on place: {:?} ({:?}) in stmt: {:?}", place, lhs_mpi, stmt); diff --git a/src/librustc_mir/transform/uniform_array_move_out.rs b/src/librustc_mir/transform/uniform_array_move_out.rs index 20eeb6eb236f9..e641710602aa0 100644 --- a/src/librustc_mir/transform/uniform_array_move_out.rs +++ b/src/librustc_mir/transform/uniform_array_move_out.rs @@ -59,7 +59,7 @@ struct UniformArrayMoveOutVisitor<'a, 'tcx: 'a> { impl<'a, 'tcx> Visitor<'tcx> for UniformArrayMoveOutVisitor<'a, 'tcx> { fn visit_assign(&mut self, block: BasicBlock, - dst_place: &Place<'tcx>, + dst_place: &NeoPlace<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) { if let Rvalue::Use(Operand::Move(ref src_place)) = rvalue { @@ -76,7 +76,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UniformArrayMoveOutVisitor<'a, 'tcx> { assert!(size <= u32::max_value() as u64, "uniform array move out doesn't supported for array bigger then u32"); - self.uniform(location, dst_place, proj, item_ty, size as u32); + self.uniform(location, &dst_place.clone().into_tree(), proj, item_ty, size as u32); } } @@ -102,7 +102,7 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> { let temp = self.patch.new_temp(item_ty, self.mir.source_info(location).span); self.patch.add_statement(location, StatementKind::StorageLive(temp)); self.patch.add_assign(location, - Place::Local(temp), + NeoPlace::local(temp), Rvalue::Use( Operand::Move( Place::Projection(box PlaceProjection{ @@ -114,8 +114,9 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> { })))); temp }).collect(); + let neo_dst_place = self.tcx.as_new_place(&dst_place); self.patch.add_assign(location, - dst_place.clone(), + neo_dst_place.clone(), Rvalue::Aggregate(box AggregateKind::Array(item_ty), temps.iter().map( |x| Operand::Move(Place::Local(*x))).collect() @@ -127,8 +128,9 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> { // uniforms statements like _11 = move _2[-1 of 1]; ProjectionElem::ConstantIndex{offset, min_length: _, from_end: true} => { self.patch.make_nop(location); + let neo_dst_place = self.tcx.as_new_place(&dst_place); self.patch.add_assign(location, - dst_place.clone(), + neo_dst_place.clone(), Rvalue::Use( Operand::Move( Place::Projection(box PlaceProjection{ @@ -217,7 +219,7 @@ impl RestoreSubsliceArrayMoveOut { items: &[Option<(&LocalUse, u32, &Place<'tcx>)>], opt_size: Option, patch: &mut MirPatch<'tcx>, - dst_place: &Place<'tcx>) { + dst_place: &NeoPlace<'tcx>) { let opt_src_place = items.first().and_then(|x| *x).map(|x| x.2); if opt_size.is_some() && items.iter().all( @@ -259,7 +261,10 @@ impl RestoreSubsliceArrayMoveOut { if block.statements.len() > location.statement_index { let statement = &block.statements[location.statement_index]; if let StatementKind::Assign( - Place::Local(_), + NeoPlace { + base: PlaceBase::Local(_), + elems: &[], + }, box Rvalue::Use(Operand::Move(Place::Projection(box PlaceProjection{ ref base, elem: ProjectionElem::ConstantIndex{ offset, min_length: _, from_end: false}})))) = statement.kind { @@ -293,7 +298,7 @@ struct RestoreDataCollector { impl<'tcx> Visitor<'tcx> for RestoreDataCollector { fn visit_assign(&mut self, block: BasicBlock, - place: &Place<'tcx>, + place: &NeoPlace<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) { if let Rvalue::Aggregate(box AggregateKind::Array(_), _) = *rvalue { diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 355467f9e73be..a97c0d172b01b 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -487,14 +487,14 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> // discriminant after it is free-ed, because that // way lies only trouble. let discr_ty = adt.repr.discr_type().to_ty(self.tcx()); - let discr = Place::Local(self.new_temp(discr_ty)); + let discr = NeoPlace::local(self.new_temp(discr_ty)); let discr_rv = Rvalue::Discriminant(self.place.clone()); let switch_block = BasicBlockData { statements: vec![self.assign(&discr, discr_rv)], terminator: Some(Terminator { source_info: self.source_info, kind: TerminatorKind::SwitchInt { - discr: Operand::Move(discr), + discr: Operand::Move(discr.into_tree()), switch_ty: discr_ty, values: From::from(values.to_owned()), targets: blocks, @@ -525,7 +525,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> let result = BasicBlockData { statements: vec![self.assign( - &Place::Local(ref_place), + &NeoPlace::local(ref_place), Rvalue::Ref(tcx.types.re_erased, BorrowKind::Mut { allow_two_phase_borrow: false }, self.place.clone()) @@ -601,10 +601,12 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> Rvalue::BinaryOp(BinOp::Add, copy(&Place::Local(cur)), one)) }; + let neo_ptr = tcx.as_new_place(&ptr); + let place = NeoPlace::local(cur); let drop_block = BasicBlockData { statements: vec![ - self.assign(ptr, ptr_next), - self.assign(&Place::Local(cur), cur_next) + self.assign(&neo_ptr, ptr_next), + self.assign(&place, cur_next) ], is_cleanup: unwind.is_cleanup(), terminator: Some(Terminator { @@ -615,9 +617,10 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> }; let drop_block = self.elaborator.patch().new_block(drop_block); + let neo_can_go = tcx.as_new_place(can_go); let loop_block = BasicBlockData { statements: vec![ - self.assign(can_go, Rvalue::BinaryOp(BinOp::Eq, + self.assign(&neo_can_go, Rvalue::BinaryOp(BinOp::Eq, copy(&Place::Local(cur)), copy(length_or_end))) ], @@ -668,13 +671,13 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> let move_ = |place: &Place<'tcx>| Operand::Move(place.clone()); let tcx = self.tcx(); - let size = &Place::Local(self.new_temp(tcx.types.usize)); - let size_is_zero = &Place::Local(self.new_temp(tcx.types.bool)); + let size = &NeoPlace::local(self.new_temp(tcx.types.usize)); + let size_is_zero = &NeoPlace::local(self.new_temp(tcx.types.bool)); let base_block = BasicBlockData { statements: vec![ self.assign(size, Rvalue::NullaryOp(NullOp::SizeOf, ety)), self.assign(size_is_zero, Rvalue::BinaryOp(BinOp::Eq, - move_(size), + move_(&size.clone().into_tree()), self.constant_usize(0))) ], is_cleanup: self.unwind.is_cleanup(), @@ -682,7 +685,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> source_info: self.source_info, kind: TerminatorKind::if_( tcx, - move_(size_is_zero), + move_(&size_is_zero.clone().into_tree()), self.drop_loop_pair(ety, false), self.drop_loop_pair(ety, true) ) @@ -732,28 +735,33 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> let cur = Place::Local(cur); let zero = self.constant_usize(0); let mut drop_block_stmts = vec![]; - drop_block_stmts.push(self.assign(&length, Rvalue::Len(self.place.clone()))); + let neo_length = tcx.as_new_place(&length); + drop_block_stmts.push(self.assign(&neo_length, Rvalue::Len(self.place.clone()))); if ptr_based { let tmp_ty = tcx.mk_mut_ptr(self.place_ty(self.place)); let tmp = Place::Local(self.new_temp(tmp_ty)); // tmp = &mut P; // cur = tmp as *mut T; // end = Offset(cur, len); - drop_block_stmts.push(self.assign(&tmp, Rvalue::Ref( + let neo_tmp = tcx.as_new_place(&tmp); + drop_block_stmts.push(self.assign(&neo_tmp, Rvalue::Ref( tcx.types.re_erased, BorrowKind::Mut { allow_two_phase_borrow: false }, self.place.clone() ))); - drop_block_stmts.push(self.assign(&cur, Rvalue::Cast( + let neo_cur = tcx.as_new_place(&cur); + drop_block_stmts.push(self.assign(&neo_cur, Rvalue::Cast( CastKind::Misc, Operand::Move(tmp), iter_ty ))); - drop_block_stmts.push(self.assign(&length_or_end, + let neo_length_or_end = tcx.as_new_place(&length_or_end); + drop_block_stmts.push(self.assign(&neo_length_or_end, Rvalue::BinaryOp(BinOp::Offset, Operand::Copy(cur), Operand::Move(length) ))); } else { // index = 0 (length already pushed) - drop_block_stmts.push(self.assign(&cur, Rvalue::Use(zero))); + let neo_cur = tcx.as_new_place(&cur); + drop_block_stmts.push(self.assign(&neo_cur, Rvalue::Use(zero))); } let drop_block = self.elaborator.patch().new_block(BasicBlockData { statements: drop_block_stmts, @@ -970,7 +978,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> }) } - fn assign(&self, lhs: &Place<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> { + fn assign(&self, lhs: &NeoPlace<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> { Statement { source_info: self.source_info, kind: StatementKind::Assign(lhs.clone(), box rhs) diff --git a/src/librustc_mir/util/patch.rs b/src/librustc_mir/util/patch.rs index 5a1f94677a1d4..6864dce180d25 100644 --- a/src/librustc_mir/util/patch.rs +++ b/src/librustc_mir/util/patch.rs @@ -119,7 +119,7 @@ impl<'tcx> MirPatch<'tcx> { self.new_statements.push((loc, stmt)); } - pub fn add_assign(&mut self, loc: Location, place: Place<'tcx>, rv: Rvalue<'tcx>) { + pub fn add_assign(&mut self, loc: Location, place: NeoPlace<'tcx>, rv: Rvalue<'tcx>) { self.add_statement(loc, StatementKind::Assign(place, box rv)); }