charon_lib/transform/finish_translation/insert_ptr_metadata.rs
1use crate::transform::TransformCtx;
2use crate::transform::ctx::BodyTransformCtx;
3use crate::{transform::ctx::UllbcPass, ullbc_ast::*};
4
5pub struct Transform;
6
7/// This pass computes the metadata for Rvalue, which is used to create references and raw pointers.
8/// E.g., in cases like:
9/// ```ignore
10/// let x = &[mut] (*some_v).field;
11/// ```
12/// If the `(*some_v).field` is a DST, like `[i32]`, we will need to fetch the metadata, i.e., the length of the slice,
13/// and store it in a local variable, then we have:
14/// ```ignore
15/// let x = Rvalue::Ref { place:(*some_v).field, kind: [mut], ptr_metadata: PtrMetadata(some_v) };
16/// ```
17/// There should be a new local variable introduced to store `PtrMetadata(some_v)`.
18impl UllbcPass for Transform {
19 fn transform_function(&self, ctx: &mut TransformCtx, decl: &mut FunDecl) {
20 decl.transform_ullbc_statements(ctx, |ctx, st: &mut Statement| {
21 st.dyn_visit_in_body_mut(|x: &mut Rvalue| {
22 if let Rvalue::Ref {
23 place,
24 ptr_metadata,
25 ..
26 }
27 | Rvalue::RawPtr {
28 place,
29 ptr_metadata,
30 ..
31 } = x
32 {
33 *ptr_metadata = ctx.compute_place_metadata(place);
34 }
35 });
36 })
37 }
38}