diff --git a/src/librustc_mir/transform/add_validation.rs b/src/librustc_mir/transform/add_validation.rs index 9c341b38e34f8..6ffd07915d248 100644 --- a/src/librustc_mir/transform/add_validation.rs +++ b/src/librustc_mir/transform/add_validation.rs @@ -196,12 +196,13 @@ impl MirPass for AddValidation { 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 } }; @@ -232,20 +233,20 @@ impl MirPass for AddValidation { { 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 }) => { @@ -298,7 +299,7 @@ impl MirPass for AddValidation { // 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)] ); @@ -312,7 +313,7 @@ impl MirPass for AddValidation { // 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() {