diff options
Diffstat (limited to 'compiler/rustc_mir_transform/src/copy_prop.rs')
-rw-r--r-- | compiler/rustc_mir_transform/src/copy_prop.rs | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs index b571215f2..3df459dfa 100644 --- a/compiler/rustc_mir_transform/src/copy_prop.rs +++ b/compiler/rustc_mir_transform/src/copy_prop.rs @@ -1,5 +1,5 @@ use rustc_index::bit_set::BitSet; -use rustc_index::vec::IndexSlice; +use rustc_index::IndexSlice; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; @@ -33,9 +33,8 @@ impl<'tcx> MirPass<'tcx> for CopyProp { } fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); let borrowed_locals = borrowed_locals(body); - let ssa = SsaLocals::new(tcx, param_env, body, &borrowed_locals); + let ssa = SsaLocals::new(body); let fully_moved = fully_moved_locals(&ssa, body); debug!(?fully_moved); @@ -76,7 +75,7 @@ fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn fully_moved_locals(ssa: &SsaLocals, body: &Body<'_>) -> BitSet<Local> { let mut fully_moved = BitSet::new_filled(body.local_decls.len()); - for (_, rvalue) in ssa.assignments(body) { + for (_, rvalue, _) in ssa.assignments(body) { let (Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) | Rvalue::CopyForDeref(place)) = rvalue else { continue }; @@ -162,20 +161,22 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> { } fn visit_statement(&mut self, stmt: &mut Statement<'tcx>, loc: Location) { - match stmt.kind { - // When removing storage statements, we need to remove both (#107511). - StatementKind::StorageLive(l) | StatementKind::StorageDead(l) - if self.storage_to_remove.contains(l) => - { - stmt.make_nop() - } - StatementKind::Assign(box (ref place, ref mut rvalue)) - if place.as_local().is_some() => - { - // Do not replace assignments. - self.visit_rvalue(rvalue, loc) - } - _ => self.super_statement(stmt, loc), + // When removing storage statements, we need to remove both (#107511). + if let StatementKind::StorageLive(l) | StatementKind::StorageDead(l) = stmt.kind + && self.storage_to_remove.contains(l) + { + stmt.make_nop(); + return + } + + self.super_statement(stmt, loc); + + // Do not leave tautological assignments around. + if let StatementKind::Assign(box (lhs, ref rhs)) = stmt.kind + && let Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)) | Rvalue::CopyForDeref(rhs) = *rhs + && lhs == rhs + { + stmt.make_nop(); } } } |