charon_lib/transform/ops_to_function_calls.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
//! Desugar some unary/binary operations and the array repeats to function calls.
//! For instance, we desugar ArrayToSlice from an unop to a function call.
//! This allows a more uniform treatment later on.
//! TODO: actually transform all the unops and binops to function calls?
use crate::transform::TransformCtx;
use crate::ullbc_ast::*;
use super::ctx::UllbcPass;
fn transform_st(s: &mut Statement) {
match &s.content {
// Transform the ArrayToSlice unop
RawStatement::Assign(p, Rvalue::UnaryOp(UnOp::ArrayToSlice(ref_kind, ty, cg), op)) => {
// We could avoid the clone operations below if we take the content of
// the statement. In practice, this shouldn't have much impact.
let id = match ref_kind {
RefKind::Mut => BuiltinFunId::ArrayToSliceMut,
RefKind::Shared => BuiltinFunId::ArrayToSliceShared,
};
let func = FunIdOrTraitMethodRef::mk_builtin(id);
let generics = GenericArgs::new(
vec![Region::Erased].into(),
vec![ty.clone()].into(),
vec![cg.clone()].into(),
vec![].into(),
);
let func = FnOperand::Regular(FnPtr { func, generics });
s.content = RawStatement::Call(Call {
func,
args: vec![op.clone()],
dest: p.clone(),
});
}
// Transform the array aggregates to function calls
RawStatement::Assign(p, Rvalue::Repeat(op, ty, cg)) => {
// We could avoid the clone operations below if we take the content of
// the statement. In practice, this shouldn't have much impact.
let id = BuiltinFunId::ArrayRepeat;
let func = FunIdOrTraitMethodRef::mk_builtin(id);
let generics = GenericArgs::new(
vec![Region::Erased].into(),
vec![ty.clone()].into(),
vec![cg.clone()].into(),
vec![].into(),
);
let func = FnOperand::Regular(FnPtr { func, generics });
s.content = RawStatement::Call(Call {
func,
args: vec![op.clone()],
dest: p.clone(),
});
}
_ => {}
}
}
pub struct Transform;
impl UllbcPass for Transform {
fn transform_body(&self, _ctx: &mut TransformCtx<'_>, b: &mut ExprBody) {
b.visit_statements(&mut transform_st);
}
}