charon_lib/transform/simplify_output/
ops_to_function_calls.rs1use crate::llbc_ast::*;
6use crate::transform::TransformCtx;
7
8use crate::transform::ctx::LlbcPass;
9
10fn transform_st(s: &mut Statement) {
11 match &s.kind {
12 StatementKind::Assign(
14 p,
15 Rvalue::UnaryOp(
16 UnOp::Cast(CastKind::Unsize(src_ty, tgt_ty, UnsizingMetadata::Length(_))),
17 op,
18 ),
19 ) => {
20 if let (TyKind::Ref(_, ty1, kind1), TyKind::Ref(_, ty2, kind2)) =
21 (src_ty.kind(), tgt_ty.kind())
22 && let TyKind::Array(arr_ty, len) = ty1.kind()
23 && let TyKind::Slice(..) = ty2.kind()
24 {
25 assert!(kind1 == kind2);
30 let id = match *kind1 {
33 RefKind::Mut => BuiltinFunId::ArrayToSliceMut,
34 RefKind::Shared => BuiltinFunId::ArrayToSliceShared,
35 };
36 let func = FnPtrKind::mk_builtin(id);
37 let generics = GenericArgs::new(
38 [Region::Erased].into(),
39 [arr_ty.clone()].into(),
40 [*len.clone()].into(),
41 [].into(),
42 );
43 s.kind = StatementKind::Call {
44 call: Call {
45 func: FnOperand::Regular(FnPtr::new(func, generics)),
46 args: vec![op.clone()],
47 dest: p.clone(),
48 },
49 on_unwind: Block::new_unreachable(s.span),
50 };
51 }
52 }
53 StatementKind::Assign(p, Rvalue::Repeat(op, ty, cg)) => {
55 let id = BuiltinFunId::ArrayRepeat;
58 let func = FnPtrKind::mk_builtin(id);
59 let generics = GenericArgs::new(
60 [].into(),
61 [ty.clone()].into(),
62 [*cg.clone()].into(),
63 [].into(),
64 );
65 s.kind = StatementKind::Call {
66 call: Call {
67 func: FnOperand::Regular(FnPtr::new(func, generics)),
68 args: vec![op.clone()],
69 dest: p.clone(),
70 },
71 on_unwind: Block::new_unreachable(s.span),
72 };
73 }
74 StatementKind::Assign(p, Rvalue::Aggregate(AggregateKind::RawPtr(ty, is_mut), ops)) => {
76 let id = BuiltinFunId::PtrFromParts(*is_mut);
77 let func = FnPtrKind::mk_builtin(id);
78 let generics = GenericArgs::new(
79 [Region::Erased].into(),
80 [ty.clone()].into(),
81 [].into(),
82 [].into(),
83 );
84
85 s.kind = StatementKind::Call {
86 call: Call {
87 func: FnOperand::Regular(FnPtr::new(func, generics)),
88 args: ops.clone(),
89 dest: p.clone(),
90 },
91 on_unwind: Block::new_unreachable(s.span),
92 };
93 }
94 _ => {}
95 }
96}
97
98pub struct Transform;
99impl LlbcPass for Transform {
100 fn should_run(&self, options: &crate::options::TranslateOptions) -> bool {
101 options.ops_to_function_calls
102 }
103
104 fn transform_body(&self, _ctx: &mut TransformCtx, b: &mut ExprBody) {
105 b.body.visit_statements(&mut transform_st);
106 }
107}