rustc_mir_transform/
erase_deref_temps.rs

1//! This pass converts all `DerefTemp` locals into normal temporaries
2//! and turns their `CopyForDeref` rvalues into normal copies.
3
4use rustc_middle::mir::visit::MutVisitor;
5use rustc_middle::mir::*;
6use rustc_middle::ty::TyCtxt;
7
8struct EraseDerefTempsVisitor<'tcx> {
9    tcx: TyCtxt<'tcx>,
10}
11
12impl<'tcx> MutVisitor<'tcx> for EraseDerefTempsVisitor<'tcx> {
13    fn tcx(&self) -> TyCtxt<'tcx> {
14        self.tcx
15    }
16
17    fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, _: Location) {
18        if let &mut Rvalue::CopyForDeref(place) = rvalue {
19            *rvalue = Rvalue::Use(Operand::Copy(place))
20        }
21    }
22
23    fn visit_local_decl(&mut self, _: Local, local_decl: &mut LocalDecl<'tcx>) {
24        if local_decl.is_deref_temp() {
25            let info = local_decl.local_info.as_mut().unwrap_crate_local();
26            **info = LocalInfo::Boring;
27        }
28    }
29}
30
31pub(super) struct EraseDerefTemps;
32
33impl<'tcx> crate::MirPass<'tcx> for EraseDerefTemps {
34    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
35        EraseDerefTempsVisitor { tcx }.visit_body_preserves_cfg(body);
36    }
37
38    fn is_required(&self) -> bool {
39        true
40    }
41}