return;
}
let restricted_validation = emit_validate == 1 && fn_contains_unsafe(tcx, src);
- let local_decls = mir.local_decls.clone(); // FIXME: Find a way to get rid of this clone.
+ let (span, arg_count) = (mir.span, mir.arg_count);
+ let (basic_blocks, local_decls) = mir.basic_blocks_and_local_decls_mut();
// Convert a place to a validation operand.
let place_to_operand = |place: Place<'tcx>| -> ValidationOperand<'tcx, Place<'tcx>> {
- let (re, mutbl) = place_context(&place, &local_decls, tcx);
- let ty = place.ty(&local_decls, tcx).to_ty(tcx);
+ let (re, mutbl) = place_context(&place, local_decls, tcx);
+ let ty = place.ty(local_decls, tcx).to_ty(tcx);
ValidationOperand { place, ty, re, mutbl }
};
{
let source_info = SourceInfo {
scope: OUTERMOST_SOURCE_SCOPE,
- span: mir.span, // FIXME: Consider using just the span covering the function
- // argument declaration.
+ span: span, // FIXME: Consider using just the span covering the function
+ // argument declaration.
};
// Gather all arguments, skip return value.
- let operands = mir.local_decls.iter_enumerated().skip(1).take(mir.arg_count)
+ let operands = local_decls.iter_enumerated().skip(1).take(arg_count)
.map(|(local, _)| place_to_operand(Place::Local(local))).collect();
- emit_acquire(&mut mir.basic_blocks_mut()[START_BLOCK], source_info, operands);
+ emit_acquire(&mut basic_blocks[START_BLOCK], source_info, operands);
}
// PART 2
// Add ReleaseValid/AcquireValid around function call terminators. We don't use a visitor
// because we need to access the block that a Call jumps to.
let mut returns : Vec<(SourceInfo, Place<'tcx>, BasicBlock)> = Vec::new();
- for block_data in mir.basic_blocks_mut() {
+ for block_data in basic_blocks.iter_mut() {
match block_data.terminator {
Some(Terminator { kind: TerminatorKind::Call { ref args, ref destination, .. },
source_info }) => {
// Now we go over the returns we collected to acquire the return values.
for (source_info, dest_place, dest_block) in returns {
emit_acquire(
- &mut mir.basic_blocks_mut()[dest_block],
+ &mut basic_blocks[dest_block],
source_info,
vec![place_to_operand(dest_place)]
);
// PART 3
// Add ReleaseValid/AcquireValid around Ref and Cast. Again an iterator does not seem very
// suited as we need to add new statements before and after each Ref.
- for block_data in mir.basic_blocks_mut() {
+ for block_data in basic_blocks {
// We want to insert statements around Ref commands as we iterate. To this end, we
// iterate backwards using indices.
for i in (0..block_data.statements.len()).rev() {