diff options
| author | bors <bors@rust-lang.org> | 2017-11-28 05:38:19 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-11-28 05:38:19 +0000 |
| commit | 7745a7a8177259cd2ea0b48eaf35dd943eec2896 (patch) | |
| tree | 71bbe2a721b54dd17566f0fc55eb37a068bd50c4 | |
| parent | 3e9a7f7fbbf2898b9f1d60886f92e76370040d83 (diff) | |
| parent | 919ed409b0fbb56bcd6c70ff50bfc9275c4b7701 (diff) | |
| download | rust-7745a7a8177259cd2ea0b48eaf35dd943eec2896.tar.gz rust-7745a7a8177259cd2ea0b48eaf35dd943eec2896.zip | |
Auto merge of #46142 - eddyb:even-mirer-2, r=nikomatsakis
MIR: split Operand::Consume into Copy and Move. By encoding the choice of leaving the source untouched (`Copy`) and invalidating it (`Move`) in MIR, we can express moves of copyable values and have MIR borrow-checking enforce them, *including* ownership transfer of stack locals in calls (when the ABI passes by indirection). Optimizations could turn a "last-use" `Copy` into a `Move`, and the MIR borrow-checker, at least within the confines of safe code, could even do this when the underlying lvalue was borrowed. (However, that last part would be the first time lifetime inference affects code generation, AFAIK). Furthermore, as `Move`s invalidate borrows as well, for any local that is initialized only once, we can ignore borrows that happened before a `Move` and safely reuse/replace its memory storage. This will allow us to perform NRVO in the presence of short-lived borrows, unlike LLVM (currently), and even compute optimal `StorageLive...StorageDead` ranges instead of discarding them.
72 files changed, 438 insertions, 445 deletions
diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index d9244c32dc4..e40d07d936b 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -420,7 +420,10 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Operand<'gcx> { mem::discriminant(self).hash_stable(hcx, hasher); match *self { - mir::Operand::Consume(ref lvalue) => { + mir::Operand::Copy(ref lvalue) => { + lvalue.hash_stable(hcx, hasher); + } + mir::Operand::Move(ref lvalue) => { lvalue.hash_stable(hcx, hasher); } mir::Operand::Constant(ref constant) => { diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 266f60094c3..d5df90a5ea0 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1283,7 +1283,17 @@ pub struct VisibilityScopeData { /// being nested in one another. #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)] pub enum Operand<'tcx> { - Consume(Lvalue<'tcx>), + /// Copy: The value must be available for use afterwards. + /// + /// This implies that the type of the lvalue must be `Copy`; this is true + /// by construction during build, but also checked by the MIR type checker. + Copy(Lvalue<'tcx>), + /// Move: The value (including old borrows of it) will not be used again. + /// + /// Safe for values of all types (modulo future developments towards `?Move`). + /// Correct usage patterns are enforced by the borrow checker for safe code. + /// `Copy` may be converted to `Move` to enable "last-use" optimizations. + Move(Lvalue<'tcx>), Constant(Box<Constant<'tcx>>), } @@ -1292,7 +1302,8 @@ impl<'tcx> Debug for Operand<'tcx> { use self::Operand::*; match *self { Constant(ref a) => write!(fmt, "{:?}", a), - Consume(ref lv) => write!(fmt, "{:?}", lv), + Copy(ref lv) => write!(fmt, "{:?}", lv), + Move(ref lv) => write!(fmt, "move {:?}", lv), } } } @@ -2089,14 +2100,16 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { match *self { - Operand::Consume(ref lval) => Operand::Consume(lval.fold_with(folder)), + Operand::Copy(ref lval) => Operand::Copy(lval.fold_with(folder)), + Operand::Move(ref lval) => Operand::Move(lval.fold_with(folder)), Operand::Constant(ref c) => Operand::Constant(c.fold_with(folder)), } } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { match *self { - Operand::Consume(ref lval) => lval.visit_with(visitor), + Operand::Copy(ref lval) | + Operand::Move(ref lval) => lval.visit_with(visitor), Operand::Constant(ref c) => c.visit_with(visitor) } } diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index d645a00e157..073f4cafc9d 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -230,7 +230,8 @@ impl<'tcx> Operand<'tcx> { where D: HasLocalDecls<'tcx> { match self { - &Operand::Consume(ref l) => l.ty(local_decls, tcx).to_ty(tcx), + &Operand::Copy(ref l) | + &Operand::Move(ref l) => l.ty(local_decls, tcx).to_ty(tcx), &Operand::Constant(ref c) => c.ty, } } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 5f2f5b79cc6..b9db7d236c0 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -611,8 +611,11 @@ macro_rules! make_mir_visitor { operand: & $($mutability)* Operand<'tcx>, location: Location) { match *operand { - Operand::Consume(ref $($mutability)* lvalue) => { - self.visit_lvalue(lvalue, LvalueContext::Consume, location); + Operand::Copy(ref $($mutability)* lvalue) => { + self.visit_lvalue(lvalue, LvalueContext::Copy, location); + } + Operand::Move(ref $($mutability)* lvalue) => { + self.visit_lvalue(lvalue, LvalueContext::Move, location); } Operand::Constant(ref $($mutability)* constant) => { self.visit_constant(constant, location); @@ -679,7 +682,7 @@ macro_rules! make_mir_visitor { self.visit_ty(ty, TyContext::Location(location)); } ProjectionElem::Index(ref $($mutability)* local) => { - self.visit_local(local, LvalueContext::Consume, location); + self.visit_local(local, LvalueContext::Copy, location); } ProjectionElem::ConstantIndex { offset: _, min_length: _, @@ -860,7 +863,8 @@ pub enum LvalueContext<'tcx> { Projection(Mutability), // Consumed as part of an operand - Consume, + Copy, + Move, // Starting and ending a storage live range StorageLive, @@ -913,7 +917,8 @@ impl<'tcx> LvalueContext<'tcx> { LvalueContext::Inspect | LvalueContext::Borrow { kind: BorrowKind::Shared, .. } | LvalueContext::Borrow { kind: BorrowKind::Unique, .. } | - LvalueContext::Projection(Mutability::Not) | LvalueContext::Consume | + LvalueContext::Projection(Mutability::Not) | + LvalueContext::Copy | LvalueContext::Move | LvalueContext::StorageLive | LvalueContext::StorageDead | LvalueContext::Validate => false, } @@ -924,7 +929,8 @@ impl<'tcx> LvalueContext<'tcx> { match *self { LvalueContext::Inspect | LvalueContext::Borrow { kind: BorrowKind::Shared, .. } | LvalueContext::Borrow { kind: BorrowKind::Unique, .. } | - LvalueContext::Projection(Mutability::Not) | LvalueContext::Consume => true, + LvalueContext::Projection(Mutability::Not) | + LvalueContext::Copy | LvalueContext::Move => true, LvalueContext::Borrow { kind: BorrowKind::Mut, .. } | LvalueContext::Store | LvalueContext::Call | LvalueContext::Projection(Mutability::Mut) | LvalueContext::Drop | LvalueContext::StorageLive | LvalueContext::StorageDead | diff --git a/src/librustc_mir/borrow_check.rs b/src/librustc_mir/borrow_check.rs index 9a05bbea487..19d121843cb 100644 --- a/src/librustc_mir/borrow_check.rs +++ b/src/librustc_mir/borrow_check.rs @@ -25,7 +25,7 @@ use rustc_data_structures::indexed_set::{self, IdxSetBuf}; use rustc_data_structures::indexed_vec::{Idx}; use syntax::ast::{self}; -use syntax_pos::{DUMMY_SP, Span}; +use syntax_pos::Span; use dataflow::{do_dataflow}; use dataflow::{MoveDataParamEnv}; @@ -38,7 +38,6 @@ use dataflow::move_paths::{HasMoveData, MoveData, MovePathIndex, LookupResult, M use util::borrowck_errors::{BorrowckErrors, Origin}; use self::MutateMode::{JustWrite, WriteAndRead}; -use self::ConsumeKind::{Consume}; pub fn provide(providers: &mut Providers) { @@ -77,7 +76,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, let id = tcx.hir.as_local_node_id(def_id) .expect("do_mir_borrowck: non-local DefId"); - let move_data: MoveData<'tcx> = match MoveData::gather_moves(input_mir, tcx, param_env) { + let move_data: MoveData<'tcx> = match MoveData::gather_moves(input_mir, tcx) { Ok(move_data) => move_data, Err((move_data, move_errors)) => { for move_error in move_errors { @@ -140,7 +139,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, node_id: id, move_data: &mdpe.move_data, param_env: param_env, - storage_drop_or_dead_error_reported: FxHashSet(), + storage_dead_or_drop_error_reported: FxHashSet(), }; let mut state = InProgress::new(flow_borrows, @@ -159,10 +158,10 @@ pub struct MirBorrowckCtxt<'cx, 'gcx: 'tcx, 'tcx: 'cx> { node_id: ast::NodeId, move_data: &'cx MoveData<'tcx>, param_env: ParamEnv<'gcx>, - /// This field keeps track of when storage drop or dead errors are reported + /// This field keeps track of when storage dead or drop errors are reported /// in order to stop duplicate error reporting and identify the conditions required /// for a "temporary value dropped here while still borrowed" error. See #45360. - storage_drop_or_dead_error_reported: FxHashSet<Local>, + storage_dead_or_drop_error_reported: FxHashSet<Local>, } // (forced to be `pub` due to its use as an associated type below.) @@ -264,14 +263,19 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx flow_state); } StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => { + let context = ContextKind::InlineAsm.new(location); for (o, output) in asm.outputs.iter().zip(outputs) { if o.is_indirect { - self.consume_lvalue(ContextKind::InlineAsm.new(location), - Consume, - (output, span), - flow_state); + // FIXME(eddyb) indirect inline asm outputs should + // be encoeded through MIR lvalue derefs instead. + self.access_lvalue(context, + (output, span), + (Deep, Read(ReadKind::Copy)), + flow_state); + self.check_if_path_is_moved(context, InitializationRequiringAction::Use, + (output, span), flow_state); } else { - self.mutate_lvalue(ContextKind::InlineAsm.new(location), + self.mutate_lvalue(context, (output, span), Deep, if o.is_rw { WriteAndRead } else { JustWrite }, @@ -279,9 +283,7 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx } } for input in inputs { - self.consume_operand(ContextKind::InlineAsm.new(location), - Consume, - (input, span), flow_state); + self.consume_operand(context, (input, span), flow_state); } } StatementKind::EndRegion(ref _rgn) => { @@ -296,15 +298,9 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx } StatementKind::StorageDead(local) => { - if !self.storage_drop_or_dead_error_reported.contains(&local) { - let error_reported = self.access_lvalue(ContextKind::StorageDead.new(location), - (&Lvalue::Local(local), span), - (Shallow(None), Write(WriteKind::StorageDeadOrDrop)), flow_state); - - if error_reported { - self.storage_drop_or_dead_error_reported.insert(local); - } - } + self.access_lvalue(ContextKind::StorageDead.new(location), + (&Lvalue::Local(local), span), + (Shallow(None), Write(WriteKind::StorageDeadOrDrop)), flow_state); } } } @@ -320,13 +316,13 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx match term.kind { TerminatorKind::SwitchInt { ref discr, switch_ty: _, values: _, targets: _ } => { self.consume_operand(ContextKind::SwitchInt.new(loc), - Consume, (discr, span), flow_state); } TerminatorKind::Drop { location: ref drop_lvalue, target: _, unwind: _ } => { - self.consume_lvalue(ContextKind::Drop.new(loc), - ConsumeKind::Drop, - (drop_lvalue, span), flow_state); + self.access_lvalue(ContextKind::Drop.new(loc), + (drop_lvalue, span), + (Deep, Write(WriteKind::StorageDeadOrDrop)), + flow_state); } TerminatorKind::DropAndReplace { location: ref drop_lvalue, value: ref new_value, @@ -338,16 +334,13 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx JustWrite, flow_state); self.consume_operand(ContextKind::DropAndReplace.new(loc), - ConsumeKind::Drop, (new_value, span), flow_state); } TerminatorKind::Call { ref func, ref args, ref destination, cleanup: _ } => { self.consume_operand(ContextKind::CallOperator.new(loc), - Consume, (func, span), flow_state); for arg in args { self.consume_operand(ContextKind::CallOperand.new(loc), - Consume, (arg, span), flow_state); } if let Some((ref dest, _/*bb*/)) = *destination { @@ -360,15 +353,12 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx } TerminatorKind::Assert { ref cond, expected: _, ref msg, target: _, cleanup: _ } => { self.consume_operand(ContextKind::Assert.new(loc), - Consume, (cond, span), flow_state); match *msg { AssertMessage::BoundsCheck { ref len, ref index } => { self.consume_operand(ContextKind::Assert.new(loc), - Consume, (len, span), flow_state); self.consume_operand(ContextKind::Assert.new(loc), - Consume, (index, span), flow_state); } AssertMessage::Math(_/*const_math_err*/) => {} @@ -379,7 +369,7 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx TerminatorKind::Yield { ref value, resume: _, drop: _} => { self.consume_operand(ContextKind::Yield.new(loc), - Consume, (value, span), flow_state); + (value, span), flow_state); } TerminatorKind::Resume | @@ -429,9 +419,6 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx enum MutateMode { JustWrite, WriteAndRead } #[derive(Copy, Clone, PartialEq, Eq, Debug)] -enum ConsumeKind { Drop, Consume } - -#[derive(Copy, Clone, PartialEq, Eq, Debug)] enum Control { Continue, Break } use self::ShallowOrDeep::{Shallow, Deep}; @@ -523,9 +510,21 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { context: Context, lvalue_span: (&Lvalue<'tcx>, Span), kind: (ShallowOrDeep, ReadOrWrite), - flow_state: &InProgress<'cx, 'gcx, 'tcx>) -> bool { + flow_state: &InProgress<'cx, 'gcx, 'tcx>) { let (sd, rw) = kind; + let storage_dead_or_drop_local = match (lvalue_span.0, rw) { + (&Lvalue::Local(local), Write(WriteKind::StorageDeadOrDrop)) => Some(local), + _ => None + }; + + // Check if error has already been reported to stop duplicate reporting. + if let Some(local) = storage_dead_or_drop_local { + if self.storage_dead_or_drop_error_reported.contains(&local) { + return; + } + } + // Check permissions self.check_access_permissions(lvalue_span, rw); @@ -590,7 +589,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } } }); - error_reported + + if error_reported { + if let Some(local) = storage_dead_or_drop_local { + self.storage_dead_or_drop_error_reported.insert(local); + } + } } fn mutate_lvalue(&mut self, @@ -637,7 +641,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Rvalue::Repeat(ref operand, _) | Rvalue::UnaryOp(_/*un_op*/, ref operand) | Rvalue::Cast(_/*cast_kind*/, ref operand, _/*ty*/) => { - self.consume_operand(context, Consume, (operand, span), flow_state) + self.consume_operand(context, (operand, span), flow_state) } Rvalue::Len(ref lvalue) | @@ -655,8 +659,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Rvalue::BinaryOp(_bin_op, ref operand1, ref operand2) | Rvalue::CheckedBinaryOp(_bin_op, ref operand1, ref operand2) => { - self.consume_operand(context, Consume, (operand1, span), flow_state); - self.consume_operand(context, Consume, (operand2, span), flow_state); + self.consume_operand(context, (operand1, span), flow_state); + self.consume_operand(context, (operand2, span), flow_state); } Rvalue::NullaryOp(_op, _ty) => { @@ -669,7 +673,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Rvalue::Aggregate(ref _aggregate_kind, ref operands) => { for operand in operands { - self.consume_operand(context, Consume, (operand, span), flow_state); + self.consume_operand(context, (operand, span), flow_state); } } } @@ -677,83 +681,33 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { fn consume_operand(&mut self, context: Context, - consume_via_drop: ConsumeKind, (operand, span): (&Operand<'tcx>, Span), flow_state: &InProgress<'cx, 'gcx, 'tcx>) { match *operand { - Operand::Consume(ref lvalue) => { - self.consume_lvalue(context, consume_via_drop, (lvalue, span), flow_state) - } - Operand::Constant(_) => {} - } - } - - fn consume_lvalue(&mut self, - context: Context, - consume_via_drop: ConsumeKind, - lvalue_span: (&Lvalue<'tcx>, Span), - flow_state: &InProgress<'cx, 'gcx, 'tcx>) { - let lvalue = lvalue_span.0; - - let ty = lvalue.ty(self.mir, self.tcx).to_ty(self.tcx); - - // Erase the regions in type before checking whether it moves by - // default. There are a few reasons to do this: - // - // - They should not affect the result. - // - It avoids adding new region constraints into the surrounding context, - // which would trigger an ICE, since the infcx will have been "frozen" by - // the NLL region context. - let gcx = self.tcx.global_tcx(); - let erased_ty = gcx.lift(&self.tcx.erase_regions(&ty)).unwrap(); - let moves_by_default = erased_ty.moves_by_default(gcx, self.param_env, DUMMY_SP); - - // Check if error has already been reported to stop duplicate reporting. - let has_storage_drop_or_dead_error_reported = match *lvalue { - Lvalue::Local(local) => self.storage_drop_or_dead_error_reported.contains(&local), - _ => false, - }; - - // If the error has been reported already, then we don't need the access_lvalue call. - if !has_storage_drop_or_dead_error_reported || consume_via_drop != ConsumeKind::Drop { - let error_reported; - - if moves_by_default { - let kind = match consume_via_drop { - ConsumeKind::Drop => WriteKind::StorageDeadOrDrop, - _ => WriteKind::Move, - }; - - // move of lvalue: check if this is move of already borrowed path - error_reported = self.access_lvalue(context, lvalue_span, - (Deep, Write(kind)), flow_state); - } else { + Operand::Copy(ref lvalue) => { // copy of lvalue: check if this is "copy of frozen path" // (FIXME: see check_loans.rs) - error_reported = self.access_lvalue(context, lvalue_span, - (Deep, Read(ReadKind::Copy)), flow_state); - } + self.access_lvalue(context, + (lvalue, span), + (Deep, Read(ReadKind::Copy)), + flow_state); - // If there was an error, then we keep track of it so as to deduplicate it. - // We only do this on ConsumeKind::Drop. - if error_reported && consume_via_drop == ConsumeKind::Drop { - if let Lvalue::Local(local) = *lvalue { - self.storage_drop_or_dead_error_reported.insert(local); - } + // Finally, check if path was already moved. + self.check_if_path_is_moved(context, InitializationRequiringAction::Use, + (lvalue, span), flow_state); } - } + Operand::Move(ref lvalue) => { + // move of lvalue: check if this is move of already borrowed path + self.access_lvalue(context, + (lvalue, span), + (Deep, Write(WriteKind::Move)), + flow_state); - // Finally, check if path was already moved. - match consume_via_drop { - ConsumeKind::Drop => { - // If path is merely being dropped, then we'll already - // check the drop flag to see if it is moved (thus we - // skip this check in that case). - } - ConsumeKind::Consume => { + // Finally, check if path was already moved. self.check_if_path_is_moved(context, InitializationRequiringAction::Use, - lvalue_span, flow_state); + (lvalue, span), flow_state); } + Operand::Constant(_) => {} } } } @@ -1489,22 +1443,22 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { return None; }; - self.tcx - .with_freevars(node_id, |freevars| { - for (v, lv) in freevars.iter().zip(lvs) { - if let Operand::Consume(Lvalue::Local(l)) = *lv { - if local == l { - debug!( - "find_closure_span: found captured local {:?}", - l - ); - return Some(v.span); - } + self.tcx.with_freevars(node_id, |freevars| { + for (v, lv) in freevars.iter().zip(lvs) { + match *lv { + Operand::Copy(Lvalue::Local(l)) | + Operand::Move(Lvalue::Local(l)) if local == l => { + debug!( + "find_closure_span: found captured local {:?}", + l + ); + return Some(v.span); } + _ => {} } - None - }) - .map(|var_span| (args_span, var_span)) + } + None + }).map(|var_span| (args_span, var_span)) } else { None }; diff --git a/src/librustc_mir/build/expr/as_lvalue.rs b/src/librustc_mir/build/expr/as_lvalue.rs index 69d0dd99228..46c15ede4d9 100644 --- a/src/librustc_mir/build/expr/as_lvalue.rs +++ b/src/librustc_mir/build/expr/as_lvalue.rs @@ -70,14 +70,14 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { &len, Rvalue::Len(slice.clone())); this.cfg.push_assign(block, source_info, // lt = idx < len <, Rvalue::BinaryOp(BinOp::Lt, - Operand::Consume(Lvalue::Local(idx)), - Operand::Consume(len.clone()))); + Operand::Copy(Lvalue::Local(idx)), + Operand::Copy(len.clone()))); let msg = AssertMessage::BoundsCheck { - len: Operand::Consume(len), - index: Operand::Consume(Lvalue::Local(idx)) + len: Operand::Move(len), + index: Operand::Copy(Lvalue::Local(idx)) }; - let success = this.assert(block, Operand::Consume(lt), true, + let success = this.assert(block, Operand::Move(lt), true, msg, expr_span); success.and(slice.index(idx)) } diff --git a/src/librustc_mir/build/expr/as_operand.rs b/src/librustc_mir/build/expr/as_operand.rs index ea6e4342098..b9d03cb2d45 100644 --- a/src/librustc_mir/build/expr/as_operand.rs +++ b/src/librustc_mir/build/expr/as_operand.rs @@ -74,7 +74,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { Category::Rvalue(..) => { let operand = unpack!(block = this.as_temp(block, scope, expr)); - block.and(Operand::Consume(Lvalue::Local(operand))) + block.and(Operand::Move(Lvalue::Local(operand))) } } } diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index d17f00b489c..b6f2477a930 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -90,7 +90,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { Rvalue::BinaryOp(BinOp::Eq, arg.clone(), minval)); let err = ConstMathErr::Overflow(Op::Neg); - block = this.assert(block, Operand::Consume(is_min), false, + block = this.assert(block, Operand::Move(is_min), false, AssertMessage::Math(err), expr_span); } block.and(Rvalue::UnaryOp(op, arg)) @@ -117,7 +117,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // initialize the box contents: unpack!(block = this.into(&Lvalue::Local(result).deref(), block, value)); - block.and(Rvalue::Use(Operand::Consume(Lvalue::Local(result)))) + block.and(Rvalue::Use(Operand::Move(Lvalue::Local(result)))) } ExprKind::Cast { source } => { let source = this.hir.mirror(source); @@ -238,7 +238,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { .zip(field_types.into_iter()) .map(|(n, ty)| match fields_map.get(&n) { Some(v) => v.clone(), - None => Operand::Consume(base.clone().field(n, ty)) + None => this.consume_by_copy_or_move(base.clone().field(n, ty)) }) .collect() } else { @@ -325,10 +325,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } }); - block = self.assert(block, Operand::Consume(of), false, + block = self.assert(block, Operand::Move(of), false, AssertMessage::Math(err), span); - block.and(Rvalue::Use(Operand::Consume(val))) + block.and(Rvalue::Use(Operand::Move(val))) } else { if ty.is_integral() && (op == BinOp::Div || op == BinOp::Rem) { // Checking division and remainder is more complex, since we 1. always check @@ -348,7 +348,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { self.cfg.push_assign(block, source_info, &is_zero, Rvalue::BinaryOp(BinOp::Eq, rhs.clone(), zero)); - block = self.assert(block, Operand::Consume(is_zero), false, + block = self.assert(block, Operand::Move(is_zero), false, AssertMessage::Math(zero_err), span); // We only need to check for the overflow in one case: @@ -368,12 +368,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { self.cfg.push_assign(block, source_info, &is_min, Rvalue::BinaryOp(BinOp::Eq, lhs.clone(), min)); - let is_neg_1 = Operand::Consume(is_neg_1); - let is_min = Operand::Consume(is_min); + let is_neg_1 = Operand::Move(is_neg_1); + let is_min = Operand::Move(is_min); self.cfg.push_assign(block, source_info, &of, Rvalue::BinaryOp(BinOp::BitAnd, is_neg_1, is_min)); - block = self.assert(block, Operand::Consume(of), false, + block = self.assert(block, Operand::Move(of), false, AssertMessage::Math(overflow_err), span); } } diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs index ba422a81831..a292d8e5498 100644 --- a/src/librustc_mir/build/expr/as_temp.rs +++ b/src/librustc_mir/build/expr/as_temp.rs @@ -67,7 +67,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { match Category::of(&expr.kind).unwrap() { Category::Lvalue => { let lvalue = unpack!(block = this.as_lvalue(block, expr)); - let rvalue = Rvalue::Use(Operand::Consume(lvalue)); + let rvalue = Rvalue::Use(this.consume_by_copy_or_move(lvalue)); this.cfg.push_assign(block, source_info, &Lvalue::Local(temp), rvalue); } _ => { diff --git a/src/librustc_mir/build/expr/stmt.rs b/src/librustc_mir/build/expr/stmt.rs index 3cfb0ff4010..1878258f908 100644 --- a/src/librustc_mir/build/expr/stmt.rs +++ b/src/librustc_mir/build/expr/stmt.rs @@ -73,7 +73,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // because AssignOp is only legal for Copy types // (overloaded ops should be desugared into a call). let result = unpack!(block = this.build_binary_op(block, op, expr_span, lhs_ty, - Operand::Consume(lhs.clone()), rhs)); + Operand::Copy(lhs.clone()), rhs)); this.cfg.push_assign(block, source_info, &lhs, result); block.unit() diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index b65d859e7d7..fb6458aa115 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -773,7 +773,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { self.schedule_drop_for_binding(binding.var_id, binding.span); let rvalue = match binding.binding_mode { BindingMode::ByValue => - Rvalue::Use(Operand::Consume(binding.source)), + Rvalue::Use(self.consume_by_copy_or_move(binding.source)), BindingMode::ByRef(region, borrow_kind) => Rvalue::Ref(region, borrow_kind, binding.source), }; diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index 02a7bc83f6e..b3a46508cf0 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -215,7 +215,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { Rvalue::Discriminant(lvalue.clone())); assert_eq!(values.len() + 1, targets.len()); self.cfg.terminate(block, source_info, TerminatorKind::SwitchInt { - discr: Operand::Consume(discr), + discr: Operand::Move(discr), switch_ty: discr_ty, values: From::from(values), targets, @@ -233,7 +233,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ConstVal::Bool(false) => vec![false_bb, true_bb], v => span_bug!(test.span, "expected boolean value but got {:?}", v) }; - (ret, TerminatorKind::if_(self.hir.tcx(), Operand::Consume(lvalue.clone()), + (ret, TerminatorKind::if_(self.hir.tcx(), Operand::Copy(lvalue.clone()), true_bb, false_bb)) } else { // The switch may be inexhaustive so we @@ -248,7 +248,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { v.val.to_const_int().expect("switching on integral") ).collect(); (targets.clone(), TerminatorKind::SwitchInt { - discr: Operand::Consume(lvalue.clone()), + discr: Operand::Copy(lvalue.clone()), switch_ty, values: From::from(values), targets, @@ -259,7 +259,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } TestKind::Eq { value, mut ty } => { - let mut val = Operand::Consume(lvalue.clone()); + let mut val = Operand::Copy(lvalue.clone()); // If we're using b"..." as a pattern, we need to insert an // unsizing coercion, as the byte string has the type &[u8; N]. @@ -273,7 +273,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let val_slice = self.temp(ty, test.span); self.cfg.push_assign(block, source_info, &val_slice, Rvalue::Cast(CastKind::Unsize, val, ty)); - val = Operand::Consume(val_slice); + val = Operand::Move(val_slice); } } @@ -288,7 +288,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let slice = self.temp(ty, test.span); self.cfg.push_assign(block, source_info, &slice, Rvalue::Cast(CastKind::Unsize, array, ty)); - Operand::Consume(slice) + Operand::Move(slice) } else { self.literal_operand(test.span, ty, Literal::Value { value @@ -322,7 +322,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let block = self.cfg.start_new_block(); self.cfg.terminate(eq_block, source_info, TerminatorKind::if_(self.hir.tcx(), - Operand::Consume(eq_result), + Operand::Move(eq_result), block, fail)); vec![block, fail] } else { @@ -335,7 +335,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // Test `val` by computing `lo <= val && val <= hi`, using primitive comparisons. let lo = self.literal_operand(test.span, ty.clone(), lo.clone()); let hi = self.literal_operand(test.span, ty.clone(), hi.clone()); - let val = Operand::Consume(lvalue.clone()); + let val = Operand::Copy(lvalue.clone()); let fail = self.cfg.start_new_block(); let block = self.compare(block, fail, test.span, BinOp::Le, lo, val.clone()); @@ -362,14 +362,14 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // result = actual == expected OR result = actual < expected self.cfg.push_assign(block, source_info, &result, Rvalue::BinaryOp(op, - Operand::Consume(actual), - Operand::Consume(expected))); + Operand::Move(actual), + Operand::Move(expected))); // branch based on result let (false_bb, true_bb) = (self.cfg.start_new_block(), self.cfg.start_new_block()); self.cfg.terminate(block, source_info, - TerminatorKind::if_(self.hir.tcx(), Operand::Consume(result), + TerminatorKind::if_(self.hir.tcx(), Operand::Move(result), true_bb, false_bb)); vec![true_bb, false_bb] } @@ -394,7 +394,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // branch based on result let target_block = self.cfg.start_new_block(); self.cfg.terminate(block, source_info, - TerminatorKind::if_(self.hir.tcx(), Operand::Consume(result), + TerminatorKind::if_(self.hir.tcx(), Operand::Move(result), target_block, fail_block)); target_block } diff --git a/src/librustc_mir/build/misc.rs b/src/librustc_mir/build/misc.rs index 1976b70ac0a..1b689aa2132 100644 --- a/src/librustc_mir/build/misc.rs +++ b/src/librustc_mir/build/misc.rs @@ -19,7 +19,7 @@ use rustc::ty::{self, Ty}; use rustc::mir::*; use syntax::ast; -use syntax_pos::Span; +use syntax_pos::{Span, DUMMY_SP}; impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// Add a new temporary value of type `ty` storing the result of @@ -133,4 +133,14 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }); temp } + + pub fn consume_by_copy_or_move(&self, lvalue: Lvalue<'tcx>) -> Operand<'tcx> { + let tcx = self.hir.tcx(); + let ty = lvalue.ty(&self.local_decls, tcx).to_ty(tcx); + if self.hir.type_moves_by_default(ty, DUMMY_SP) { + Operand::Move(lvalue) + } else { + Operand::Copy(lvalue) + } + } } diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index af582b8cf66..b8a9103c816 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -14,8 +14,6 @@ use rustc::mir::tcx::RvalueInitializationState; use rustc::util::nodemap::FxHashMap; use rustc_data_structures::indexed_vec::{IndexVec}; -use syntax::codemap::DUMMY_SP; - use std::collections::hash_map::Entry; use std::mem; @@ -28,16 +26,12 @@ use super::IllegalMoveOriginKind::*; struct MoveDataBuilder<'a, 'gcx: 'tcx, 'tcx: 'a> { mir: &'a Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>, - param_env: ty::ParamEnv<'gcx>, data: MoveData<'tcx>, errors: Vec<MoveError<'tcx>>, } impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> { - fn new(mir: &'a Mir<'tcx>, - tcx: TyCtxt<'a, 'gcx, 'tcx>, - param_env: ty::ParamEnv<'gcx>) - -> Self { + fn new(mir: &'a Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Self { let mut move_paths = IndexVec::new(); let mut path_map = IndexVec::new(); let mut init_path_map = IndexVec::new(); @@ -45,7 +39,6 @@ impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> { MoveDataBuilder { mir, tcx, - param_env, errors: Vec::new(), data: MoveData { moves: IndexVec::new(), @@ -213,12 +206,10 @@ impl<'a, 'gcx, 'tcx> MoveDataBuilder<'a, 'gcx, 'tcx> { } } -pub(super) fn gather_moves<'a, 'gcx, 'tcx>(mir: &Mir<'tcx>, - tcx: TyCtxt<'a, 'gcx, 'tcx>, - param_env: ty::ParamEnv<'gcx>) +pub(super) fn gather_moves<'a, 'gcx, 'tcx>(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Result<MoveData<'tcx>, (MoveData<'tcx>, Vec<MoveError<'tcx>>)> { - let mut builder = MoveDataBuilder::new(mir, tcx, param_env); + let mut builder = MoveDataBuilder::new(mir, tcx); builder.gather_args(); @@ -289,7 +280,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> { } StatementKind::StorageLive(_) => {} StatementKind::StorageDead(local) => { - self.gather_move(&Lvalue::Local(local), true); + self.gather_move(&Lvalue::Local(local)); } StatementKind::SetDiscriminant{ .. } => { span_bug!(stmt.source_info.span, @@ -348,7 +339,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> { TerminatorKind::Unreachable => { } TerminatorKind::Return => { - self.gather_move(&Lvalue::Local(RETURN_POINTER), false); + self.gather_move(&Lvalue::Local(RETURN_POINTER)); } TerminatorKind::Assert { .. } | @@ -361,7 +352,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> { } TerminatorKind::Drop { ref location, target: _, unwind: _ } => { - self.gather_move(location, false); + self.gather_move(location); } TerminatorKind::DropAndReplace { ref location, ref value, .. } => { self.create_move_path(location); @@ -383,25 +374,17 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> { fn gather_operand(&mut self, operand: &Operand<'tcx>) { match *operand { - Operand::Constant(..) => {} // not-a-move - Operand::Consume(ref lval) => { // a move - self.gather_move(lval, false); + Operand::Constant(..) | + Operand::Copy(..) => {} // not-a-move + Operand::Move(ref lval) => { // a move + self.gather_move(lval); } } } - fn gather_move(&mut self, lval: &Lvalue<'tcx>, force: bool) { + fn gather_move(&mut self, lval: &Lvalue<'tcx>) { debug!("gather_move({:?}, {:?})", self.loc, lval); - let tcx = self.builder.tcx; - let gcx = tcx.global_tcx(); - let lv_ty = lval.ty(self.builder.mir, tcx).to_ty(tcx); - let erased_ty = gcx.lift(&tcx.erase_regions(&lv_ty)).unwrap(); - if !force && !erased_ty.moves_by_default(gcx, self.builder.param_env, DUMMY_SP) { - debug!("gather_move({:?}, {:?}) - {:?} is Copy. skipping", self.loc, lval, lv_ty); - return - } - let path = match self.move_path_for(lval) { Ok(path) | Err(MoveError::UnionMove { path }) => path, Err(error @ MoveError::IllegalMove { .. }) => { diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs index 4703dd8a2af..69877367c76 100644 --- a/src/librustc_mir/dataflow/move_paths/mod.rs +++ b/src/librustc_mir/dataflow/move_paths/mod.rs @@ -293,10 +293,8 @@ impl<'tcx> MoveError<'tcx> { } impl<'a, 'gcx, 'tcx> MoveData<'tcx> { - pub fn gather_moves(mir: &Mir<'tcx>, - tcx: TyCtxt<'a, 'gcx, 'tcx>, - param_env: ty::ParamEnv<'gcx>) + pub fn gather_moves(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Result<Self, (Self, Vec<MoveError<'tcx>>)> { - builder::gather_moves(mir, tcx, param_env) + builder::gather_moves(mir, tcx) } } diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index b1f4b849b89..306b41714a5 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -252,6 +252,10 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { pub fn check_overflow(&self) -> bool { self.check_overflow } + + pub fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool { + self.infcx.type_moves_by_default(self.param_env, ty, span) + } } fn lint_level_for_hir_id(tcx: TyCtxt, mut id: ast::NodeId) -> ast::NodeId { diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 0fa47d80999..119cd35910f 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -385,7 +385,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { let ret_statement = self.make_statement( StatementKind::Assign( Lvalue::Local(RETURN_POINTER), - Rvalue::Use(Operand::Consume(rcvr)) + Rvalue::Use(Operand::Copy(rcvr)) ) ); self.block(vec![ret_statement], TerminatorKind::Return, false); @@ -448,7 +448,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { // `let loc = Clone::clone(ref_loc);` self.block(vec![statement], TerminatorKind::Call { func, - args: vec![Operand::Consume(ref_loc)], + args: vec![Operand::Move(ref_loc)], destination: Some((loc.clone(), next)), cleanup: Some(cleanup), }, false); @@ -470,14 +470,14 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { let compute_cond = self.make_statement( StatementKind::Assign( cond.clone(), - Rvalue::BinaryOp(BinOp::Ne, Operand::Consume(end), Operand::Consume(beg)) + Rvalue::BinaryOp(BinOp::Ne, Operand::Copy(end), Operand::Copy(beg)) ) ); // `if end != beg { goto loop_body; } else { goto loop_end; }` self.block( vec![compute_cond], - TerminatorKind::if_(tcx, Operand::Consume(cond), loop_body, loop_end), + TerminatorKind::if_(tcx, Operand::Move(cond), loop_body, loop_end), is_cleanup ); } @@ -547,7 +547,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { self.make_statement( StatementKind::Assign( ret_field, - Rvalue::Use(Operand::Consume(cloned)) + Rvalue::Use(Operand::Move(cloned)) ) ), self.make_statement( @@ -555,7 +555,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { Lvalue::Local(beg), Rvalue::BinaryOp( BinOp::Add, - Operand::Consume(Lvalue::Local(beg)), + Operand::Copy(Lvalue::Local(beg)), Operand::Constant(self.make_usize(1)) ) ) @@ -568,7 +568,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { let ret_statement = self.make_statement( StatementKind::Assign( Lvalue::Local(RETURN_POINTER), - Rvalue::Use(Operand::Consume(ret.clone())), + Rvalue::Use(Operand::Move(ret.clone())), ) ); self.block(vec![ret_statement], TerminatorKind::Return, false); @@ -611,7 +611,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { Lvalue::Local(beg), Rvalue::BinaryOp( BinOp::Add, - Operand::Consume(Lvalue::Local(beg)), + Operand::Copy(Lvalue::Local(beg)), Operand::Constant(self.make_usize(1)) ) ) @@ -666,7 +666,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { Lvalue::Local(RETURN_POINTER), Rvalue::Aggregate( box kind, - returns.into_iter().map(Operand::Consume).collect() + returns.into_iter().map(Operand::Move).collect() ) ) ); @@ -705,8 +705,8 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let mut statements = vec![]; let rcvr = match rcvr_adjustment { - Adjustment::Identity => Operand::Consume(rcvr_l), - Adjustment::Deref => Operand::Consume(rcvr_l.deref()), + Adjustment::Identity => Operand::Move(rcvr_l), + Adjustment::Deref => Operand::Copy(rcvr_l.deref()), Adjustment::RefMut => { // let rcvr = &mut rcvr; let ref_rcvr = local_decls.push(temp_decl( @@ -724,7 +724,7 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Rvalue::Ref(tcx.types.re_erased, BorrowKind::Mut, rcvr_l) ) }); - Operand::Consume(Lvalue::Local(ref_rcvr)) + Operand::Move(Lvalue::Local(ref_rcvr)) } }; @@ -750,11 +750,11 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if let Some(untuple_args) = untuple_args { args.extend(untuple_args.iter().enumerate().map(|(i, ity)| { let arg_lv = Lvalue::Local(Local::new(1+1)); - Operand::Consume(arg_lv.field(Field::new(i), *ity)) + Operand::Move(arg_lv.field(Field::new(i), *ity)) })); } else { args.extend((1..sig.inputs().len()).map(|i| { - Operand::Consume(Lvalue::Local(Local::new(1+i))) + Operand::Move(Lvalue::Local(Local::new(1+i))) })); } @@ -868,7 +868,7 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>, Rvalue::Aggregate( box AggregateKind::Adt(adt_def, variant_no, substs, None), (1..sig.inputs().len()+1).map(|i| { - Operand::Consume(Lvalue::Local(Local::new(i))) + Operand::Move(Lvalue::Local(Local::new(i))) }).collect() ) ) 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 297bc76d472..2cb8cb60e07 100644 --- a/src/librustc_mir/transform/add_moves_for_packed_drops.rs +++ b/src/librustc_mir/transform/add_moves_for_packed_drops.rs @@ -132,7 +132,7 @@ fn add_move_for_packed_drop<'a, 'tcx>( patch.add_statement( loc, StatementKind::StorageLive(temp)); patch.add_assign(loc, Lvalue::Local(temp), - Rvalue::Use(Operand::Consume(location.clone()))); + Rvalue::Use(Operand::Move(location.clone()))); patch.patch_terminator(loc.block, TerminatorKind::Drop { location: Lvalue::Local(temp), target: storage_dead_block, diff --git a/src/librustc_mir/transform/add_validation.rs b/src/librustc_mir/transform/add_validation.rs index c6f2154eaa4..6021955004e 100644 --- a/src/librustc_mir/transform/add_validation.rs +++ b/src/librustc_mir/transform/add_validation.rs @@ -260,7 +260,8 @@ impl MirPass for AddValidation { .chain( args.iter().filter_map(|op| { match op { - &Operand::Consume(ref lval) => + &Operand::Copy(ref lval) | + &Operand::Move(ref lval) => Some(lval_to_operand(lval.clone())), &Operand::Constant(..) => { None }, } @@ -353,14 +354,17 @@ impl MirPass for AddValidation { block_data.statements.insert(i, release_stmt); } // Casts can change what validation does (e.g. unsizing) - StatementKind::Assign(_, Rvalue::Cast(kind, Operand::Consume(_), _)) + StatementKind::Assign(_, Rvalue::Cast(kind, Operand::Copy(_), _)) | + StatementKind::Assign(_, Rvalue::Cast(kind, Operand::Move(_), _)) if kind != CastKind::Misc => { // Due to a lack of NLL; we can't capture anything directly here. // Instead, we have to re-match and clone there. let (dest_lval, src_lval) = match block_data.statements[i].kind { StatementKind::Assign(ref dest_lval, - Rvalue::Cast(_, Operand::Consume(ref src_lval), _)) => + Rvalue::Cast(_, Operand::Copy(ref src_lval), _)) | + StatementKind::Assign(ref dest_lval, + Rvalue::Cast(_, Operand::Move(ref src_lval), _)) => { (dest_lval.clone(), src_lval.clone()) }, diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs index 2966290c296..30048639589 100644 --- a/src/librustc_mir/transform/copy_prop.rs +++ b/src/librustc_mir/transform/copy_prop.rs @@ -126,7 +126,8 @@ impl MirPass for CopyPropagation { StatementKind::Assign(Lvalue::Local(local), Rvalue::Use(ref operand)) if local == dest_local => { let maybe_action = match *operand { - Operand::Consume(ref src_lvalue) => { + Operand::Copy(ref src_lvalue) | + Operand::Move(ref src_lvalue) => { Action::local_copy(&mir, &def_use_analysis, src_lvalue) } Operand::Constant(ref src_constant) => { @@ -173,7 +174,11 @@ fn eliminate_self_assignments<'tcx>( match stmt.kind { StatementKind::Assign( Lvalue::Local(local), - Rvalue::Use(Operand::Consume(Lvalue::Local(src_local))), + Rvalue::Use(Operand::Copy(Lvalue::Local(src_local))), + ) | + StatementKind::Assign( + Lvalue::Local(local), + Rvalue::Use(Operand::Move(Lvalue::Local(src_local))), ) if local == dest_local && dest_local == src_local => {} _ => { continue; @@ -351,7 +356,8 @@ impl<'tcx> MutVisitor<'tcx> for ConstantPropagationVisitor<'tcx> { self.super_operand(operand, location); match *operand { - Operand::Consume(Lvalue::Local(local)) if local == self.dest_local => {} + Operand::Copy(Lvalue::Local(local)) | + Operand::Move(Lvalue::Local(local)) if local == self.dest_local => {} _ => return, } diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index c24256cc92c..6f94bd1f88f 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -50,7 +50,7 @@ impl MirPass for ElaborateDrops { _ => return } let param_env = tcx.param_env(src.def_id); - let move_data = MoveData::gather_moves(mir, tcx, param_env).unwrap(); + let move_data = MoveData::gather_moves(mir, tcx).unwrap(); let elaborate_patch = { let mir = &*mir; let env = MoveDataParamEnv { @@ -278,7 +278,7 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> { } fn get_drop_flag(&mut self, path: Self::Path) -> Option<Operand<'tcx>> { - self.ctxt.drop_flag(path).map(Operand::Consume) + self.ctxt.drop_flag(path).map(Operand::Copy) } } diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 43635bcb631..fe7ff326f49 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -230,7 +230,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for TransformVisitor<'a, 'tcx> { let ret_val = match data.terminator().kind { TerminatorKind::Return => Some((1, None, - Operand::Consume(Lvalue::Local(self.new_ret_local)), + Operand::Move(Lvalue::Local(self.new_ret_local)), None)), TerminatorKind::Yield { ref value, resume, drop } => Some((0, Some(resume), @@ -452,7 +452,7 @@ fn insert_switch<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let default_block = insert_term_block(mir, default); let switch = TerminatorKind::SwitchInt { - discr: Operand::Consume(transform.make_field(transform.state_field, tcx.types.u32)), + discr: Operand::Copy(transform.make_field(transform.state_field, tcx.types.u32)), switch_ty: tcx.types.u32, values: Cow::from(cases.iter().map(|&(i, _)| ConstInt::U32(i)).collect::<Vec<_>>()), targets: cases.iter().map(|&(_, d)| d).chain(once(default_block)).collect(), diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 35cade25f77..844459930b8 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -456,7 +456,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { // needs to generate the cast. // FIXME: we should probably just generate correct MIR in the first place... - let arg = if let Operand::Consume(ref lval) = args[0] { + let arg = if let Operand::Move(ref lval) = args[0] { lval.clone() } else { bug!("Constant arg to \"box_free\""); @@ -509,7 +509,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { } fn cast_box_free_arg(&self, arg: Lvalue<'tcx>, ptr_ty: Ty<'tcx>, - callsite: &CallSite<'tcx>, caller_mir: &mut Mir<'tcx>) -> Operand<'tcx> { + callsite: &CallSite<'tcx>, caller_mir: &mut Mir<'tcx>) -> Local { let arg = Rvalue::Ref( self.tcx.types.re_erased, BorrowKind::Mut, @@ -535,21 +535,20 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { }; let ptr_ty = self.tcx.mk_mut_ptr(pointee_ty); - let raw_ptr = Rvalue::Cast(CastKind::Misc, Operand::Consume(ref_tmp), ptr_ty); + let raw_ptr = Rvalue::Cast(CastKind::Misc, Operand::Move(ref_tmp), ptr_ty); let cast_tmp = LocalDecl::new_temp(ptr_ty, callsite.location.span); let cast_tmp = caller_mir.local_decls.push(cast_tmp); - let cast_tmp = Lvalue::Local(cast_tmp); let cast_stmt = Statement { source_info: callsite.location, - kind: StatementKind::Assign(cast_tmp.clone(), raw_ptr) + kind: StatementKind::Assign(Lvalue::Local(cast_tmp), raw_ptr) }; caller_mir[callsite.bb] .statements.push(cast_stmt); - Operand::Consume(cast_tmp) + cast_tmp } fn make_call_args( @@ -557,7 +556,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { args: Vec<Operand<'tcx>>, callsite: &CallSite<'tcx>, caller_mir: &mut Mir<'tcx>, - ) -> Vec<Operand<'tcx>> { + ) -> Vec<Local> { let tcx = self.tcx; // There is a bit of a mismatch between the *caller* of a closure and the *callee*. @@ -589,6 +588,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { let tuple = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_mir); assert!(args.next().is_none()); + let tuple = Lvalue::Local(tuple); let tuple_tys = if let ty::TyTuple(s, _) = tuple.ty(caller_mir, tcx).to_ty(tcx).sty { s } else { @@ -596,23 +596,22 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { }; // The `closure_ref` in our example above. - let closure_ref_arg = iter::once(Operand::Consume(self_)); + let closure_ref_arg = iter::once(self_); // The `tmp0`, `tmp1`, and `tmp2` in our example abonve. let tuple_tmp_args = tuple_tys.iter().enumerate().map(|(i, ty)| { // This is e.g. `tuple_tmp.0` in our example above. - let tuple_field = Operand::Consume(tuple.clone().field(Field::new(i), ty)); + let tuple_field = Operand::Move(tuple.clone().field(Field::new(i), ty)); // Spill to a local to make e.g. `tmp0`. - let tmp = self.create_temp_if_necessary(tuple_field, callsite, caller_mir); - Operand::Consume(tmp) + self.create_temp_if_necessary(tuple_field, callsite, caller_mir) }); closure_ref_arg.chain(tuple_tmp_args).collect() } else { args.into_iter() - .map(|a| Operand::Consume(self.create_temp_if_necessary(a, callsite, caller_mir))) + .map(|a| self.create_temp_if_necessary(a, callsite, caller_mir)) .collect() } } @@ -624,14 +623,14 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { arg: Operand<'tcx>, callsite: &CallSite<'tcx>, caller_mir: &mut Mir<'tcx>, - ) -> Lvalue<'tcx> { + ) -> Local { // FIXME: Analysis of the usage of the arguments to avoid // unnecessary temporaries. - if let Operand::Consume(Lvalue::Local(local)) = arg { + if let Operand::Move(Lvalue::Local(local)) = arg { if caller_mir.local_kind(local) == LocalKind::Temp { // Reuse the operand if it's a temporary already - return Lvalue::Local(local); + return local; } } @@ -643,11 +642,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 arg_tmp = Lvalue::Local(arg_tmp); let stmt = Statement { source_info: callsite.location, - kind: StatementKind::Assign(arg_tmp.clone(), arg), + kind: StatementKind::Assign(Lvalue::Local(arg_tmp), arg), }; caller_mir[callsite.bb].statements.push(stmt); arg_tmp @@ -693,7 +691,7 @@ fn subst_and_normalize<'a, 'tcx: 'a>( */ struct Integrator<'a, 'tcx: 'a> { block_idx: usize, - args: &'a [Operand<'tcx>], + args: &'a [Local], local_map: IndexVec<Local, Local>, scope_map: IndexVec<VisibilityScope, VisibilityScope>, promoted_map: IndexVec<Promoted, Promoted>, @@ -710,15 +708,6 @@ impl<'a, 'tcx> Integrator<'a, 'tcx> { debug!("Updating target `{:?}`, new: `{:?}`", tgt, new); new } - - fn arg_index(&self, arg: Local) -> Option<usize> { - let idx = arg.index(); - if idx > 0 && idx <= self.args.len() { - Some(idx - 1) - } else { - None - } - } } impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { @@ -737,13 +726,8 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { } let idx = local.index() - 1; if idx < self.args.len() { - match self.args[idx] { - Operand::Consume(Lvalue::Local(l)) => { - *local = l; - return; - }, - ref op => bug!("Arg operand `{:?}` is {:?}, not local", idx, op) - } + *local = self.args[idx]; + return; } *local = self.local_map[Local::new(idx - self.args.len())]; } @@ -760,17 +744,6 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { } } - fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) { - if let Operand::Consume(Lvalue::Local(arg)) = *operand { - if let Some(idx) = self.arg_index(arg) { - let new_arg = self.args[idx].clone(); - *operand = new_arg; - return; - } - } - self.super_operand(operand, location); - } - fn visit_basic_block_data(&mut self, block: BasicBlock, data: &mut BasicBlockData<'tcx>) { self.in_cleanup_block = data.is_cleanup; self.super_basic_block_data(block, data); diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs index d66d4b14d69..b45db18eff5 100644 --- a/src/librustc_mir/transform/instcombine.rs +++ b/src/librustc_mir/transform/instcombine.rs @@ -59,7 +59,7 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> { } _ => bug!("Detected `&*` but didn't find `&*`!"), }; - *rvalue = Rvalue::Use(Operand::Consume(new_lvalue)) + *rvalue = Rvalue::Use(Operand::Copy(new_lvalue)) } if let Some(constant) = self.optimizations.arrays_lengths.remove(&location) { diff --git a/src/librustc_mir/transform/lower_128bit.rs b/src/librustc_mir/transform/lower_128bit.rs index 9dc5fdadbb1..26621afaba4 100644 --- a/src/librustc_mir/transform/lower_128bit.rs +++ b/src/librustc_mir/transform/lower_128bit.rs @@ -105,7 +105,7 @@ impl Lower128Bit { rhs, rhs_override_ty.unwrap())), }); - rhs = Operand::Consume(Lvalue::Local(local)); + rhs = Operand::Move(Lvalue::Local(local)); } let call_did = check_lang_item_type( @@ -237,4 +237,4 @@ fn item_for_checked_op(bin_op: BinOp, is_signed: bool) -> Option<(LangItem, RhsK _ => bug!("That should be all the checked ones?"), }; Some(i) -} \ No newline at end of file +} diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 97e80de96c5..555f0a32798 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -519,7 +519,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) { match *operand { - Operand::Consume(ref lvalue) => { + Operand::Copy(ref lvalue) | + Operand::Move(ref lvalue) => { self.nest(|this| { this.super_operand(operand, location); this.try_consume(); @@ -872,10 +873,14 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { self.const_fn_arg_vars.insert(index.index()) { // Direct use of an argument is permitted. - if let Rvalue::Use(Operand::Consume(Lvalue::Local(local))) = *rvalue { - if self.mir.local_kind(local) == LocalKind::Arg { - return; + match *rvalue { + Rvalue::Use(Operand::Copy(Lvalue::Local(local))) | + Rvalue::Use(Operand::Move(Lvalue::Local(local))) => { + if self.mir.local_kind(local) == LocalKind::Arg { + return; + } } + _ => {} } // Avoid a generic error for other uses of arguments. diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index 32d4a14c7f7..cc8a6e66da1 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -45,7 +45,7 @@ impl MirPass for SanityCheck { let attributes = tcx.get_attrs(def_id); let param_env = tcx.param_env(def_id); - let move_data = MoveData::gather_moves(mir, tcx, param_env).unwrap(); + let move_data = MoveData::gather_moves(mir, tcx).unwrap(); let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env }; let dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len()); let flow_inits = @@ -124,7 +124,8 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; assert!(args.len() == 1); let peek_arg_lval = match args[0] { - mir::Operand::Consume(ref lval @ mir::Lvalue::Local(_)) => Some(lval), + mir::Operand::Copy(ref lval @ mir::Lvalue::Local(_)) | + mir::Operand::Move(ref lval @ mir::Lvalue::Local(_)) => Some(lval), _ => None, }; diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index ade5cf8b70c..6cbc8b7e619 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -20,7 +20,7 @@ use rustc::ty::{self, Ty, TyCtxt, TypeVariants}; use rustc::middle::const_val::ConstVal; use rustc::mir::*; use rustc::mir::tcx::LvalueTy; -use rustc::mir::visit::Visitor; +use rustc::mir::visit::{LvalueContext, Visitor}; use std::fmt; use syntax::ast; use syntax_pos::{Span, DUMMY_SP}; @@ -107,10 +107,10 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> { fn visit_lvalue( &mut self, lvalue: &Lvalue<'tcx>, - _context: visit::LvalueContext, + context: LvalueContext, location: Location, ) { - self.sanitize_lvalue(lvalue, location); + self.sanitize_lvalue(lvalue, location, context); } fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) { @@ -164,9 +164,13 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { } } - fn sanitize_lvalue(&mut self, lvalue: &Lvalue<'tcx>, location: Location) -> LvalueTy<'tcx> { + fn sanitize_lvalue(&mut self, + lvalue: &Lvalue<'tcx>, + location: Location, + context: LvalueContext) + -> LvalueTy<'tcx> { debug!("sanitize_lvalue: {:?}", lvalue); - match *lvalue { + let lvalue_ty = match *lvalue { Lvalue::Local(index) => LvalueTy::Ty { ty: self.mir.local_decls[index].ty, }, @@ -189,7 +193,12 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { LvalueTy::Ty { ty: sty } } Lvalue::Projection(ref proj) => { - let base_ty = self.sanitize_lvalue(&proj.base, location); + let base_context = if context.is_mutating_use() { + LvalueContext::Projection(Mutability::Mut) + } else { + LvalueContext::Projection(Mutability::Not) + }; + let base_ty = self.sanitize_lvalue(&proj.base, location, base_context); if let LvalueTy::Ty { ty } = base_ty { if ty.references_error() { assert!(self.errors_reported); @@ -200,7 +209,15 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { } self.sanitize_projection(base_ty, &proj.elem, lvalue, location) } + }; + if let LvalueContext::Copy = context { + let ty = lvalue_ty.to_ty(self.tcx()); + if self.cx.infcx.type_moves_by_default(self.cx.param_env, ty, DUMMY_SP) { + span_mirbug!(self, lvalue, + "attempted copy of non-Copy type ({:?})", ty); + } } + lvalue_ty } fn sanitize_projection( diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 1852712a083..bb8dbd64c36 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -498,7 +498,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> terminator: Some(Terminator { source_info: self.source_info, kind: TerminatorKind::SwitchInt { - discr: Operand::Consume(discr), + discr: Operand::Move(discr), switch_ty: discr_ty, values: From::from(values.to_owned()), targets: blocks, @@ -536,7 +536,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> kind: TerminatorKind::Call { func: Operand::function_handle(tcx, drop_fn.def_id, substs, self.source_info.span), - args: vec![Operand::Consume(Lvalue::Local(ref_lvalue))], + args: vec![Operand::Move(Lvalue::Local(ref_lvalue))], destination: Some((unit_temp, succ)), cleanup: unwind.into_option(), }, @@ -572,7 +572,8 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> ptr_based: bool) -> BasicBlock { - let use_ = |lv: &Lvalue<'tcx>| Operand::Consume(lv.clone()); + let copy = |lv: &Lvalue<'tcx>| Operand::Copy(lv.clone()); + let move_ = |lv: &Lvalue<'tcx>| Operand::Move(lv.clone()); let tcx = self.tcx(); let ref_ty = tcx.mk_ref(tcx.types.re_erased, ty::TypeAndMut { @@ -584,14 +585,14 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> let one = self.constant_usize(1); let (ptr_next, cur_next) = if ptr_based { - (Rvalue::Use(use_(&Lvalue::Local(cur))), - Rvalue::BinaryOp(BinOp::Offset, use_(&Lvalue::Local(cur)), one)) + (Rvalue::Use(copy(&Lvalue::Local(cur))), + Rvalue::BinaryOp(BinOp::Offset, copy(&Lvalue::Local(cur)), one)) } else { (Rvalue::Ref( tcx.types.re_erased, BorrowKind::Mut, self.lvalue.clone().index(cur)), - Rvalue::BinaryOp(BinOp::Add, use_(&Lvalue::Local(cur)), one)) + Rvalue::BinaryOp(BinOp::Add, copy(&Lvalue::Local(cur)), one)) }; let drop_block = BasicBlockData { @@ -611,13 +612,13 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> let loop_block = BasicBlockData { statements: vec![ self.assign(can_go, Rvalue::BinaryOp(BinOp::Eq, - use_(&Lvalue::Local(cur)), - use_(length_or_end))) + copy(&Lvalue::Local(cur)), + copy(length_or_end))) ], is_cleanup: unwind.is_cleanup(), terminator: Some(Terminator { source_info: self.source_info, - kind: TerminatorKind::if_(tcx, use_(can_go), succ, drop_block) + kind: TerminatorKind::if_(tcx, move_(can_go), succ, drop_block) }) }; let loop_block = self.elaborator.patch().new_block(loop_block); @@ -642,14 +643,14 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> let tcx = self.tcx(); - let use_ = |lv: &Lvalue<'tcx>| Operand::Consume(lv.clone()); + let move_ = |lv: &Lvalue<'tcx>| Operand::Move(lv.clone()); let size = &Lvalue::Local(self.new_temp(tcx.types.usize)); let size_is_zero = &Lvalue::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, - use_(size), + move_(size), self.constant_usize(0))) ], is_cleanup: self.unwind.is_cleanup(), @@ -657,7 +658,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> source_info: self.source_info, kind: TerminatorKind::if_( tcx, - use_(size_is_zero), + move_(size_is_zero), self.drop_loop_pair(ety, false), self.drop_loop_pair(ety, true) ) @@ -718,11 +719,11 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> tcx.types.re_erased, BorrowKind::Mut, self.lvalue.clone() ))); drop_block_stmts.push(self.assign(&cur, Rvalue::Cast( - CastKind::Misc, Operand::Consume(tmp.clone()), iter_ty + CastKind::Misc, Operand::Move(tmp.clone()), iter_ty ))); drop_block_stmts.push(self.assign(&length_or_end, Rvalue::BinaryOp(BinOp::Offset, - Operand::Consume(cur.clone()), Operand::Consume(length.clone()) + Operand::Copy(cur.clone()), Operand::Move(length.clone()) ))); } else { // index = 0 (length already pushed) @@ -854,7 +855,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> let call = TerminatorKind::Call { func: Operand::function_handle(tcx, free_func, substs, self.source_info.span), - args: vec![Operand::Consume(self.lvalue.clone())], + args: vec![Operand::Move(self.lvalue.clone())], destination: Some((unit_temp, target)), cleanup: None }; // FIXME(#6393) diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index 4b165a71c81..9afd5a1483f 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -273,7 +273,8 @@ impl<'tcx> Visitor<'tcx> for DefsUsesVisitor { LvalueContext::Borrow { .. } | LvalueContext::Inspect | - LvalueContext::Consume | + LvalueContext::Copy | + LvalueContext::Move | LvalueContext::Validate => { if self.mode.include_regular_use { self.defs_uses.add_use(local); diff --git a/src/librustc_passes/mir_stats.rs b/src/librustc_passes/mir_stats.rs index ab41ad1e099..6054d6c2410 100644 --- a/src/librustc_passes/mir_stats.rs +++ b/src/librustc_passes/mir_stats.rs @@ -181,7 +181,8 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> { location: Location) { self.record("Operand", operand); self.record(match *operand { - Operand::Consume(..) => "Operand::Consume", + Operand::Copy(..) => "Operand::Copy", + Operand::Move(..) => "Operand::Move", Operand::Constant(..) => "Operand::Constant", }, operand); self.super_operand(operand, location); diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs index 223379527c9..77f607e5514 100644 --- a/src/librustc_trans/mir/analyze.rs +++ b/src/librustc_trans/mir/analyze.rs @@ -121,7 +121,7 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> { // box_free(x) shares with `drop x` the property that it // is not guaranteed to be statically dominated by the // definition of x, so x must always be in an alloca. - if let mir::Operand::Consume(ref lvalue) = args[0] { + if let mir::Operand::Move(ref lvalue) = args[0] { self.visit_lvalue(lvalue, LvalueContext::Drop, location); } } @@ -140,7 +140,11 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> { if let mir::Lvalue::Projection(ref proj) = *lvalue { // Allow uses of projections that are ZSTs or from scalar fields. - if let LvalueContext::Consume = context { + let is_consume = match context { + LvalueContext::Copy | LvalueContext::Move => true, + _ => false + }; + if is_consume { let base_ty = proj.base.ty(self.cx.mir, ccx.tcx()); let base_ty = self.cx.monomorphize(&base_ty); @@ -154,10 +158,10 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> { if let mir::ProjectionElem::Field(..) = proj.elem { let layout = ccx.layout_of(base_ty.to_ty(ccx.tcx())); if layout.is_llvm_immediate() || layout.is_llvm_scalar_pair() { - // Recurse as a `Consume` instead of `Projection`, + // Recurse with the same context, instead of `Projection`, // potentially stopping at non-operand projections, // which would trigger `mark_as_lvalue` on locals. - self.visit_lvalue(&proj.base, LvalueContext::Consume, location); + self.visit_lvalue(&proj.base, context, location); return; } } @@ -165,7 +169,7 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> { // A deref projection only reads the pointer, never needs the lvalue. if let mir::ProjectionElem::Deref = proj.elem { - return self.visit_lvalue(&proj.base, LvalueContext::Consume, location); + return self.visit_lvalue(&proj.base, LvalueContext::Copy, location); } } @@ -184,7 +188,8 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> { LvalueContext::StorageLive | LvalueContext::StorageDead | LvalueContext::Validate | - LvalueContext::Consume => {} + LvalueContext::Copy | + LvalueContext::Move => {} LvalueContext::Inspect | LvalueContext::Store | diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index f43eba36a82..61811a62c66 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -517,7 +517,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { // promotes any complex rvalues to constants. if i == 2 && intrinsic.unwrap().starts_with("simd_shuffle") { match *arg { - mir::Operand::Consume(_) => { + mir::Operand::Copy(_) | + mir::Operand::Move(_) => { span_bug!(span, "shuffle indices must be constant"); } mir::Operand::Constant(ref constant) => { @@ -573,10 +574,14 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { // The callee needs to own the argument memory if we pass it // by-ref, so make a local copy of non-immediate constants. - if let (&mir::Operand::Constant(_), Ref(..)) = (arg, op.val) { - let tmp = LvalueRef::alloca(&bcx, op.layout, "const"); - op.val.store(&bcx, tmp); - op.val = Ref(tmp.llval, tmp.alignment); + match (arg, op.val) { + (&mir::Operand::Copy(_), Ref(..)) | + (&mir::Operand::Constant(_), Ref(..)) => { + let tmp = LvalueRef::alloca(&bcx, op.layout, "const"); + op.val.store(&bcx, tmp); + op.val = Ref(tmp.llval, tmp.alignment); + } + _ => {} } self.trans_argument(&bcx, op, &mut llargs, &fn_ty.args[i]); diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 8c013330e5b..e38af774a51 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -505,7 +505,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { (Base::Value(llprojected), llextra) } mir::ProjectionElem::Index(index) => { - let index = &mir::Operand::Consume(mir::Lvalue::Local(index)); + let index = &mir::Operand::Copy(mir::Lvalue::Local(index)); let llindex = self.const_operand(index, span)?.llval; let iv = if let Some(iv) = common::const_to_opt_u128(llindex, false) { @@ -540,7 +540,8 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { -> Result<Const<'tcx>, ConstEvalErr<'tcx>> { debug!("const_operand({:?} @ {:?})", operand, span); let result = match *operand { - mir::Operand::Consume(ref lvalue) => { + mir::Operand::Copy(ref lvalue) | + mir::Operand::Move(ref lvalue) => { Ok(self.const_lvalue(lvalue, span)?.to_const(span)) } diff --git a/src/librustc_trans/mir/lvalue.rs b/src/librustc_trans/mir/lvalue.rs index 891d52045c2..b7470e470bc 100644 --- a/src/librustc_trans/mir/lvalue.rs +++ b/src/librustc_trans/mir/lvalue.rs @@ -487,7 +487,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { tr_base.project_field(bcx, field.index()) } mir::ProjectionElem::Index(index) => { - let index = &mir::Operand::Consume(mir::Lvalue::Local(index)); + let index = &mir::Operand::Copy(mir::Lvalue::Local(index)); let index = self.trans_operand(bcx, index); let llindex = index.immediate(); tr_base.project_index(bcx, llindex) diff --git a/src/librustc_trans/mir/operand.rs b/src/librustc_trans/mir/operand.rs index 8c43bded1bf..21770c1d792 100644 --- a/src/librustc_trans/mir/operand.rs +++ b/src/librustc_trans/mir/operand.rs @@ -308,7 +308,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> { debug!("trans_operand(operand={:?})", operand); match *operand { - mir::Operand::Consume(ref lvalue) => { + mir::Operand::Copy(ref lvalue) | + mir::Operand::Move(ref lvalue) => { self.trans_consume(bcx, lvalue) } diff --git a/src/test/mir-opt/basic_assignment.rs b/src/test/mir-opt/basic_assignment.rs index e7263b47394..a8b87a273bf 100644 --- a/src/test/mir-opt/basic_assignment.rs +++ b/src/test/mir-opt/basic_assignment.rs @@ -43,14 +43,14 @@ fn main() { // StorageLive(_2); // StorageLive(_3); // _3 = _1; -// _2 = _3; +// _2 = move _3; // StorageDead(_3); // StorageLive(_4); // _4 = std::option::Option<std::boxed::Box<u32>>::None; // StorageLive(_5); // StorageLive(_6); -// _6 = _4; -// replace(_5 <- _6) -> [return: bb1, unwind: bb5]; +// _6 = move _4; +// replace(_5 <- move _6) -> [return: bb1, unwind: bb5]; // } // bb1: { // drop(_6) -> [return: bb6, unwind: bb4]; diff --git a/src/test/mir-opt/box_expr.rs b/src/test/mir-opt/box_expr.rs index c782859b126..f4938fae6a5 100644 --- a/src/test/mir-opt/box_expr.rs +++ b/src/test/mir-opt/box_expr.rs @@ -46,7 +46,7 @@ impl Drop for S { // } // // bb1: { -// _1 = _2; +// _1 = move _2; // drop(_2) -> bb4; // } // @@ -61,8 +61,8 @@ impl Drop for S { // bb4: { // StorageDead(_2); // StorageLive(_4); -// _4 = _1; -// _3 = const std::mem::drop(_4) -> [return: bb5, unwind: bb7]; +// _4 = move _1; +// _3 = const std::mem::drop(move _4) -> [return: bb5, unwind: bb7]; // } // // bb5: { diff --git a/src/test/mir-opt/copy_propagation.rs b/src/test/mir-opt/copy_propagation.rs index 223c65737ad..50d8a5154c4 100644 --- a/src/test/mir-opt/copy_propagation.rs +++ b/src/test/mir-opt/copy_propagation.rs @@ -24,10 +24,10 @@ fn main() { // ... // _3 = _1; // ... -// _2 = _3; +// _2 = move _3; // ... // _4 = _2; -// _0 = _4; +// _0 = move _4; // ... // return; // } @@ -35,7 +35,7 @@ fn main() { // START rustc.test.CopyPropagation.after.mir // bb0: { // ... -// _0 = _1; +// _0 = move _1; // ... // return; // } diff --git a/src/test/mir-opt/copy_propagation_arg.rs b/src/test/mir-opt/copy_propagation_arg.rs index ae30b5fae88..017fac6a6a1 100644 --- a/src/test/mir-opt/copy_propagation_arg.rs +++ b/src/test/mir-opt/copy_propagation_arg.rs @@ -43,11 +43,11 @@ fn main() { // StorageLive(_2); // StorageLive(_3); // _3 = _1; -// _2 = const dummy(_3) -> bb1; +// _2 = const dummy(move _3) -> bb1; // } // bb1: { // StorageDead(_3); -// _1 = _2; +// _1 = move _2; // StorageDead(_2); // _0 = (); // return; @@ -58,11 +58,11 @@ fn main() { // StorageLive(_2); // nop; // nop; -// _2 = const dummy(_1) -> bb1; +// _2 = const dummy(move _1) -> bb1; // } // bb1: { // nop; -// _1 = _2; +// _1 = move _2; // StorageDead(_2); // _0 = (); // return; @@ -72,7 +72,7 @@ fn main() { // bb0: { // StorageLive(_3); // _3 = _1; -// _2 = const dummy(_3) -> bb1; +// _2 = const dummy(move _3) -> bb1; // } // bb1: { // StorageDead(_3); @@ -85,7 +85,7 @@ fn main() { // bb0: { // nop; // nop; -// _2 = const dummy(_1) -> bb1; +// _2 = const dummy(move _1) -> bb1; // } // bb1: { // nop; @@ -98,7 +98,7 @@ fn main() { // bb0: { // StorageLive(_2); // _2 = _1; -// _1 = _2; +// _1 = move _2; // StorageDead(_2); // _0 = (); // return; diff --git a/src/test/mir-opt/deaggregator_test.rs b/src/test/mir-opt/deaggregator_test.rs index d0f4e3bb60b..c918bef129a 100644 --- a/src/test/mir-opt/deaggregator_test.rs +++ b/src/test/mir-opt/deaggregator_test.rs @@ -29,7 +29,7 @@ fn main() { // ... // _2 = _1; // ... -// _0 = Baz { x: _2, y: const 0f32, z: const false }; +// _0 = Baz { x: move _2, y: const 0f32, z: const false }; // ... // return; // } @@ -39,7 +39,7 @@ fn main() { // ... // _2 = _1; // ... -// (_0.0: usize) = _2; +// (_0.0: usize) = move _2; // (_0.1: f32) = const 0f32; // (_0.2: bool) = const false; // ... diff --git a/src/test/mir-opt/deaggregator_test_enum.rs b/src/test/mir-opt/deaggregator_test_enum.rs index 9400ae5050b..8af56b7c011 100644 --- a/src/test/mir-opt/deaggregator_test_enum.rs +++ b/src/test/mir-opt/deaggregator_test_enum.rs @@ -30,7 +30,7 @@ fn main() { // bb0: { // StorageLive(_2); // _2 = _1; -// _0 = Baz::Foo { x: _2 }; +// _0 = Baz::Foo { x: move _2 }; // StorageDead(_2); // return; // } @@ -39,7 +39,7 @@ fn main() { // bb0: { // StorageLive(_2); // _2 = _1; -// ((_0 as Foo).0: usize) = _2; +// ((_0 as Foo).0: usize) = move _2; // discriminant(_0) = 1; // StorageDead(_2); // return; diff --git a/src/test/mir-opt/deaggregator_test_enum_2.rs b/src/test/mir-opt/deaggregator_test_enum_2.rs index ab62164e800..b6505de22f3 100644 --- a/src/test/mir-opt/deaggregator_test_enum_2.rs +++ b/src/test/mir-opt/deaggregator_test_enum_2.rs @@ -33,14 +33,14 @@ fn main() { // bb1: { // StorageLive(_4); // _4 = _2; -// _0 = Foo::A(_4,); +// _0 = Foo::A(move _4,); // StorageDead(_4); // goto -> bb3; // } // bb2: { // StorageLive(_5); // _5 = _2; -// _0 = Foo::B(_5,); +// _0 = Foo::B(move _5,); // StorageDead(_5); // goto -> bb3; // } @@ -49,7 +49,7 @@ fn main() { // bb1: { // StorageLive(_4); // _4 = _2; -// ((_0 as A).0: i32) = _4; +// ((_0 as A).0: i32) = move _4; // discriminant(_0) = 0; // StorageDead(_4); // goto -> bb3; @@ -57,7 +57,7 @@ fn main() { // bb2: { // StorageLive(_5); // _5 = _2; -// ((_0 as B).0: i32) = _5; +// ((_0 as B).0: i32) = move _5; // discriminant(_0) = 1; // StorageDead(_5); // goto -> bb3; diff --git a/src/test/mir-opt/deaggregator_test_multiple.rs b/src/test/mir-opt/deaggregator_test_multiple.rs index 91643e07ed0..3a9a458fd46 100644 --- a/src/test/mir-opt/deaggregator_test_multiple.rs +++ b/src/test/mir-opt/deaggregator_test_multiple.rs @@ -30,12 +30,12 @@ fn main() { // ... // _3 = _1; // ... -// _2 = Foo::A(_3,); +// _2 = Foo::A(move _3,); // ... // _5 = _1; -// _4 = Foo::A(_5,); +// _4 = Foo::A(move _5,); // ... -// _0 = [_2, _4]; +// _0 = [move _2, move _4]; // ... // return; // } @@ -45,14 +45,14 @@ fn main() { // ... // _3 = _1; // ... -// ((_2 as A).0: i32) = _3; +// ((_2 as A).0: i32) = move _3; // discriminant(_2) = 0; // ... // _5 = _1; -// ((_4 as A).0: i32) = _5; +// ((_4 as A).0: i32) = move _5; // discriminant(_4) = 0; // ... -// _0 = [_2, _4]; +// _0 = [move _2, move _4]; // ... // return; // } diff --git a/src/test/mir-opt/end_region_2.rs b/src/test/mir-opt/end_region_2.rs index 5ee377569dd..56c3e2a38a0 100644 --- a/src/test/mir-opt/end_region_2.rs +++ b/src/test/mir-opt/end_region_2.rs @@ -46,7 +46,7 @@ fn main() { // _3 = &'23_1rs _2; // StorageLive(_5); // _5 = _2; -// switchInt(_5) -> [0u8: bb3, otherwise: bb2]; +// switchInt(move _5) -> [0u8: bb3, otherwise: bb2]; // } // bb2: { // _0 = (); diff --git a/src/test/mir-opt/end_region_3.rs b/src/test/mir-opt/end_region_3.rs index 1dbbd74cdf3..8c0d56eba78 100644 --- a/src/test/mir-opt/end_region_3.rs +++ b/src/test/mir-opt/end_region_3.rs @@ -48,7 +48,7 @@ fn main() { // _3 = &'26_1rs _1; // StorageLive(_5); // _5 = _1; -// switchInt(_5) -> [0u8: bb3, otherwise: bb2]; +// switchInt(move _5) -> [0u8: bb3, otherwise: bb2]; // } // bb2: { // _0 = (); diff --git a/src/test/mir-opt/end_region_4.rs b/src/test/mir-opt/end_region_4.rs index 6b8018e4b22..d9456ef1563 100644 --- a/src/test/mir-opt/end_region_4.rs +++ b/src/test/mir-opt/end_region_4.rs @@ -51,7 +51,7 @@ fn foo(i: i32) { // _3 = &'26_2rs _2; // StorageLive(_5); // _5 = (*_3); -// _4 = const foo(_5) -> [return: bb1, unwind: bb3]; +// _4 = const foo(move _5) -> [return: bb1, unwind: bb3]; // } // bb1: { // StorageDead(_5); diff --git a/src/test/mir-opt/end_region_5.rs b/src/test/mir-opt/end_region_5.rs index f5d5bf1e4a6..c2ee2d62b98 100644 --- a/src/test/mir-opt/end_region_5.rs +++ b/src/test/mir-opt/end_region_5.rs @@ -41,9 +41,9 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 { // StorageLive(_3); // StorageLive(_4); // _4 = &'14s _1; -// _3 = [closure@NodeId(18)] { d: _4 }; +// _3 = [closure@NodeId(18)] { d: move _4 }; // StorageDead(_4); -// _2 = const foo(_3) -> [return: bb1, unwind: bb3]; +// _2 = const foo(move _3) -> [return: bb1, unwind: bb3]; // } // bb1: { // EndRegion('14s); @@ -73,7 +73,7 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 { // bb0: { // StorageLive(_2); // _2 = ((*(_1.0: &'14s D)).0: i32); -// _0 = _2; +// _0 = move _2; // StorageDead(_2); // return; // } diff --git a/src/test/mir-opt/end_region_6.rs b/src/test/mir-opt/end_region_6.rs index 7f0e16eaa06..34675e8842f 100644 --- a/src/test/mir-opt/end_region_6.rs +++ b/src/test/mir-opt/end_region_6.rs @@ -41,9 +41,9 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 { // StorageLive(_3); // StorageLive(_4); // _4 = &'19s _1; -// _3 = [closure@NodeId(22)] { d: _4 }; +// _3 = [closure@NodeId(22)] { d: move _4 }; // StorageDead(_4); -// _2 = const foo(_3) -> [return: bb1, unwind: bb3]; +// _2 = const foo(move _3) -> [return: bb1, unwind: bb3]; // } // bb1: { // EndRegion('19s); @@ -76,7 +76,7 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 { // _2 = &'15_0rs (*(_1.0: &'19s D)); // StorageLive(_3); // _3 = ((*_2).0: i32); -// _0 = _3; +// _0 = move _3; // StorageDead(_3); // EndRegion('15_0rs); // StorageDead(_2); diff --git a/src/test/mir-opt/end_region_7.rs b/src/test/mir-opt/end_region_7.rs index 7a17afee3e0..a9b6d2196fc 100644 --- a/src/test/mir-opt/end_region_7.rs +++ b/src/test/mir-opt/end_region_7.rs @@ -40,8 +40,8 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 { // _1 = D::{{constructor}}(const 0i32,); // StorageLive(_3); // StorageLive(_4); -// _4 = _1; -// _3 = [closure@NodeId(22)] { d: _4 }; +// _4 = move _1; +// _3 = [closure@NodeId(22)] { d: move _4 }; // drop(_4) -> [return: bb4, unwind: bb3]; // } // bb1: { @@ -55,7 +55,7 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 { // } // bb4: { // StorageDead(_4); -// _2 = const foo(_3) -> [return: bb5, unwind: bb3]; +// _2 = const foo(move _3) -> [return: bb5, unwind: bb3]; // } // bb5: { // drop(_3) -> [return: bb6, unwind: bb2]; @@ -84,7 +84,7 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 { // _2 = &'15_0rs (_1.0: D); // StorageLive(_3); // _3 = ((*_2).0: i32); -// _0 = _3; +// _0 = move _3; // StorageDead(_3); // EndRegion('15_0rs); // StorageDead(_2); diff --git a/src/test/mir-opt/end_region_8.rs b/src/test/mir-opt/end_region_8.rs index 1df30995102..4c1ec4b1026 100644 --- a/src/test/mir-opt/end_region_8.rs +++ b/src/test/mir-opt/end_region_8.rs @@ -46,9 +46,9 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 { // StorageLive(_4); // StorageLive(_5); // _5 = _2; -// _4 = [closure@NodeId(22)] { r: _5 }; +// _4 = [closure@NodeId(22)] { r: move _5 }; // StorageDead(_5); -// _3 = const foo(_4) -> [return: bb1, unwind: bb3]; +// _3 = const foo(move _4) -> [return: bb1, unwind: bb3]; // } // bb1: { // StorageDead(_4); @@ -79,7 +79,7 @@ fn foo<F>(f: F) where F: FnOnce() -> i32 { // bb0: { // StorageLive(_2); // _2 = ((*(_1.0: &'21_1rs D)).0: i32); -// _0 = _2; +// _0 = move _2; // StorageDead(_2); // return; // } diff --git a/src/test/mir-opt/end_region_9.rs b/src/test/mir-opt/end_region_9.rs index d3482077305..b313e296ac9 100644 --- a/src/test/mir-opt/end_region_9.rs +++ b/src/test/mir-opt/end_region_9.rs @@ -64,7 +64,7 @@ fn main() { // bb1: { // StorageLive(_7); // _7 = _1; -// switchInt(_7) -> [0u8: bb3, otherwise: bb2]; +// switchInt(move _7) -> [0u8: bb3, otherwise: bb2]; // } // bb2: { // _0 = (); diff --git a/src/test/mir-opt/end_region_cyclic.rs b/src/test/mir-opt/end_region_cyclic.rs index 5eada97ed20..b8dabada18e 100644 --- a/src/test/mir-opt/end_region_cyclic.rs +++ b/src/test/mir-opt/end_region_cyclic.rs @@ -70,11 +70,11 @@ fn query() -> bool { true } // StorageLive(_3); // StorageLive(_4); // _4 = std::option::Option<&'35_0rs S<'35_0rs>>::None; -// _3 = const <std::cell::Cell<T>>::new(_4) -> bb2; +// _3 = const <std::cell::Cell<T>>::new(move _4) -> bb2; // } // bb2: { // StorageDead(_4); -// _2 = S<'35_0rs> { r: _3 }; +// _2 = S<'35_0rs> { r: move _3 }; // StorageDead(_3); // StorageLive(_6); // _6 = &'16s (_2.0: std::cell::Cell<std::option::Option<&'35_0rs S<'35_0rs>>>); @@ -83,9 +83,9 @@ fn query() -> bool { true } // StorageLive(_9); // _9 = &'35_0rs _2; // _8 = &'35_0rs (*_9); -// _7 = std::option::Option<&'35_0rs S<'35_0rs>>::Some(_8,); +// _7 = std::option::Option<&'35_0rs S<'35_0rs>>::Some(move _8,); // StorageDead(_8); -// _5 = const <std::cell::Cell<T>>::set(_6, _7) -> bb3; +// _5 = const <std::cell::Cell<T>>::set(move _6, move _7) -> bb3; // } // bb3: { // EndRegion('16s); @@ -96,7 +96,7 @@ fn query() -> bool { true } // _11 = const query() -> bb4; // } // bb4: { -// switchInt(_11) -> [0u8: bb6, otherwise: bb5]; +// switchInt(move _11) -> [0u8: bb6, otherwise: bb5]; // } // bb5: { // _0 = (); @@ -115,9 +115,9 @@ fn query() -> bool { true } // StorageLive(_17); // _17 = &'35_0rs _2; // _16 = &'35_0rs (*_17); -// _15 = std::option::Option<&'35_0rs S<'35_0rs>>::Some(_16,); +// _15 = std::option::Option<&'35_0rs S<'35_0rs>>::Some(move _16,); // StorageDead(_16); -// _13 = const <std::cell::Cell<T>>::set(_14, _15) -> bb7; +// _13 = const <std::cell::Cell<T>>::set(move _14, move_15) -> bb7; // } // bb7: { // EndRegion('33s); diff --git a/src/test/mir-opt/end_region_destruction_extents_1.rs b/src/test/mir-opt/end_region_destruction_extents_1.rs index 12d14df47df..aebe0a1ff6a 100644 --- a/src/test/mir-opt/end_region_destruction_extents_1.rs +++ b/src/test/mir-opt/end_region_destruction_extents_1.rs @@ -92,12 +92,12 @@ unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> { // _9 = S1::{{constructor}}(const "dang1",); // _8 = &'10s _9; // _7 = &'10s (*_8); -// _3 = D1<'12ds, '10s>::{{constructor}}(_4, _7); +// _3 = D1<'12ds, '10s>::{{constructor}}(move _4, move _7); // EndRegion('10s); // StorageDead(_7); // StorageDead(_4); // _2 = (_3.0: &'12ds S1); -// _1 = _2; +// _1 = move _2; // StorageDead(_2); // drop(_3) -> bb1; // } @@ -139,12 +139,12 @@ unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> { // StorageLive(_8); // _8 = promoted[0]; // _7 = &'10s (*_8); -// _3 = D1<'12ds, '10s>::{{constructor}}(_4, _7); +// _3 = D1<'12ds, '10s>::{{constructor}}(move _4, move _7); // EndRegion('10s); // StorageDead(_7); // StorageDead(_4); // _2 = (_3.0: &'12ds S1); -// _1 = _2; +// _1 = move _2; // StorageDead(_2); // drop(_3) -> bb1; // } diff --git a/src/test/mir-opt/inline-closure-borrows-arg.rs b/src/test/mir-opt/inline-closure-borrows-arg.rs index de7b38d5519..3fb54f90984 100644 --- a/src/test/mir-opt/inline-closure-borrows-arg.rs +++ b/src/test/mir-opt/inline-closure-borrows-arg.rs @@ -37,12 +37,12 @@ fn foo<T: Copy>(_t: T, q: &i32) -> i32 { // _6 = &(*_2); // ... // _7 = &(*_2); -// _5 = (_6, _7); -// _9 = (_5.0: &i32); -// _10 = (_5.1: &i32); +// _5 = (move _6, move _7); +// _9 = move (_5.0: &i32); +// _10 = move (_5.1: &i32); // StorageLive(_8); // _8 = (*_9); -// _0 = _8; +// _0 = move _8; // ... // return; // } diff --git a/src/test/mir-opt/inline-closure.rs b/src/test/mir-opt/inline-closure.rs index 9d3fb923f5b..dc8ff13c03a 100644 --- a/src/test/mir-opt/inline-closure.rs +++ b/src/test/mir-opt/inline-closure.rs @@ -33,10 +33,10 @@ fn foo<T: Copy>(_t: T, q: i32) -> i32 { // _6 = _2; // ... // _7 = _2; -// _5 = (_6, _7); -// _8 = (_5.0: i32); -// _9 = (_5.1: i32); -// _0 = _8; +// _5 = (move _6, move _7); +// _8 = move (_5.0: i32); +// _9 = move (_5.1: i32); +// _0 = move _8; // ... // return; // } diff --git a/src/test/mir-opt/issue-38669.rs b/src/test/mir-opt/issue-38669.rs index 9415e140d80..b5c188cf834 100644 --- a/src/test/mir-opt/issue-38669.rs +++ b/src/test/mir-opt/issue-38669.rs @@ -31,7 +31,7 @@ fn main() { // bb1: { // StorageLive(_4); // _4 = _1; -// switchInt(_4) -> [0u8: bb3, otherwise: bb2]; +// switchInt(move _4) -> [0u8: bb3, otherwise: bb2]; // } // // bb2: { diff --git a/src/test/mir-opt/lower_128bit_debug_test.rs b/src/test/mir-opt/lower_128bit_debug_test.rs index 4626dc17e1f..134a868f933 100644 --- a/src/test/mir-opt/lower_128bit_debug_test.rs +++ b/src/test/mir-opt/lower_128bit_debug_test.rs @@ -75,71 +75,71 @@ fn main() { // START rustc.test_signed.Lower128Bit.after.mir // _2 = const i128_addo(_1, const 1i128) -> bb10; // ... -// _1 = (_2.0: i128); +// _1 = move (_2.0: i128); // _3 = const i128_subo(_1, const 2i128) -> bb11; // ... -// _1 = (_3.0: i128); +// _1 = move (_3.0: i128); // _4 = const i128_mulo(_1, const 3i128) -> bb12; // ... -// _1 = (_4.0: i128); +// _1 = move (_4.0: i128); // ... // _1 = const i128_div(_1, const 4i128) -> bb13; // ... // _1 = const i128_rem(_1, const 5i128) -> bb15; // ... -// _1 = (_13.0: i128); +// _1 = move (_13.0: i128); // ... // _17 = const 7i32 as u128 (Misc); -// _14 = const i128_shro(_1, _17) -> bb16; +// _14 = const i128_shro(_1, move _17) -> bb16; // ... -// _1 = (_14.0: i128); +// _1 = move (_14.0: i128); // ... -// assert(!(_2.1: bool), "attempt to add with overflow") -> bb1; +// assert(!move (_2.1: bool), "attempt to add with overflow") -> bb1; // ... -// assert(!(_3.1: bool), "attempt to subtract with overflow") -> bb2; +// assert(!move (_3.1: bool), "attempt to subtract with overflow") -> bb2; // ... -// assert(!(_4.1: bool), "attempt to multiply with overflow") -> bb3; +// assert(!move (_4.1: bool), "attempt to multiply with overflow") -> bb3; // ... -// assert(!(_13.1: bool), "attempt to shift left with overflow") -> bb8; +// assert(!move (_13.1: bool), "attempt to shift left with overflow") -> bb8; // ... // _16 = const 6i32 as u128 (Misc); -// _13 = const i128_shlo(_1, _16) -> bb14; +// _13 = const i128_shlo(_1, move _16) -> bb14; // ... -// assert(!(_14.1: bool), "attempt to shift right with overflow") -> bb9; +// assert(!move (_14.1: bool), "attempt to shift right with overflow") -> bb9; // END rustc.test_signed.Lower128Bit.after.mir // START rustc.test_unsigned.Lower128Bit.after.mir // _2 = const u128_addo(_1, const 1u128) -> bb8; // ... -// _1 = (_2.0: u128); +// _1 = move (_2.0: u128); // _3 = const u128_subo(_1, const 2u128) -> bb9; // ... -// _1 = (_3.0: u128); +// _1 = move (_3.0: u128); // _4 = const u128_mulo(_1, const 3u128) -> bb10; // ... -// _1 = (_4.0: u128); +// _1 = move (_4.0: u128); // ... // _1 = const u128_div(_1, const 4u128) -> bb11; // ... // _1 = const u128_rem(_1, const 5u128) -> bb13; // ... -// _1 = (_7.0: u128); +// _1 = move (_7.0: u128); // ... // _11 = const 7i32 as u128 (Misc); -// _8 = const u128_shro(_1, _11) -> bb14; +// _8 = const u128_shro(_1, move _11) -> bb14; // ... -// _1 = (_8.0: u128); +// _1 = move (_8.0: u128); // ... -// assert(!(_2.1: bool), "attempt to add with overflow") -> bb1; +// assert(!move (_2.1: bool), "attempt to add with overflow") -> bb1; // ... -// assert(!(_3.1: bool), "attempt to subtract with overflow") -> bb2; +// assert(!move (_3.1: bool), "attempt to subtract with overflow") -> bb2; // ... -// assert(!(_4.1: bool), "attempt to multiply with overflow") -> bb3; +// assert(!move (_4.1: bool), "attempt to multiply with overflow") -> bb3; // ... -// assert(!(_7.1: bool), "attempt to shift left with overflow") -> bb6; +// assert(!move (_7.1: bool), "attempt to shift left with overflow") -> bb6; // ... // _10 = const 6i32 as u128 (Misc); -// _7 = const u128_shlo(_1, _10) -> bb12; +// _7 = const u128_shlo(_1, move _10) -> bb12; // ... -// assert(!(_8.1: bool), "attempt to shift right with overflow") -> bb7; +// assert(!move (_8.1: bool), "attempt to shift right with overflow") -> bb7; // END rustc.test_unsigned.Lower128Bit.after.mir diff --git a/src/test/mir-opt/lower_128bit_test.rs b/src/test/mir-opt/lower_128bit_test.rs index 207cd0ac57e..5de75014f0e 100644 --- a/src/test/mir-opt/lower_128bit_test.rs +++ b/src/test/mir-opt/lower_128bit_test.rs @@ -83,10 +83,10 @@ fn main() { // _1 = const i128_sub(_1, const 2i128) -> bb6; // ... // _11 = const 7i32 as u32 (Misc); -// _1 = const i128_shr(_1, _11) -> bb9; +// _1 = const i128_shr(_1, move _11) -> bb9; // ... // _12 = const 6i32 as u32 (Misc); -// _1 = const i128_shl(_1, _12) -> bb10; +// _1 = const i128_shl(_1, move _12) -> bb10; // END rustc.test_signed.Lower128Bit.after.mir // START rustc.test_unsigned.Lower128Bit.after.mir @@ -101,8 +101,8 @@ fn main() { // _1 = const u128_sub(_1, const 2u128) -> bb4; // ... // _5 = const 7i32 as u32 (Misc); -// _1 = const u128_shr(_1, _5) -> bb7; +// _1 = const u128_shr(_1, move _5) -> bb7; // ... // _6 = const 6i32 as u32 (Misc); -// _1 = const u128_shl(_1, _6) -> bb8; +// _1 = const u128_shl(_1, move _6) -> bb8; // END rustc.test_unsigned.Lower128Bit.after.mir diff --git a/src/test/mir-opt/match_false_edges.rs b/src/test/mir-opt/match_false_edges.rs index a59b21473f1..b0adbd6ba89 100644 --- a/src/test/mir-opt/match_false_edges.rs +++ b/src/test/mir-opt/match_false_edges.rs @@ -54,12 +54,12 @@ fn main() { // ... // _2 = std::option::Option<i32>::Some(const 42i32,); // _5 = discriminant(_2); -// switchInt(_5) -> [0isize: bb5, 1isize: bb3, otherwise: bb7]; +// switchInt(move _5) -> [0isize: bb5, 1isize: bb3, otherwise: bb7]; // } // bb1: { // arm1 // StorageLive(_7); // _7 = _3; -// _1 = (const 1i32, _7); +// _1 = (const 1i32, move _7); // StorageDead(_7); // goto -> bb12; // } @@ -89,7 +89,7 @@ fn main() { // _6 = const guard() -> bb9; // } // bb9: { // end of guard -// switchInt(_6) -> [0u8: bb10, otherwise: bb1]; +// switchInt(move _6) -> [0u8: bb10, otherwise: bb1]; // } // bb10: { // to pre_binding2 // falseEdges -> [real: bb4, imaginary: bb4]; @@ -99,7 +99,7 @@ fn main() { // _4 = ((_2 as Some).0: i32); // StorageLive(_8); // _8 = _4; -// _1 = (const 2i32, _8); +// _1 = (const 2i32, move _8); // StorageDead(_8); // goto -> bb12; // } @@ -114,12 +114,12 @@ fn main() { // ... // _2 = std::option::Option<i32>::Some(const 42i32,); // _5 = discriminant(_2); -// switchInt(_5) -> [0isize: bb4, 1isize: bb3, otherwise: bb7]; +// switchInt(move _5) -> [0isize: bb4, 1isize: bb3, otherwise: bb7]; // } // bb1: { // arm1 // StorageLive(_7); // _7 = _3; -// _1 = (const 1i32, _7); +// _1 = (const 1i32, move _7); // StorageDead(_7); // goto -> bb12; // } @@ -149,7 +149,7 @@ fn main() { // _6 = const guard() -> bb9; // } // bb9: { // end of guard -// switchInt(_6) -> [0u8: bb10, otherwise: bb1]; +// switchInt(move _6) -> [0u8: bb10, otherwise: bb1]; // } // bb10: { // to pre_binding2 // falseEdges -> [real: bb5, imaginary: bb4]; @@ -159,7 +159,7 @@ fn main() { // _4 = ((_2 as Some).0: i32); // StorageLive(_8); // _8 = _4; -// _1 = (const 2i32, _8); +// _1 = (const 2i32, move _8); // StorageDead(_8); // goto -> bb12; // } @@ -174,7 +174,7 @@ fn main() { // ... // _2 = std::option::Option<i32>::Some(const 1i32,); // _7 = discriminant(_2); -// switchInt(_7) -> [1isize: bb3, otherwise: bb4]; +// switchInt(move _7) -> [1isize: bb3, otherwise: bb4]; // } // bb1: { // arm1 // _1 = const 1i32; @@ -207,7 +207,7 @@ fn main() { // _8 = const guard() -> bb9; // } // bb9: { //end of guard -// switchInt(_8) -> [0u8: bb10, otherwise: bb1]; +// switchInt(move _8) -> [0u8: bb10, otherwise: bb1]; // } // bb10: { // to pre_binding2 // falseEdges -> [real: bb4, imaginary: bb4]; @@ -224,11 +224,11 @@ fn main() { // StorageLive(_10); // StorageLive(_11); // _11 = _5; -// _10 = const guard2(_11) -> bb13; +// _10 = const guard2(move _11) -> bb13; // } // bb13: { // end of guard2 // StorageDead(_11); -// switchInt(_10) -> [0u8: bb14, otherwise: bb2]; +// switchInt(move _10) -> [0u8: bb14, otherwise: bb2]; // } // bb14: { // to pre_binding4 // falseEdges -> [real: bb6, imaginary: bb6]; diff --git a/src/test/mir-opt/nll/liveness-drop-intra-block.rs b/src/test/mir-opt/nll/liveness-drop-intra-block.rs index 5c34479d259..3e86677956f 100644 --- a/src/test/mir-opt/nll/liveness-drop-intra-block.rs +++ b/src/test/mir-opt/nll/liveness-drop-intra-block.rs @@ -36,6 +36,6 @@ fn main() { // | Live variables at bb1[3]: [_1] // _4 = _1; // | Live variables at bb1[4]: [_4] -// _3 = const use_x(_4) -> bb2; +// _3 = const use_x(move _4) -> bb2; // } // END rustc.main.nll.0.mir diff --git a/src/test/mir-opt/nll/liveness-interblock.rs b/src/test/mir-opt/nll/liveness-interblock.rs index 8217befca6b..32a38a5cd5e 100644 --- a/src/test/mir-opt/nll/liveness-interblock.rs +++ b/src/test/mir-opt/nll/liveness-interblock.rs @@ -36,7 +36,7 @@ fn main() { // | Live variables at bb2[1]: [_1] // _4 = _1; // | Live variables at bb2[2]: [_4] -// _3 = const make_live(_4) -> bb4; +// _3 = const make_live(move _4) -> bb4; // } // END rustc.main.nll.0.mir // START rustc.main.nll.0.mir diff --git a/src/test/mir-opt/nll/region-liveness-basic.rs b/src/test/mir-opt/nll/region-liveness-basic.rs index ae059febc71..3aba3ac86ae 100644 --- a/src/test/mir-opt/nll/region-liveness-basic.rs +++ b/src/test/mir-opt/nll/region-liveness-basic.rs @@ -51,6 +51,6 @@ fn main() { // | Live variables at bb2[1]: [_2] // _7 = (*_2); // | Live variables at bb2[2]: [_7] -// _6 = const use_x(_7) -> bb4; +// _6 = const use_x(move _7) -> bb4; // } // END rustc.main.nll.0.mir diff --git a/src/test/mir-opt/nll/region-subtyping-basic.rs b/src/test/mir-opt/nll/region-subtyping-basic.rs index fb178b46b47..35701076730 100644 --- a/src/test/mir-opt/nll/region-subtyping-basic.rs +++ b/src/test/mir-opt/nll/region-subtyping-basic.rs @@ -45,5 +45,5 @@ fn main() { // ... // _7 = _2; // ... -// _6 = _7; +// _6 = move _7; // END rustc.main.nll.0.mir diff --git a/src/test/mir-opt/packed-struct-drop-aligned.rs b/src/test/mir-opt/packed-struct-drop-aligned.rs index 07a943976c3..dc36248811e 100644 --- a/src/test/mir-opt/packed-struct-drop-aligned.rs +++ b/src/test/mir-opt/packed-struct-drop-aligned.rs @@ -40,10 +40,10 @@ impl Drop for Droppy { // bb0: { // StorageLive(_1); // ... -// _1 = Packed::{{constructor}}(_2,); +// _1 = Packed::{{constructor}}(move _2,); // ... // StorageLive(_6); -// _6 = (_1.0: Aligned); +// _6 = move (_1.0: Aligned); // drop(_6) -> [return: bb4, unwind: bb3]; // } // bb1: { @@ -54,12 +54,12 @@ impl Drop for Droppy { // return; // } // bb3: { -// (_1.0: Aligned) = _4; +// (_1.0: Aligned) = move _4; // drop(_1) -> bb1; // } // bb4: { // StorageDead(_6); -// (_1.0: Aligned) = _4; +// (_1.0: Aligned) = move _4; // StorageDead(_4); // _0 = (); // drop(_1) -> bb2; diff --git a/src/test/mir-opt/storage_live_dead_in_statics.rs b/src/test/mir-opt/storage_live_dead_in_statics.rs index 995639e20d6..730ef655b13 100644 --- a/src/test/mir-opt/storage_live_dead_in_statics.rs +++ b/src/test/mir-opt/storage_live_dead_in_statics.rs @@ -185,11 +185,11 @@ fn main() { // _47 = (const 0u32, const 2u32); // StorageLive(_48); // _48 = (const 0u32, const 3u32); -// _6 = [_7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48]; +// _6 = [move _7, move _8, move _9, move _10, move _11, move _12, move _13, move _14, move _15, move _16, move _17, move _18, move _19, move _20, move _21, move _22, move _23, move _24, move _25, move _26, move _27, move _28, move _29, move _30, move _31, move _32, move _33, move _34, move _35, move _36, move _37, move _38, move _39, move _40, move _41, move _42, move _43, move _44, move _45, move _46, move _47, move _48]; // _5 = &_6; // _4 = &(*_5); -// _3 = _4 as &'static [(u32, u32)] (Unsize); -// _2 = Foo { tup: const "hi", data: _3 }; +// _3 = move _4 as &'static [(u32, u32)] (Unsize); +// _2 = Foo { tup: const "hi", data: move _3 }; // _1 = &_2; // _0 = &(*_1); // StorageDead(_1); diff --git a/src/test/mir-opt/storage_ranges.rs b/src/test/mir-opt/storage_ranges.rs index 53cb82bb0f6..41eaf67d292 100644 --- a/src/test/mir-opt/storage_ranges.rs +++ b/src/test/mir-opt/storage_ranges.rs @@ -27,7 +27,7 @@ fn main() { // StorageLive(_4); // StorageLive(_5); // _5 = _1; -// _4 = std::option::Option<i32>::Some(_5,); +// _4 = std::option::Option<i32>::Some(move _5,); // StorageDead(_5); // _3 = &_4; // _2 = (); diff --git a/src/test/mir-opt/validate_1.rs b/src/test/mir-opt/validate_1.rs index b7360a0e087..e6cd5355000 100644 --- a/src/test/mir-opt/validate_1.rs +++ b/src/test/mir-opt/validate_1.rs @@ -47,7 +47,7 @@ fn main() { // _5 = &ReErased mut (*_6); // Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(10)))]); // Validate(Release, [_2: (), _3: &ReScope(Node(ItemLocalId(10))) Test, _5: &ReScope(Node(ItemLocalId(10))) mut i32]); -// _2 = const Test::foo(_3, _5) -> bb1; +// _2 = const Test::foo(move _3, move _5) -> bb1; // } // // bb1: { @@ -69,7 +69,7 @@ fn main() { // Validate(Acquire, [(*_3): i32/ReScope(Remainder(BlockRemainder { block: ItemLocalId(22), first_statement_index: 0 })) (imm)]); // StorageLive(_4); // _4 = (*_3); -// _0 = _4; +// _0 = move _4; // StorageDead(_4); // EndRegion(ReScope(Remainder(BlockRemainder { block: ItemLocalId(22), first_statement_index: 0 }))); // StorageDead(_3); diff --git a/src/test/mir-opt/validate_2.rs b/src/test/mir-opt/validate_2.rs index 5f3dad5efde..5b8ba4d8d06 100644 --- a/src/test/mir-opt/validate_2.rs +++ b/src/test/mir-opt/validate_2.rs @@ -22,7 +22,7 @@ fn main() { // bb1: { // Validate(Acquire, [_2: std::boxed::Box<[i32; 3]>]); // Validate(Release, [_2: std::boxed::Box<[i32; 3]>]); -// _1 = _2 as std::boxed::Box<[i32]> (Unsize); +// _1 = move _2 as std::boxed::Box<[i32]> (Unsize); // Validate(Acquire, [_1: std::boxed::Box<[i32]>]); // StorageDead(_2); // StorageDead(_3); diff --git a/src/test/mir-opt/validate_3.rs b/src/test/mir-opt/validate_3.rs index 50c410039e2..80e75fcee8a 100644 --- a/src/test/mir-opt/validate_3.rs +++ b/src/test/mir-opt/validate_3.rs @@ -48,7 +48,7 @@ fn main() { // _4 = &ReErased (*_5); // Validate(Acquire, [(*_4): i32/ReScope(Node(ItemLocalId(17))) (imm)]); // Validate(Release, [_3: (), _4: &ReScope(Node(ItemLocalId(17))) i32]); -// _3 = const foo(_4) -> bb1; +// _3 = const foo(move _4) -> bb1; // } // bb1: { // Validate(Acquire, [_3: ()]); diff --git a/src/test/mir-opt/validate_4.rs b/src/test/mir-opt/validate_4.rs index 39438af4b44..fb0c8871d83 100644 --- a/src/test/mir-opt/validate_4.rs +++ b/src/test/mir-opt/validate_4.rs @@ -65,7 +65,7 @@ fn main() { // Validate(Acquire, [_1: &ReFree(DefId(0/0:4 ~ validate_4[317d]::test[0]), BrAnon(0)) mut i32]); // Validate(Release, [_1: &ReFree(DefId(0/0:4 ~ validate_4[317d]::test[0]), BrAnon(0)) mut i32]); // ... -// _2 = const write_42(_3) -> bb1; +// _2 = const write_42(move _3) -> bb1; // } // bb1: { // Validate(Acquire, [_2: bool]); @@ -82,7 +82,7 @@ fn main() { // Validate(Release, [_1: &ReFree(DefId(0/1:10 ~ validate_4[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(60)], _2: &ReFree(DefId(0/1:10 ~ validate_4[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); // StorageLive(_3); // ... -// _0 = const write_42(_3) -> bb1; +// _0 = const write_42(move _3) -> bb1; // } // ... // } diff --git a/src/test/mir-opt/validate_5.rs b/src/test/mir-opt/validate_5.rs index 043338c8089..c9408c1f2f8 100644 --- a/src/test/mir-opt/validate_5.rs +++ b/src/test/mir-opt/validate_5.rs @@ -40,7 +40,7 @@ fn main() { // Validate(Acquire, [_1: &ReFree(DefId(0/0:4 ~ validate_5[317d]::test[0]), BrAnon(0)) mut i32]); // ... // Validate(Release, [_2: bool, _3: *mut i32]); -// _2 = const write_42(_3) -> bb1; +// _2 = const write_42(move _3) -> bb1; // } // ... // } @@ -55,11 +55,11 @@ fn main() { // Validate(Suspend(ReScope(Node(ItemLocalId(9)))), [(*_2): i32]); // _4 = &ReErased mut (*_2); // Validate(Acquire, [(*_4): i32/ReScope(Node(ItemLocalId(9)))]); -// _3 = _4 as *mut i32 (Misc); +// _3 = move _4 as *mut i32 (Misc); // EndRegion(ReScope(Node(ItemLocalId(9)))); // StorageDead(_4); // Validate(Release, [_0: bool, _3: *mut i32]); -// _0 = const write_42(_3) -> bb1; +// _0 = const write_42(move _3) -> bb1; // } // ... // } |
