charon_lib/transform/
remove_drop_never.rs

1//! The MIR code often contains variables with type `!` that come from `panic!`s and similar
2//! `!`-returning` functions.
3//!
4//! We want to get rid of these variables since they are never initialized. The only instruction
5//! that uses them is `StorageLive`/`StorageDead`; we remove these, which may hide some UB but
6//! shouldn't have other consequences.
7//!
8//! The now-unused local will then be removed in `remove_unused_locals`.
9use crate::transform::TransformCtx;
10use crate::ullbc_ast::*;
11
12use super::ctx::UllbcPass;
13
14pub struct Transform;
15impl UllbcPass for Transform {
16    fn transform_body(&self, _ctx: &mut TransformCtx, b: &mut ExprBody) {
17        let locals = b.locals.clone();
18        b.visit_statements(|st: &mut Statement| {
19            // Remove any `Storage{Live,Dead}(x)` where `x` has type `!`. Otherwise leave it unchanged.
20            if let RawStatement::StorageLive(var_id) | RawStatement::StorageDead(var_id) =
21                &st.content
22                && locals[*var_id].ty.is_never()
23            {
24                st.content = RawStatement::Nop;
25            }
26        });
27    }
28}