This shrinks StatementKind from 80 bytes to 64 bytes on 64-bit.
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub enum StatementKind<'tcx> {
/// Write the RHS Rvalue to the LHS Place.
- Assign(Place<'tcx>, Rvalue<'tcx>),
+ Assign(Place<'tcx>, Box<Rvalue<'tcx>>),
/// This represents all the reading that a pattern match may do
/// (e.g. inspecting constants and discriminant values), and the
);
if let StatementKind::Assign(
Place::Local(assigned_to),
- rvalue,
+ box rvalue,
) = &stmt.kind {
debug!("annotate_argument_and_return_for_borrow: assigned_to={:?} \
rvalue={:?}", assigned_to, rvalue);
None => return OtherUse(self.mir.source_info(location).span),
};
- if let StatementKind::Assign(_, Rvalue::Aggregate(ref kind, ref places)) = stmt.kind {
+ if let StatementKind::Assign(_, box Rvalue::Aggregate(ref kind, ref places)) = stmt.kind {
if let AggregateKind::Closure(def_id, _) = **kind {
debug!("find_closure_move_span: found closure {:?}", places);
}
for stmt in &self.mir[location.block].statements[location.statement_index + 1..] {
- if let StatementKind::Assign(_, Rvalue::Aggregate(ref kind, ref places)) = stmt.kind {
+ if let StatementKind::Assign(_, box Rvalue::Aggregate(ref kind, ref places))
+ = stmt.kind {
if let AggregateKind::Closure(def_id, _) = **kind {
debug!("find_closure_borrow_span: found closure {:?}", places);
// flow could be used.
if let Some(StatementKind::Assign(
Place::Local(local),
- Rvalue::Use(Operand::Move(move_from)),
+ box Rvalue::Use(Operand::Move(move_from)),
)) = self.mir.basic_blocks()[location.block]
.statements
.get(location.statement_index)
rvalue: Rvalue<'tcx>) {
self.push(block, Statement {
source_info,
- kind: StatementKind::Assign(place.clone(), rvalue)
+ kind: StatementKind::Assign(place.clone(), box rvalue)
});
}
// re-consider the current implementations of the
// propagate_call_return method.
- if let mir::Rvalue::Ref(region, _, ref place) = *rhs {
+ if let mir::Rvalue::Ref(region, _, ref place) = **rhs {
if place.ignore_borrow(
self.tcx,
self.mir,
let ret_statement = self.make_statement(
StatementKind::Assign(
Place::Local(RETURN_PLACE),
- Rvalue::Use(Operand::Copy(rcvr))
+ box Rvalue::Use(Operand::Copy(rcvr))
)
);
self.block(vec![ret_statement], TerminatorKind::Return, false);
let statement = self.make_statement(
StatementKind::Assign(
ref_loc.clone(),
- Rvalue::Ref(tcx.types.re_erased, BorrowKind::Shared, src)
+ box Rvalue::Ref(tcx.types.re_erased, BorrowKind::Shared, src)
)
);
let compute_cond = self.make_statement(
StatementKind::Assign(
cond.clone(),
- Rvalue::BinaryOp(BinOp::Ne, Operand::Copy(end), Operand::Copy(beg))
+ box Rvalue::BinaryOp(BinOp::Ne, Operand::Copy(end), Operand::Copy(beg))
)
);
self.make_statement(
StatementKind::Assign(
Place::Local(beg),
- Rvalue::Use(Operand::Constant(self.make_usize(0)))
+ box Rvalue::Use(Operand::Constant(self.make_usize(0)))
)
),
self.make_statement(
StatementKind::Assign(
end.clone(),
- Rvalue::Use(Operand::Constant(self.make_usize(len)))
+ box Rvalue::Use(Operand::Constant(self.make_usize(len)))
)
)
];
self.make_statement(
StatementKind::Assign(
Place::Local(beg),
- Rvalue::BinaryOp(
+ box Rvalue::BinaryOp(
BinOp::Add,
Operand::Copy(Place::Local(beg)),
Operand::Constant(self.make_usize(1))
let init = self.make_statement(
StatementKind::Assign(
Place::Local(beg),
- Rvalue::Use(Operand::Constant(self.make_usize(0)))
+ box Rvalue::Use(Operand::Constant(self.make_usize(0)))
)
);
self.block(vec![init], TerminatorKind::Goto { target: BasicBlock::new(6) }, true);
let statement = self.make_statement(
StatementKind::Assign(
Place::Local(beg),
- Rvalue::BinaryOp(
+ box Rvalue::BinaryOp(
BinOp::Add,
Operand::Copy(Place::Local(beg)),
Operand::Constant(self.make_usize(1))
source_info,
kind: StatementKind::Assign(
Place::Local(ref_rcvr),
- Rvalue::Ref(tcx.types.re_erased, borrow_kind, rcvr_l)
+ box Rvalue::Ref(tcx.types.re_erased, borrow_kind, rcvr_l)
)
});
Operand::Move(Place::Local(ref_rcvr))
source_info,
kind: StatementKind::Assign(
Place::Local(RETURN_PLACE),
- Rvalue::Aggregate(
+ box Rvalue::Aggregate(
box AggregateKind::Adt(adt_def, variant_no, substs, None, None),
(1..sig.inputs().len()+1).map(|i| {
Operand::Move(Place::Local(Local::new(i)))
for i in (0..block_data.statements.len()).rev() {
match block_data.statements[i].kind {
// When the borrow of this ref expires, we need to recover validation.
- StatementKind::Assign(_, Rvalue::Ref(_, _, _)) => {
+ StatementKind::Assign(_, box Rvalue::Ref(_, _, _)) => {
// Due to a lack of NLL; we can't capture anything directly here.
// Instead, we have to re-match and clone there.
let (dest_place, re, src_place) = match block_data.statements[i].kind {
StatementKind::Assign(ref dest_place,
- Rvalue::Ref(re, _, ref src_place)) => {
+ box Rvalue::Ref(re, _, ref src_place)) => {
(dest_place.clone(), re, src_place.clone())
},
_ => bug!("We already matched this."),
block_data.statements.insert(i, release_stmt);
}
// Casts can change what validation does (e.g. unsizing)
- StatementKind::Assign(_, Rvalue::Cast(kind, Operand::Copy(_), _)) |
- StatementKind::Assign(_, Rvalue::Cast(kind, Operand::Move(_), _))
+ StatementKind::Assign(_, box Rvalue::Cast(kind, Operand::Copy(_), _)) |
+ StatementKind::Assign(_, box 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_place, src_place) = match block_data.statements[i].kind {
StatementKind::Assign(ref dest_place,
- Rvalue::Cast(_, Operand::Copy(ref src_place), _)) |
+ box Rvalue::Cast(_, Operand::Copy(ref src_place), _)) |
StatementKind::Assign(ref dest_place,
- Rvalue::Cast(_, Operand::Move(ref src_place), _)) =>
+ box Rvalue::Cast(_, Operand::Move(ref src_place), _)) =>
{
(dest_place.clone(), src_place.clone())
},
// That use of the source must be an assignment.
match statement.kind {
- StatementKind::Assign(Place::Local(local), Rvalue::Use(ref operand)) if
+ StatementKind::Assign(Place::Local(local), box Rvalue::Use(ref operand)) if
local == dest_local => {
let maybe_action = match *operand {
Operand::Copy(ref src_place) |
match stmt.kind {
StatementKind::Assign(
Place::Local(local),
- Rvalue::Use(Operand::Copy(Place::Local(src_local))),
+ box Rvalue::Use(Operand::Copy(Place::Local(src_local))),
) |
StatementKind::Assign(
Place::Local(local),
- Rvalue::Use(Operand::Move(Place::Local(src_local))),
+ box Rvalue::Use(Operand::Move(Place::Local(src_local))),
) if local == dest_local && dest_local == src_local => {}
_ => {
continue;
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 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 (mut lhs, kind, operands) = match stmt.kind {
- StatementKind::Assign(lhs, Rvalue::Aggregate(kind, operands))
- => (lhs, kind, operands),
+ StatementKind::Assign(lhs, box rvalue) => {
+ match rvalue {
+ Rvalue::Aggregate(kind, operands) => (lhs, kind, operands),
+ _ => bug!()
+ }
+ }
_ => bug!()
};
};
Statement {
source_info,
- kind: StatementKind::Assign(lhs_field, Rvalue::Use(op)),
+ kind: StatementKind::Assign(lhs_field, box Rvalue::Use(op)),
}
}).chain(set_discriminant))
});
assert!(!data.is_cleanup, "DropAndReplace in unwind path not supported");
let assign = Statement {
- kind: StatementKind::Assign(location.clone(), Rvalue::Use(value.clone())),
+ kind: StatementKind::Assign(location.clone(), box Rvalue::Use(value.clone())),
source_info: terminator.source_info
};
});
Statement {
source_info,
- kind: StatementKind::Assign(state, Rvalue::Use(val)),
+ kind: StatementKind::Assign(state, box Rvalue::Use(val)),
}
}
}
data.statements.push(Statement {
source_info,
kind: StatementKind::Assign(Place::Local(RETURN_PLACE),
- self.make_state(state_idx, v)),
+ box self.make_state(state_idx, v)),
});
let state = if let Some(resume) = resume { // Yield
let state = 3 + self.suspension_points.len() as u32;
let stmt = Statement {
source_info: callsite.location,
- kind: StatementKind::Assign(tmp.clone(), dest)
+ kind: StatementKind::Assign(tmp.clone(), box dest)
};
caller_mir[callsite.bb]
.statements.push(stmt);
let stmt = Statement {
source_info: callsite.location,
- kind: StatementKind::Assign(Place::Local(arg_tmp), arg),
+ kind: StatementKind::Assign(Place::Local(arg_tmp), box arg),
};
caller_mir[callsite.bb].statements.push(stmt);
arg_tmp
let bin_statement = block.statements.pop().unwrap();
let source_info = bin_statement.source_info;
let (place, lhs, mut rhs) = match bin_statement.kind {
- StatementKind::Assign(place, Rvalue::BinaryOp(_, lhs, rhs))
- | StatementKind::Assign(place, Rvalue::CheckedBinaryOp(_, lhs, rhs)) => {
- (place, lhs, rhs)
+ StatementKind::Assign(place, box rvalue) => {
+ match rvalue {
+ Rvalue::BinaryOp(_, lhs, rhs)
+ | Rvalue::CheckedBinaryOp(_, lhs, rhs) => (place, lhs, rhs),
+ _ => bug!(),
+ }
}
- _ => bug!("Statement doesn't match pattern any more?"),
+ _ => bug!()
};
if let Some(local) = cast_local {
source_info: source_info,
kind: StatementKind::Assign(
Place::Local(local),
- Rvalue::Cast(
+ box Rvalue::Cast(
CastKind::Misc,
rhs,
rhs_override_ty.unwrap())),
where D: HasLocalDecls<'tcx>
{
match statement.kind {
- StatementKind::Assign(_, Rvalue::BinaryOp(bin_op, ref lhs, _)) => {
+ StatementKind::Assign(_, box Rvalue::BinaryOp(bin_op, ref lhs, _)) => {
let ty = lhs.ty(local_decls, tcx);
if let Some(is_signed) = sign_of_128bit(ty) {
return item_for_op(bin_op, is_signed);
}
},
- StatementKind::Assign(_, Rvalue::CheckedBinaryOp(bin_op, ref lhs, _)) => {
+ StatementKind::Assign(_, box Rvalue::CheckedBinaryOp(bin_op, ref lhs, _)) => {
let ty = lhs.ty(local_decls, tcx);
if let Some(is_signed) = sign_of_128bit(ty) {
return item_for_checked_op(bin_op, is_signed);
span,
scope: OUTERMOST_SOURCE_SCOPE
},
- kind: StatementKind::Assign(Place::Local(dest), rvalue)
+ kind: StatementKind::Assign(Place::Local(dest), box 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 (mut rvalue, source_info) = {
+ let (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,
(if self.keep_original {
rhs.clone()
} else {
- let unit = Rvalue::Aggregate(box AggregateKind::Tuple, vec![]);
+ let unit = box 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(_, Rvalue::Ref(_, _, ref mut place)) => {
+ StatementKind::Assign(_, box Rvalue::Ref(_, _, ref mut place)) => {
// Find the underlying local for this (necessarily interior) borrow.
// HACK(eddyb) using a recursive function because of mutable borrows.
fn interior_base<'a, 'tcx>(place: &'a mut Place<'tcx>)
match *candidate {
Candidate::Ref(Location { block: bb, statement_index: stmt_idx }) => {
match self.mir[bb].statements[stmt_idx].kind {
- StatementKind::Assign(_, Rvalue::Ref(_, _, Place::Local(index))) => {
+ StatementKind::Assign(_, box Rvalue::Ref(_, _, Place::Local(index))) => {
promoted_temps.insert(index);
}
_ => {}
// instructions, but this should all run after borrowck).
}
- StatementKind::Assign(Place::Local(_), Rvalue::Use(_)) => {
+ StatementKind::Assign(Place::Local(_), box Rvalue::Use(_)) => {
// Writing to a local (e.g. a drop flag) does not
// turn a landing pad to a non-nop
}
};
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) {
LookupResult::Exact(peek_mpi) => {
for candidate in &visitor.candidates {
let statement = &mir[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 Rvalue::Aggregate(box AggregateKind::Array(_), ref items) = **rval {
let items : Vec<_> = items.iter().map(|item| {
if let Operand::Move(Place::Local(local)) = item {
let local_use = &visitor.locals_use[*local];
let statement = &block.statements[location.statement_index];
if let StatementKind::Assign(
Place::Local(_),
- Rvalue::Use(Operand::Move(Place::Projection(box PlaceProjection{
+ box Rvalue::Use(Operand::Move(Place::Projection(box PlaceProjection{
ref base, elem: ProjectionElem::ConstantIndex{
offset, min_length: _, from_end: false}})))) = statement.kind {
return Some((offset, base))
fn assign(&self, lhs: &Place<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> {
Statement {
source_info: self.source_info,
- kind: StatementKind::Assign(lhs.clone(), rhs)
+ kind: StatementKind::Assign(lhs.clone(), box rhs)
}
}
}
}
pub fn add_assign(&mut self, loc: Location, place: Place<'tcx>, rv: Rvalue<'tcx>) {
- self.add_statement(loc, StatementKind::Assign(place, rv));
+ self.add_statement(loc, StatementKind::Assign(place, box rv));
}
pub fn make_nop(&mut self, loc: Location) {