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 (
21 TyKind::Ref(_, deref!(TyKind::Adt(tref1)), kind1),
22 TyKind::Ref(_, deref!(TyKind::Adt(tref2)), kind2),
23 ) = (src_ty.kind(), tgt_ty.kind())
24 && matches!(tref1.id, TypeId::Builtin(BuiltinTy::Array))
25 && matches!(tref2.id, TypeId::Builtin(BuiltinTy::Slice))
26 {
27 assert!(
32 tref1.generics.types.elem_count() == 1
33 && tref1.generics.const_generics.elem_count() == 1
34 );
35 assert!(tref1.generics.types[0] == tref2.generics.types[0]);
36 assert!(kind1 == kind2);
37 let id = match *kind1 {
40 RefKind::Mut => BuiltinFunId::ArrayToSliceMut,
41 RefKind::Shared => BuiltinFunId::ArrayToSliceShared,
42 };
43 let func = FnPtrKind::mk_builtin(id);
44 let generics = GenericArgs::new(
45 [Region::Erased].into(),
46 tref1.generics.types.clone(),
47 tref1.generics.const_generics.clone(),
48 [].into(),
49 );
50 s.kind = StatementKind::Call(Call {
51 func: FnOperand::Regular(FnPtr::new(func, generics)),
52 args: vec![op.clone()],
53 dest: p.clone(),
54 });
55 }
56 }
57 StatementKind::Assign(p, Rvalue::Repeat(op, ty, cg)) => {
59 let id = BuiltinFunId::ArrayRepeat;
62 let func = FnPtrKind::mk_builtin(id);
63 let generics = GenericArgs::new(
64 [Region::Erased].into(),
65 [ty.clone()].into(),
66 [cg.clone()].into(),
67 [].into(),
68 );
69 s.kind = StatementKind::Call(Call {
70 func: FnOperand::Regular(FnPtr::new(func, generics)),
71 args: vec![op.clone()],
72 dest: p.clone(),
73 });
74 }
75 StatementKind::Assign(p, Rvalue::Aggregate(AggregateKind::RawPtr(ty, is_mut), ops)) => {
77 let id = BuiltinFunId::PtrFromParts(is_mut.clone());
78 let func = FnPtrKind::mk_builtin(id);
79 let generics = GenericArgs::new(
80 [Region::Erased].into(),
81 [ty.clone()].into(),
82 [].into(),
83 [].into(),
84 );
85
86 s.kind = StatementKind::Call(Call {
87 func: FnOperand::Regular(FnPtr::new(func, generics)),
88 args: ops.clone(),
89 dest: p.clone(),
90 });
91 }
92 _ => {}
93 }
94}
95
96pub struct Transform;
97impl LlbcPass for Transform {
98 fn transform_body(&self, ctx: &mut TransformCtx, b: &mut ExprBody) {
99 if ctx.options.no_ops_to_function_calls {
100 return;
101 }
102 b.body.visit_statements(&mut transform_st);
103 }
104}