charon_lib/transform/
ops_to_function_calls.rs1use crate::llbc_ast::*;
6use crate::transform::TransformCtx;
7
8use super::ctx::LlbcPass;
9
10fn transform_st(s: &mut Statement) {
11 match &s.content {
12 RawStatement::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 = FunIdOrTraitMethodRef::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 let func = FnOperand::Regular(FnPtr {
51 func: Box::new(func),
52 generics: Box::new(generics),
53 });
54 s.content = RawStatement::Call(Call {
55 func,
56 args: vec![op.clone()],
57 dest: p.clone(),
58 });
59 }
60 }
61 RawStatement::Assign(p, Rvalue::Repeat(op, ty, cg)) => {
63 let id = BuiltinFunId::ArrayRepeat;
66 let func = FunIdOrTraitMethodRef::mk_builtin(id);
67 let generics = GenericArgs::new(
68 [Region::Erased].into(),
69 [ty.clone()].into(),
70 [cg.clone()].into(),
71 [].into(),
72 );
73 let func = FnOperand::Regular(FnPtr {
74 func: Box::new(func),
75 generics: Box::new(generics),
76 });
77 s.content = RawStatement::Call(Call {
78 func,
79 args: vec![op.clone()],
80 dest: p.clone(),
81 });
82 }
83 RawStatement::Assign(p, Rvalue::Aggregate(AggregateKind::RawPtr(ty, is_mut), ops)) => {
85 let id = BuiltinFunId::PtrFromParts(is_mut.clone());
86 let func = FunIdOrTraitMethodRef::mk_builtin(id);
87 let generics = GenericArgs::new(
88 [Region::Erased].into(),
89 [ty.clone()].into(),
90 [].into(),
91 [].into(),
92 );
93
94 let func = FnOperand::Regular(FnPtr {
95 func: Box::new(func),
96 generics: Box::new(generics),
97 });
98 s.content = RawStatement::Call(Call {
99 func,
100 args: ops.clone(),
101 dest: p.clone(),
102 });
103 }
104 _ => {}
105 }
106}
107
108pub struct Transform;
109impl LlbcPass for Transform {
110 fn transform_body(&self, ctx: &mut TransformCtx, b: &mut ExprBody) {
111 if ctx.options.no_ops_to_function_calls {
112 return;
113 }
114 b.body.visit_statements(&mut transform_st);
115 }
116}