Skip to main content

rustc_mir_transform/
cleanup_post_borrowck.rs

1//! This module provides a pass that removes parts of MIR that are no longer relevant after
2//! analysis phase and borrowck. In particular, it removes false edges, user type annotations and
3//! replaces following statements with [`Nop`]s:
4//!
5//!   - [`AscribeUserType`]
6//!   - [`FakeRead`]
7//!   - [`Assign`] statements with a [`Fake`] borrow
8//!   - [`Coverage`] statements that are not needed after the [`InstrumentCoverage`] pass
9//!
10//! [`AscribeUserType`]: rustc_middle::mir::StatementKind::AscribeUserType
11//! [`Assign`]: rustc_middle::mir::StatementKind::Assign
12//! [`FakeRead`]: rustc_middle::mir::StatementKind::FakeRead
13//! [`Nop`]: rustc_middle::mir::StatementKind::Nop
14//! [`Fake`]: rustc_middle::mir::BorrowKind::Fake
15//! [`Coverage`]: rustc_middle::mir::StatementKind::Coverage
16//! [`InstrumentCoverage`]: crate::coverage::InstrumentCoverage
17
18use rustc_middle::mir::*;
19use rustc_middle::ty::TyCtxt;
20use rustc_middle::ty::adjustment::PointerCoercion;
21
22use crate::PassPolicy;
23
24pub(super) struct CleanupPostBorrowck;
25
26impl<'tcx> crate::MirPass<'tcx> for CleanupPostBorrowck {
27    fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
28        // Manually invalidate CFG caches if we actually change a terminator's edges.
29        let mut invalidate_cfg = false;
30        for basic_block in body.basic_blocks.as_mut_preserves_cfg().iter_mut() {
31            for statement in basic_block.statements.iter_mut() {
32                match statement.kind {
33                    StatementKind::AscribeUserType(..)
34                    | StatementKind::Assign((_, Rvalue::Ref(_, BorrowKind::Fake(_), _)))
35                    | StatementKind::FakeRead(..)
36                    | StatementKind::BackwardIncompatibleDropHint { .. } => {
37                        statement.make_nop(true)
38                    }
39                    StatementKind::Coverage(ref kind) if kind.is_removed_after_analysis() => {
40                        statement.make_nop(true)
41                    }
42                    StatementKind::Assign((
43                        _,
44                        Rvalue::Cast(
45                            ref mut cast_kind @ CastKind::PointerCoercion(
46                                PointerCoercion::ArrayToPointer
47                                | PointerCoercion::MutToConstPointer,
48                                _,
49                            ),
50                            ..,
51                        ),
52                    )) => {
53                        // BorrowCk needed to track whether these cases were coercions or casts,
54                        // to know whether to check lifetimes in their pointees,
55                        // but from now on that distinction doesn't matter,
56                        // so just make them ordinary pointer casts instead.
57                        *cast_kind = CastKind::PtrToPtr;
58                    }
59                    _ => (),
60                }
61            }
62
63            // If we change any terminator, we need to ensure that we invalidated the CFG cache.
64            let terminator = basic_block.terminator_mut();
65            match terminator.kind {
66                TerminatorKind::FalseEdge { real_target, .. }
67                | TerminatorKind::FalseUnwind { real_target, .. } => {
68                    invalidate_cfg = true;
69                    terminator.kind = TerminatorKind::Goto { target: real_target };
70                }
71                _ => {}
72            }
73        }
74
75        if invalidate_cfg {
76            body.basic_blocks.invalidate_cfg_cache();
77        }
78
79        body.user_type_annotations.raw.clear();
80
81        for decl in &mut body.local_decls {
82            decl.user_ty = None;
83        }
84    }
85
86    fn policy(&self, _ctx: &crate::PassCtx<'_>) -> PassPolicy {
87        // Removes administrative MIR instructions that later passes must never see.
88        PassPolicy::Required
89    }
90}