charon_lib/transform/
reconstruct_asserts.rs1use std::collections::HashMap;
7
8use crate::transform::TransformCtx;
9use crate::ullbc_ast::*;
10
11use super::ctx::UllbcPass;
12
13pub struct Transform;
14impl UllbcPass for Transform {
15 fn transform_body(&self, _ctx: &mut TransformCtx, b: &mut ExprBody) {
16 let panics: HashMap<BlockId, AbortKind> = b
20 .body
21 .iter_indexed()
22 .filter_map(|(bid, block)| {
23 if block
24 .statements
25 .iter()
26 .all(|st| st.content.is_storage_live())
27 && let RawTerminator::Abort(abort) = &block.terminator.content
28 {
29 Some((bid, abort.clone()))
30 } else {
31 None
32 }
33 })
34 .collect();
35
36 for block in b.body.iter_mut() {
37 match &block.terminator.content {
38 RawTerminator::Switch {
39 discr: _,
40 targets: SwitchTargets::If(bid0, bid1),
41 } => {
42 let (nbid, expected, abort) = if let Some(abort) = panics.get(bid0) {
43 (*bid1, false, abort)
44 } else if let Some(abort) = panics.get(bid1) {
45 (*bid0, true, abort)
46 } else {
47 continue;
48 };
49
50 let content = std::mem::replace(
51 &mut block.terminator.content,
52 RawTerminator::Goto { target: nbid },
53 );
54 let (discr, _) = content.as_switch().unwrap();
55 block.statements.push(Statement::new(
56 block.terminator.span,
57 RawStatement::Assert(Assert {
58 cond: discr.clone(),
59 expected,
60 on_failure: abort.clone(),
61 }),
62 ));
63 }
64 _ => (),
65 }
66 }
67 }
68}