// `Statement` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
-static_assert_size!(Statement<'_>, 64);
+static_assert_size!(Statement<'_>, 32);
impl Statement<'_> {
/// Changes a statement to a nop. This is both faster than deleting instructions and avoids
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
pub enum StatementKind<'tcx> {
/// Write the RHS Rvalue to the LHS Place.
- Assign(Place<'tcx>, Box<Rvalue<'tcx>>),
+ Assign(Box<(Place<'tcx>, Rvalue<'tcx>)>),
/// This represents all the reading that a pattern match may do
/// (e.g., inspecting constants and discriminant values), and the
///
/// Note that this also is emitted for regular `let` bindings to ensure that locals that are
/// never accessed still get some sanity checks for, e.g., `let x: ! = ..;`
- FakeRead(FakeReadCause, Place<'tcx>),
+ FakeRead(FakeReadCause, Box<Place<'tcx>>),
/// Write the discriminant for a variant to the enum Place.
- SetDiscriminant { place: Place<'tcx>, variant_index: VariantIdx },
+ SetDiscriminant { place: Box<Place<'tcx>>, variant_index: VariantIdx },
/// Start a live range for the storage of the local.
StorageLive(Local),
/// by miri and only generated when "-Z mir-emit-retag" is passed.
/// See <https://internals.rust-lang.org/t/stacked-borrows-an-aliasing-model-for-rust/8153/>
/// for more details.
- Retag(RetagKind, Place<'tcx>),
+ Retag(RetagKind, Box<Place<'tcx>>),
/// Encodes a user's type ascription. These need to be preserved
/// intact so that NLL can respect them. For example:
/// - `Contravariant` -- requires that `T_y :> T`
/// - `Invariant` -- requires that `T_y == T`
/// - `Bivariant` -- no effect
- AscribeUserType(Place<'tcx>, ty::Variance, Box<UserTypeProjection>),
+ AscribeUserType(Box<(Place<'tcx>, UserTypeProjection)>, ty::Variance),
/// No-op. Useful for deleting instructions without affecting statement indices.
Nop,
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
use self::StatementKind::*;
match self.kind {
- Assign(ref place, ref rv) => write!(fmt, "{:?} = {:?}", place, rv),
+ Assign(box(ref place, ref rv)) => write!(fmt, "{:?} = {:?}", place, rv),
FakeRead(ref cause, ref place) => write!(fmt, "FakeRead({:?}, {:?})", cause, place),
Retag(ref kind, ref place) => write!(
fmt,
InlineAsm(ref asm) => {
write!(fmt, "asm!({:?} : {:?} : {:?})", asm.asm, asm.outputs, asm.inputs)
}
- AscribeUserType(ref place, ref variance, ref c_ty) => {
+ AscribeUserType(box(ref place, ref c_ty), ref variance) => {
write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty)
}
Nop => write!(fmt, "nop"),
EnumTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for StatementKind<'tcx> {
- (StatementKind::Assign)(a, b),
+ (StatementKind::Assign)(a),
(StatementKind::FakeRead)(cause, place),
(StatementKind::SetDiscriminant) { place, variant_index },
(StatementKind::StorageLive)(a),
(StatementKind::StorageDead)(a),
(StatementKind::InlineAsm)(a),
(StatementKind::Retag)(kind, place),
- (StatementKind::AscribeUserType)(a, v, b),
+ (StatementKind::AscribeUserType)(a, v),
(StatementKind::Nop),
}
}
self.visit_source_info(source_info);
match kind {
- StatementKind::Assign(place, rvalue) => {
+ StatementKind::Assign(
+ box(ref $($mutability)? place, ref $($mutability)? rvalue)
+ ) => {
self.visit_assign(place, rvalue, location);
}
StatementKind::FakeRead(_, place) => {
StatementKind::Retag(kind, place) => {
self.visit_retag(kind, place, location);
}
- StatementKind::AscribeUserType(place, variance, user_ty) => {
+ StatementKind::AscribeUserType(
+ box(ref $($mutability)? place, ref $($mutability)? user_ty),
+ variance
+ ) => {
self.visit_ascribe_user_ty(place, variance, user_ty, location);
}
StatementKind::Nop => {}
self.set_debug_loc(&mut bx, statement.source_info);
match statement.kind {
- mir::StatementKind::Assign(ref place, ref rvalue) => {
+ mir::StatementKind::Assign(box(ref place, ref rvalue)) => {
if let mir::Place {
base: mir::PlaceBase::Local(index),
projection: box [],
- } = *place {
- match self.locals[index] {
+ } = place {
+ match self.locals[*index] {
LocalRef::Place(cg_dest) => {
self.codegen_rvalue(bx, cg_dest, rvalue)
}
}
LocalRef::Operand(None) => {
let (mut bx, operand) = self.codegen_rvalue_operand(bx, rvalue);
- if let Some(name) = self.mir.local_decls[index].name {
+ if let Some(name) = self.mir.local_decls[*index].name {
match operand.val {
OperandValue::Ref(x, ..) |
OperandValue::Immediate(x) => {
}
}
}
- self.locals[index] = LocalRef::Operand(Some(operand));
+ self.locals[*index] = LocalRef::Operand(Some(operand));
bx
}
LocalRef::Operand(Some(op)) => {
self.codegen_rvalue(bx, cg_dest, rvalue)
}
}
- mir::StatementKind::SetDiscriminant{ref place, variant_index} => {
+ mir::StatementKind::SetDiscriminant{box ref place, variant_index} => {
self.codegen_place(&mut bx, &place.as_ref())
.codegen_set_discr(&mut bx, variant_index);
bx
"annotate_argument_and_return_for_borrow: location={:?}",
location
);
- if let Some(&Statement { kind: StatementKind::Assign(ref reservation, _), ..})
+ if let Some(&Statement { kind: StatementKind::Assign(box(ref reservation, _)), ..})
= &self.body[location.block].statements.get(location.statement_index)
{
debug!(
target, stmt
);
if let StatementKind::Assign(
- Place {
- base: PlaceBase::Local(assigned_to),
- projection: box [],
- },
- box rvalue
+ box(
+ Place {
+ base: PlaceBase::Local(assigned_to),
+ projection: box [],
+ },
+ rvalue
+ )
) = &stmt.kind {
debug!(
"annotate_argument_and_return_for_borrow: assigned_to={:?} \
let mut target = place.local_or_deref_local();
for stmt in &self.body[location.block].statements[location.statement_index..] {
debug!("add_moved_or_invoked_closure_note: stmt={:?} target={:?}", stmt, target);
- if let StatementKind::Assign(into, box Rvalue::Use(from)) = &stmt.kind {
+ if let StatementKind::Assign(box(into, Rvalue::Use(from))) = &stmt.kind {
debug!("add_fnonce_closure_note: into={:?} from={:?}", into, from);
match from {
Operand::Copy(ref place) |
debug!("move_spans: moved_place={:?} location={:?} stmt={:?}", moved_place, location, stmt);
if let StatementKind::Assign(
- _,
- box Rvalue::Aggregate(ref kind, ref places)
+ box(_, Rvalue::Aggregate(ref kind, ref places))
) = stmt.kind {
let (def_id, is_generator) = match kind {
box AggregateKind::Closure(def_id, _) => (def_id, false),
.get(location.statement_index)
{
Some(&Statement {
- kind: StatementKind::Assign(Place {
+ kind: StatementKind::Assign(box(Place {
base: PlaceBase::Local(local),
projection: box [],
- }, _),
+ }, _)),
..
}) => local,
_ => return OtherUse(use_span),
for stmt in &self.body[location.block].statements[location.statement_index + 1..] {
if let StatementKind::Assign(
- _, box Rvalue::Aggregate(ref kind, ref places)
+ box(_, Rvalue::Aggregate(ref kind, ref places))
) = stmt.kind {
let (def_id, is_generator) = match kind {
box AggregateKind::Closure(def_id, _) => (def_id, false),
self.check_activations(location, span, flow_state);
match stmt.kind {
- StatementKind::Assign(ref lhs, ref rhs) => {
+ StatementKind::Assign(box(ref lhs, ref rhs)) => {
self.consume_rvalue(
location,
(rhs, span),
flow_state,
);
}
- StatementKind::FakeRead(_, ref place) => {
+ StatementKind::FakeRead(_, box ref place) => {
// Read for match doesn't access any memory and is used to
// assert that a place is safe and live. So we don't have to
// do any checks here.
let stmt = &bbd.statements[loc.statement_index];
debug!("temporary assigned in: stmt={:?}", stmt);
- if let StatementKind::Assign(_, box Rvalue::Ref(_, _, ref source)) = stmt.kind {
+ if let StatementKind::Assign(box(_, Rvalue::Ref(_, _, ref source))) = stmt.kind {
propagate_closure_used_mut_place(self, source);
} else {
bug!("closures should only capture user variables \
// If that ever stops being the case, then the ever initialized
// flow could be used.
if let Some(StatementKind::Assign(
- Place {
- base: PlaceBase::Local(local),
- projection: box [],
- },
- box Rvalue::Use(Operand::Move(move_from)),
+ box(
+ Place {
+ base: PlaceBase::Local(local),
+ projection: box [],
+ },
+ Rvalue::Use(Operand::Move(move_from))
+ )
)) = self.body.basic_blocks()[location.block]
.statements
.get(location.statement_index)
// it which simplifies the termination logic.
let mut queue = vec![location];
let mut target = if let Some(&Statement {
- kind: StatementKind::Assign(Place {
+ kind: StatementKind::Assign(box(Place {
base: PlaceBase::Local(local),
projection: box [],
- }, _),
+ }, _)),
..
}) = stmt
{
debug!("was_captured_by_trait_object: stmt={:?}", stmt);
// The only kind of statement that we care about is assignments...
- if let StatementKind::Assign(place, box rvalue) = &stmt.kind {
+ if let StatementKind::Assign(box(place, rvalue)) = &stmt.kind {
let into = match place.local_or_deref_local() {
Some(into) => into,
None => {
self.check_activations(location);
match statement.kind {
- StatementKind::Assign(ref lhs, ref rhs) => {
+ StatementKind::Assign(box(ref lhs, ref rhs)) => {
self.consume_rvalue(
location,
rhs,
debug!("check_stmt: {:?}", stmt);
let tcx = self.tcx();
match stmt.kind {
- StatementKind::Assign(ref place, ref rv) => {
+ StatementKind::Assign(box(ref place, ref rv)) => {
// Assignments to temporaries are not "interesting";
// they are not caused by the user, but rather artifacts
// of lowering. Assignments to other sorts of places *are* interesting
);
};
}
- StatementKind::AscribeUserType(ref place, variance, box ref projection) => {
+ StatementKind::AscribeUserType(box(ref place, ref projection), variance) => {
let place_ty = place.ty(body, tcx).ty;
if let Err(terr) = self.relate_type_and_user_type(
place_ty,
_location: Location,
) {
match &statement.kind {
- StatementKind::Assign(into, _) => {
+ StatementKind::Assign(box(into, _)) => {
if let PlaceBase::Local(local) = into.base {
debug!(
"visit_statement: statement={:?} local={:?} \
rvalue: Rvalue<'tcx>) {
self.push(block, Statement {
source_info,
- kind: StatementKind::Assign(place.clone(), box rvalue)
+ kind: StatementKind::Assign(box(place.clone(), rvalue))
});
}
Statement {
source_info,
kind: StatementKind::AscribeUserType(
- place.clone(),
+ box(
+ place.clone(),
+ UserTypeProjection { base: annotation_index, projs: vec![], }
+ ),
Variance::Invariant,
- box UserTypeProjection { base: annotation_index, projs: vec![], },
),
},
);
Statement {
source_info,
kind: StatementKind::AscribeUserType(
- Place::from(temp.clone()),
+ box(
+ Place::from(temp.clone()),
+ UserTypeProjection { base: annotation_index, projs: vec![], },
+ ),
Variance::Invariant,
- box UserTypeProjection { base: annotation_index, projs: vec![], },
),
},
);
source_info,
kind: StatementKind::FakeRead(
FakeReadCause::ForMatchedPlace,
- scrutinee_place.clone(),
+ box(scrutinee_place.clone()),
),
});
block,
Statement {
source_info,
- kind: StatementKind::FakeRead(FakeReadCause::ForLet, place),
+ kind: StatementKind::FakeRead(FakeReadCause::ForLet, box(place)),
},
);
block,
Statement {
source_info: pattern_source_info,
- kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()),
+ kind: StatementKind::FakeRead(FakeReadCause::ForLet, box(place.clone())),
},
);
let ty_source_info = self.source_info(user_ty_span);
- let user_ty = box pat_ascription_ty.user_ty(
+ let user_ty = pat_ascription_ty.user_ty(
&mut self.canonical_user_type_annotations,
place.ty(&self.local_decls, self.hir.tcx()).ty,
ty_source_info.span,
Statement {
source_info: ty_source_info,
kind: StatementKind::AscribeUserType(
- place,
+ box(
+ place,
+ user_ty,
+ ),
// We always use invariant as the variance here. This is because the
// variance field from the ascription refers to the variance to use
// when applying the type to the value being matched, but this
// contrast, is intended to be used to relate `T` to the type of
// `<expr>`.
ty::Variance::Invariant,
- user_ty,
),
},
);
source_info: guard_end,
kind: StatementKind::FakeRead(
FakeReadCause::ForMatchGuard,
- Place::from(temp),
+ box(Place::from(temp)),
),
});
}
post_guard_block,
Statement {
source_info: guard_end,
- kind: StatementKind::FakeRead(FakeReadCause::ForGuardBinding, place),
+ kind: StatementKind::FakeRead(FakeReadCause::ForGuardBinding, box(place)),
},
);
}
ascription.user_ty,
);
- let user_ty = box ascription.user_ty.clone().user_ty(
+ let user_ty = ascription.user_ty.clone().user_ty(
&mut self.canonical_user_type_annotations,
ascription.source.ty(&self.local_decls, self.hir.tcx()).ty,
source_info.span
Statement {
source_info,
kind: StatementKind::AscribeUserType(
- ascription.source.clone(),
+ box(
+ ascription.source.clone(),
+ user_ty,
+ ),
ascription.variance,
- user_ty,
),
},
);
debug!("Borrows::statement_effect: stmt={:?}", stmt);
match stmt.kind {
- mir::StatementKind::Assign(ref lhs, ref rhs) => {
- if let mir::Rvalue::Ref(_, _, ref place) = **rhs {
+ mir::StatementKind::Assign(box(ref lhs, ref rhs)) => {
+ if let mir::Rvalue::Ref(_, _, ref place) = *rhs {
if place.ignore_borrow(
self.tcx,
self.body,
match stmt.kind {
StatementKind::StorageLive(l) => sets.gen(l),
StatementKind::StorageDead(l) => sets.kill(l),
- StatementKind::Assign(ref place, _)
- | StatementKind::SetDiscriminant { ref place, .. } => {
+ StatementKind::Assign(box(ref place, _))
+ | StatementKind::SetDiscriminant { box ref place, .. } => {
if let PlaceBase::Local(local) = place.base {
sets.gen(local);
}
impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
match stmt.kind {
- StatementKind::Assign(ref place, ref rval) => {
+ StatementKind::Assign(box(ref place, ref rval)) => {
self.create_move_path(place);
if let RvalueInitializationState::Shallow = rval.initialization_state() {
// Box starts out uninitialized - need to create a separate
self.memory.tcx.span = stmt.source_info.span;
match stmt.kind {
- Assign(ref place, ref rvalue) => self.eval_rvalue_into_place(rvalue, place)?,
+ Assign(box(ref place, ref rvalue)) => self.eval_rvalue_into_place(rvalue, place)?,
SetDiscriminant {
ref place,
// Function arguments should be retagged, and we make this one raw.
body.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
source_info,
- kind: StatementKind::Retag(RetagKind::Raw, dropee_ptr.clone()),
+ kind: StatementKind::Retag(RetagKind::Raw, box(dropee_ptr.clone())),
});
}
let patch = {
let rcvr = Place::from(Local::new(1+0)).deref();
let ret_statement = self.make_statement(
StatementKind::Assign(
- Place::return_place(),
- box Rvalue::Use(Operand::Copy(rcvr))
+ box(
+ Place::return_place(),
+ Rvalue::Use(Operand::Copy(rcvr))
+ )
)
);
self.block(vec![ret_statement], TerminatorKind::Return, false);
// `let ref_loc: &ty = &src;`
let statement = self.make_statement(
StatementKind::Assign(
- ref_loc.clone(),
- box Rvalue::Ref(tcx.lifetimes.re_erased, BorrowKind::Shared, src)
+ box(
+ ref_loc.clone(),
+ Rvalue::Ref(tcx.lifetimes.re_erased, BorrowKind::Shared, src)
+ )
)
);
let cond = self.make_place(Mutability::Mut, tcx.types.bool);
let compute_cond = self.make_statement(
StatementKind::Assign(
- cond.clone(),
- box Rvalue::BinaryOp(BinOp::Ne, Operand::Copy(end), Operand::Copy(beg))
+ box(
+ cond.clone(),
+ Rvalue::BinaryOp(BinOp::Ne, Operand::Copy(end), Operand::Copy(beg))
+ )
)
);
let inits = vec![
self.make_statement(
StatementKind::Assign(
- Place::from(beg),
- box Rvalue::Use(Operand::Constant(self.make_usize(0)))
+ box(
+ Place::from(beg),
+ Rvalue::Use(Operand::Constant(self.make_usize(0)))
+ )
)
),
self.make_statement(
StatementKind::Assign(
- end.clone(),
- box Rvalue::Use(Operand::Constant(self.make_usize(len)))
+ box(
+ end.clone(),
+ Rvalue::Use(Operand::Constant(self.make_usize(len)))
+ )
)
)
];
let statements = vec![
self.make_statement(
StatementKind::Assign(
- Place::from(beg),
- box Rvalue::BinaryOp(
- BinOp::Add,
- Operand::Copy(Place::from(beg)),
- Operand::Constant(self.make_usize(1))
+ box(
+ Place::from(beg),
+ Rvalue::BinaryOp(
+ BinOp::Add,
+ Operand::Copy(Place::from(beg)),
+ Operand::Constant(self.make_usize(1))
+ )
)
)
)
let beg = self.local_decls.push(temp_decl(Mutability::Mut, tcx.types.usize, span));
let init = self.make_statement(
StatementKind::Assign(
- Place::from(beg),
- box Rvalue::Use(Operand::Constant(self.make_usize(0)))
+ box(
+ Place::from(beg),
+ Rvalue::Use(Operand::Constant(self.make_usize(0)))
+ )
)
);
self.block(vec![init], TerminatorKind::Goto { target: BasicBlock::new(6) }, true);
// `goto #6;`
let statement = self.make_statement(
StatementKind::Assign(
- Place::from(beg),
- box Rvalue::BinaryOp(
- BinOp::Add,
- Operand::Copy(Place::from(beg)),
- Operand::Constant(self.make_usize(1))
+ box(
+ Place::from(beg),
+ Rvalue::BinaryOp(
+ BinOp::Add,
+ Operand::Copy(Place::from(beg)),
+ Operand::Constant(self.make_usize(1))
+ )
)
)
);
statements.push(Statement {
source_info,
kind: StatementKind::Assign(
- Place::from(ref_rcvr),
- box Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_l)
+ box(
+ Place::from(ref_rcvr),
+ Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_l)
+ )
)
});
Operand::Move(Place::from(ref_rcvr))
basic_blocks[START_BLOCK].statements.splice(0..0,
places.into_iter().map(|place| Statement {
source_info,
- kind: StatementKind::Retag(RetagKind::FnEntry, place),
+ kind: StatementKind::Retag(RetagKind::FnEntry, box(place)),
})
);
}
for (source_info, dest_place, dest_block) in returns {
basic_blocks[dest_block].statements.insert(0, Statement {
source_info,
- kind: StatementKind::Retag(RetagKind::Default, dest_place),
+ kind: StatementKind::Retag(RetagKind::Default, box(dest_place)),
});
}
for i in (0..block_data.statements.len()).rev() {
let (retag_kind, place) = match block_data.statements[i].kind {
// If we are casting *from* a reference, we may have to retag-as-raw.
- StatementKind::Assign(ref place, box Rvalue::Cast(
+ StatementKind::Assign(box(ref place, Rvalue::Cast(
CastKind::Misc,
ref src,
dest_ty,
- )) => {
+ ))) => {
let src_ty = src.ty(&*local_decls, tcx);
if src_ty.is_region_ptr() {
// The only `Misc` casts on references are those creating raw pointers.
// Assignments of reference or ptr type are the ones where we may have
// to update tags. This includes `x = &[mut] ...` and hence
// we also retag after taking a reference!
- StatementKind::Assign(ref place, box ref rvalue) if needs_retag(place) => {
+ StatementKind::Assign(box(ref place, ref rvalue)) if needs_retag(place) => {
let kind = match rvalue {
Rvalue::Ref(_, borrow_kind, _)
if borrow_kind.allows_two_phase_borrow()
let source_info = block_data.statements[i].source_info;
block_data.statements.insert(i+1, Statement {
source_info,
- kind: StatementKind::Retag(retag_kind, place),
+ kind: StatementKind::Retag(retag_kind, box(place)),
});
}
}
location: Location) {
match statement.kind {
StatementKind::AscribeUserType(..)
- | StatementKind::Assign(_, box Rvalue::Ref(_, BorrowKind::Shallow, _))
+ | StatementKind::Assign(box(_, Rvalue::Ref(_, BorrowKind::Shallow, _)))
| StatementKind::FakeRead(..) => statement.make_nop(),
_ => (),
}
location: Location,
) {
trace!("visit_statement: {:?}", statement);
- if let StatementKind::Assign(ref place, ref mut rval) = statement.kind {
+ if let StatementKind::Assign(box(ref place, ref mut rval)) = statement.kind {
let place_ty: Ty<'tcx> = place
.ty(&self.local_decls, self.tcx)
.ty;
// That use of the source must be an assignment.
match statement.kind {
StatementKind::Assign(
- Place {
- base: PlaceBase::Local(local),
- projection: box [],
- },
- box Rvalue::Use(ref operand)
+ box(
+ Place {
+ base: PlaceBase::Local(local),
+ projection: box [],
+ },
+ Rvalue::Use(ref operand)
+ )
) if local == dest_local => {
let maybe_action = match *operand {
Operand::Copy(ref src_place) |
if let Some(stmt) = body[location.block].statements.get(location.statement_index) {
match stmt.kind {
StatementKind::Assign(
- Place {
- base: PlaceBase::Local(local),
- projection: box [],
- },
- box Rvalue::Use(Operand::Copy(Place {
- base: PlaceBase::Local(src_local),
- projection: box [],
- })),
+ box(
+ Place {
+ base: PlaceBase::Local(local),
+ projection: box [],
+ },
+ Rvalue::Use(Operand::Copy(Place {
+ base: PlaceBase::Local(src_local),
+ projection: box [],
+ })),
+ )
) |
StatementKind::Assign(
- Place {
- base: PlaceBase::Local(local),
- projection: box [],
- },
- box Rvalue::Use(Operand::Move(Place {
- base: PlaceBase::Local(src_local),
- projection: box [],
- })),
+ box(
+ Place {
+ base: PlaceBase::Local(local),
+ projection: box [],
+ },
+ Rvalue::Use(Operand::Move(Place {
+ base: PlaceBase::Local(src_local),
+ projection: box [],
+ })),
+ )
) if local == dest_local && dest_local == src_local => {}
_ => {
continue;
for bb in basic_blocks {
bb.expand_statements(|stmt| {
// FIXME(eddyb) don't match twice on `stmt.kind` (post-NLL).
- if let StatementKind::Assign(_, ref rhs) = stmt.kind {
- if let Rvalue::Aggregate(ref kind, _) = **rhs {
+ if let StatementKind::Assign(box(_, ref rhs)) = stmt.kind {
+ if let Rvalue::Aggregate(ref kind, _) = *rhs {
// FIXME(#48193) Deaggregate arrays when it's cheaper to do so.
if let AggregateKind::Array(_) = **kind {
return None;
let stmt = stmt.replace_nop();
let source_info = stmt.source_info;
let (lhs, kind, operands) = match stmt.kind {
- StatementKind::Assign(lhs, box rvalue) => {
+ StatementKind::Assign(box(lhs, rvalue)) => {
match rvalue {
Rvalue::Aggregate(kind, operands) => (lhs, kind, operands),
_ => bug!()
assert!(!data.is_cleanup, "DropAndReplace in unwind path not supported");
let assign = Statement {
- kind: StatementKind::Assign(location.clone(), box Rvalue::Use(value.clone())),
+ kind: StatementKind::Assign(box(location.clone(), Rvalue::Use(value.clone()))),
source_info: terminator.source_info
};
let self_place = Place::from(self_arg());
Statement {
source_info,
- kind: StatementKind::SetDiscriminant { place: self_place, variant_index: state_disc },
+ kind: StatementKind::SetDiscriminant {
+ place: box self_place,
+ variant_index: state_disc,
+ },
}
}
let self_place = Place::from(self_arg());
let assign = Statement {
source_info: source_info(body),
- kind: StatementKind::Assign(temp.clone(), box Rvalue::Discriminant(self_place)),
+ kind: StatementKind::Assign(box(temp.clone(), Rvalue::Discriminant(self_place))),
};
(assign, temp)
}
// We must assign the value first in case it gets declared dead below
data.statements.push(Statement {
source_info,
- kind: StatementKind::Assign(Place::return_place(),
- box self.make_state(state_idx, v)),
+ kind: StatementKind::Assign(
+ box(
+ Place::return_place(),
+ self.make_state(state_idx, v)
+ )
+ ),
});
let state = if let Some(resume) = resume { // Yield
let state = 3 + self.suspension_points.len();
// Alias tracking must know we changed the type
body.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
source_info,
- kind: StatementKind::Retag(RetagKind::Raw, Place::from(self_arg())),
+ kind: StatementKind::Retag(RetagKind::Raw, box Place::from(self_arg())),
})
}
let stmt = Statement {
source_info: callsite.location,
- kind: StatementKind::Assign(tmp.clone(), box dest)
+ kind: StatementKind::Assign(box(tmp.clone(), dest))
};
caller_body[callsite.bb]
.statements.push(stmt);
let stmt = Statement {
source_info: callsite.location,
- kind: StatementKind::Assign(Place::from(arg_tmp), box arg),
+ kind: StatementKind::Assign(box(Place::from(arg_tmp), arg)),
};
caller_body[callsite.bb].statements.push(stmt);
arg_tmp
span,
scope: OUTERMOST_SOURCE_SCOPE
},
- kind: StatementKind::Assign(Place::from(dest), box rvalue)
+ kind: StatementKind::Assign(box(Place::from(dest), rvalue))
});
}
// First, take the Rvalue or Call out of the source MIR,
// or duplicate it, depending on keep_original.
if loc.statement_index < no_stmts {
- let (rvalue, source_info) = {
+ let (mut rvalue, source_info) = {
let statement = &mut self.source[loc.block].statements[loc.statement_index];
let rhs = match statement.kind {
- StatementKind::Assign(_, ref mut rhs) => rhs,
+ StatementKind::Assign(box(_, ref mut rhs)) => rhs,
_ => {
span_bug!(statement.source_info.span, "{:?} is not an assignment",
statement);
(if self.keep_original {
rhs.clone()
} else {
- let unit = box Rvalue::Aggregate(box AggregateKind::Tuple, vec![]);
+ let unit = Rvalue::Aggregate(box AggregateKind::Tuple, vec![]);
mem::replace(rhs, unit)
}, statement.source_info)
};
- let mut rvalue = *rvalue;
self.visit_rvalue(&mut rvalue, loc);
self.assign(new_temp, rvalue, source_info.span);
} else {
Candidate::Ref(loc) => {
let ref mut statement = blocks[loc.block].statements[loc.statement_index];
match statement.kind {
- StatementKind::Assign(_, box Rvalue::Ref(_, _, ref mut place)) => {
+ StatementKind::Assign(box(_, Rvalue::Ref(_, _, ref mut place))) => {
// Use the underlying local for this (necessarily interior) borrow.
let ty = place.base.ty(local_decls).ty;
let span = statement.source_info.span;
Candidate::Repeat(loc) => {
let ref mut statement = blocks[loc.block].statements[loc.statement_index];
match statement.kind {
- StatementKind::Assign(_, box Rvalue::Repeat(ref mut operand, _)) => {
+ StatementKind::Assign(box(_, Rvalue::Repeat(ref mut operand, _))) => {
let ty = operand.ty(local_decls, self.tcx);
let span = statement.source_info.span;
mem::replace(
Candidate::Repeat(Location { block, statement_index }) |
Candidate::Ref(Location { block, statement_index }) => {
match body[block].statements[statement_index].kind {
- StatementKind::Assign(Place {
+ StatementKind::Assign(box(Place {
base: PlaceBase::Local(local),
projection: box [],
- }, _) => {
+ }, _)) => {
if temps[local] == TempState::PromotedOut {
// Already promoted.
continue;
for block in body.basic_blocks_mut() {
block.statements.retain(|statement| {
match statement.kind {
- StatementKind::Assign(Place {
+ StatementKind::Assign(box(Place {
base: PlaceBase::Local(index),
projection: box [],
- }, _) |
+ }, _)) |
StatementKind::StorageLive(index) |
StatementKind::StorageDead(index) => {
!promoted(index)
for candidate in &self.promotion_candidates {
match *candidate {
Candidate::Repeat(Location { block: bb, statement_index: stmt_idx }) => {
- if let StatementKind::Assign(_, box Rvalue::Repeat(
+ if let StatementKind::Assign(box(_, Rvalue::Repeat(
Operand::Move(Place {
base: PlaceBase::Local(index),
projection: box [],
}),
_
- )) = self.body[bb].statements[stmt_idx].kind {
+ ))) = self.body[bb].statements[stmt_idx].kind {
promoted_temps.insert(index);
}
}
Candidate::Ref(Location { block: bb, statement_index: stmt_idx }) => {
if let StatementKind::Assign(
- _,
- box Rvalue::Ref(_, _, Place {
- base: PlaceBase::Local(index),
- projection: box [],
- })
+ box(
+ _,
+ Rvalue::Ref(_, _, Place {
+ base: PlaceBase::Local(index),
+ projection: box [],
+ })
+ )
) = self.body[bb].statements[stmt_idx].kind {
promoted_temps.insert(index);
}
) -> McfResult {
let span = statement.source_info.span;
match &statement.kind {
- StatementKind::Assign(place, rval) => {
+ StatementKind::Assign(box(place, rval)) => {
check_place(place, span)?;
check_rvalue(tcx, body, rval, span)
}
// These are all nops in a landing pad
}
- StatementKind::Assign(Place {
+ StatementKind::Assign(box(Place {
base: PlaceBase::Local(_),
projection: box [],
- }, box Rvalue::Use(_)) => {
+ }, Rvalue::Use(_))) => {
// Writing to a local (e.g., a drop flag) does not
// turn a landing pad to a non-nop
}
for (j, stmt) in statements.iter().enumerate() {
debug!("rustc_peek: ({:?},{}) {:?}", bb, j, stmt);
let (place, rvalue) = match stmt.kind {
- mir::StatementKind::Assign(ref place, ref rvalue) => {
+ mir::StatementKind::Assign(box(ref place, ref rvalue)) => {
(place, rvalue)
}
mir::StatementKind::FakeRead(..) |
};
if place == peek_arg_place {
- if let mir::Rvalue::Ref(_, mir::BorrowKind::Shared, ref peeking_at_place) = **rvalue {
+ if let mir::Rvalue::Ref(_, mir::BorrowKind::Shared, ref peeking_at_place) = *rvalue {
// Okay, our search is over.
match move_data.rev_lookup.find(peeking_at_place.as_ref()) {
LookupResult::Exact(peek_mpi) => {
for candidate in &visitor.candidates {
let statement = &body[candidate.block].statements[candidate.statement_index];
- if let StatementKind::Assign(ref dst_place, ref rval) = statement.kind {
- if let Rvalue::Aggregate(box AggregateKind::Array(_), ref items) = **rval {
+ if let StatementKind::Assign(box(ref dst_place, ref rval)) = statement.kind {
+ if let Rvalue::Aggregate(box AggregateKind::Array(_), ref items) = *rval {
let items : Vec<_> = items.iter().map(|item| {
if let Operand::Move(Place {
base: PlaceBase::Local(local),
if block.statements.len() > location.statement_index {
let statement = &block.statements[location.statement_index];
if let StatementKind::Assign(
- Place {
- base: PlaceBase::Local(_),
- projection: box [],
- },
- box Rvalue::Use(Operand::Move(Place {
- base: _,
- projection: box [.., ProjectionElem::ConstantIndex {
+ box(
+ Place {
+ base: PlaceBase::Local(_),
+ projection: box [],
+ },
+ Rvalue::Use(Operand::Move(Place {
+ base: _,
+ projection: box [.., ProjectionElem::ConstantIndex {
offset, min_length: _, from_end: false
- }],
- })),
+ }],
+ })),
+ )
) = &statement.kind {
// FIXME remove once we can use slices patterns
if let StatementKind::Assign(
- _,
- box Rvalue::Use(Operand::Move(Place {
- base,
- projection: box [proj_base @ .., _],
- })),
+ box(
+ _,
+ Rvalue::Use(Operand::Move(Place {
+ base,
+ projection: box [proj_base @ .., _],
+ })),
+ )
) = &statement.kind {
return Some((*offset, PlaceRef {
base,
if adt_def.is_enum() {
set_discriminant = Some(Statement {
kind: StatementKind::SetDiscriminant {
- place: lhs.clone(),
+ place: box(lhs.clone()),
variant_index,
},
source_info,
let variant_index = VariantIdx::new(0);
set_discriminant = Some(Statement {
kind: StatementKind::SetDiscriminant {
- place: lhs.clone(),
+ place: box(lhs.clone()),
variant_index,
},
source_info,
};
Statement {
source_info,
- kind: StatementKind::Assign(lhs_field, box Rvalue::Use(op)),
+ kind: StatementKind::Assign(box(lhs_field, Rvalue::Use(op))),
}
}).chain(set_discriminant)
}
fn assign(&self, lhs: &Place<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> {
Statement {
source_info: self.source_info,
- kind: StatementKind::Assign(lhs.clone(), box rhs)
+ kind: StatementKind::Assign(box(lhs.clone(), rhs))
}
}
}
}
pub fn add_assign(&mut self, loc: Location, place: Place<'tcx>, rv: Rvalue<'tcx>) {
- self.add_statement(loc, StatementKind::Assign(place, box rv));
+ self.add_statement(loc, StatementKind::Assign(box(place, rv)));
}
pub fn make_nop(&mut self, loc: Location) {