Skip to main content

charon_lib/transform/add_missing_info/
link_specs.rs

1use crate::ast::*;
2use crate::transform::{TransformCtx, ctx::TransformPass};
3
4pub struct Transform;
5impl TransformPass for Transform {
6    fn transform_ctx(&self, ctx: &mut TransformCtx) {
7        let mut attrs = Vec::new();
8        for (spec_id, fdecl) in ctx.translated.fun_decls.iter_mut_enumerated() {
9            for attr in &fdecl.item_meta.attr_info.attributes {
10                if let Attribute::IsContract { kind, target } = attr {
11                    attrs.push((
12                        *target,
13                        Attribute::HasContract {
14                            kind: kind.clone(),
15                            contract: spec_id,
16                        },
17                    ));
18                }
19            }
20        }
21
22        for (target_id, attr) in attrs {
23            match target_id {
24                MaybeAssocItemId::Free(item_id) => {
25                    let Some(mut item) = ctx.translated.get_item_mut(item_id) else {
26                        continue;
27                    };
28                    item.item_meta().attr_info.attributes.push(attr);
29                }
30                MaybeAssocItemId::Assoc(trait_id, item_id) => {
31                    let Some(trait_decl) = ctx.translated.trait_decls.get_mut(trait_id) else {
32                        continue;
33                    };
34                    let attr_info = match item_id {
35                        AssocItemId::Type(id) => &mut trait_decl.types[id].skip_binder.attr_info,
36                        AssocItemId::Method(id) => {
37                            &mut trait_decl.methods[id].skip_binder.item_meta.attr_info
38                        }
39                        AssocItemId::Const(id) => &mut trait_decl.consts[id].attr_info,
40                    };
41                    attr_info.attributes.push(attr);
42                }
43            }
44        }
45    }
46}