diff options
Diffstat (limited to 'compiler/rustc_middle/src/mir/patch.rs')
| -rw-r--r-- | compiler/rustc_middle/src/mir/patch.rs | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/compiler/rustc_middle/src/mir/patch.rs b/compiler/rustc_middle/src/mir/patch.rs index 1f571a36441..d03f9235efd 100644 --- a/compiler/rustc_middle/src/mir/patch.rs +++ b/compiler/rustc_middle/src/mir/patch.rs @@ -78,13 +78,24 @@ impl<'tcx> MirPatch<'tcx> { Location { block: bb, statement_index: offset } } - pub fn new_temp(&mut self, ty: Ty<'tcx>, span: Span) -> Local { + pub fn new_local_with_info( + &mut self, + ty: Ty<'tcx>, + span: Span, + local_info: Option<Box<LocalInfo<'tcx>>>, + ) -> Local { let index = self.next_local; self.next_local += 1; - self.new_locals.push(LocalDecl::new(ty, span)); + let mut new_decl = LocalDecl::new(ty, span); + new_decl.local_info = local_info; + self.new_locals.push(new_decl); Local::new(index as usize) } + pub fn new_temp(&mut self, ty: Ty<'tcx>, span: Span) -> Local { + self.new_local_with_info(ty, span, None) + } + pub fn new_internal(&mut self, ty: Ty<'tcx>, span: Span) -> Local { let index = self.next_local; self.next_local += 1; @@ -141,6 +152,7 @@ impl<'tcx> MirPatch<'tcx> { let mut delta = 0; let mut last_bb = START_BLOCK; + let mut stmts_and_targets: Vec<(Statement<'_>, BasicBlock)> = Vec::new(); for (mut loc, stmt) in new_statements { if loc.block != last_bb { delta = 0; @@ -149,11 +161,30 @@ impl<'tcx> MirPatch<'tcx> { debug!("MirPatch: adding statement {:?} at loc {:?}+{}", stmt, loc, delta); loc.statement_index += delta; let source_info = Self::source_info_for_index(&body[loc.block], loc); + + // For mir-opt `Derefer` to work in all cases we need to + // get terminator's targets and apply the statement to all of them. + if loc.statement_index > body[loc.block].statements.len() { + let term = body[loc.block].terminator(); + let successors = term.successors().clone(); + + for i in successors { + stmts_and_targets + .push((Statement { source_info, kind: stmt.clone() }, i.clone())); + } + delta += 1; + continue; + } + body[loc.block] .statements .insert(loc.statement_index, Statement { source_info, kind: stmt }); delta += 1; } + + for (stmt, target) in stmts_and_targets.into_iter().rev() { + body[target].statements.insert(0, stmt); + } } pub fn source_info_for_index(data: &BasicBlockData<'_>, loc: Location) -> SourceInfo { |
