cairo_lang_sierra/extensions/modules/
squashed_felt252_dict.rs

1use super::array::ArrayType;
2use super::felt252::Felt252Type;
3use super::structure::StructType;
4use super::utils::reinterpret_cast_signature;
5use crate::define_libfunc_hierarchy;
6use crate::extensions::lib_func::{
7    LibfuncSignature, SignatureAndTypeGenericLibfunc, SignatureSpecializationContext,
8    WrapSignatureAndTypeGenericLibfunc,
9};
10use crate::extensions::type_specialization_context::TypeSpecializationContext;
11use crate::extensions::types::{
12    GenericTypeArgGenericType, GenericTypeArgGenericTypeWrapper, TypeInfo,
13};
14use crate::extensions::{NamedType, SpecializationError};
15use crate::ids::{ConcreteTypeId, GenericTypeId, UserTypeId};
16use crate::program::GenericArg;
17
18define_libfunc_hierarchy! {
19    pub enum SquashedFelt252DictLibfunc {
20        IntoEntries(SquashedDictIntoEntriesLibfunc),
21    }, SquashedFelt252DictConcreteLibfunc
22}
23/// Type representing a static squashed dictionary from a felt252 to any type of size one.
24#[derive(Default)]
25pub struct SquashedFelt252DictTypeWrapped {}
26impl GenericTypeArgGenericType for SquashedFelt252DictTypeWrapped {
27    const ID: GenericTypeId = GenericTypeId::new_inline("SquashedFelt252Dict");
28
29    fn calc_info(
30        &self,
31        _context: &dyn TypeSpecializationContext,
32        long_id: crate::program::ConcreteTypeLongId,
33        TypeInfo { zero_sized, storable, droppable, .. }: TypeInfo,
34    ) -> Result<TypeInfo, SpecializationError> {
35        // Note: SquashedFelt252Dict is defined as non-duplicatable even if the inner type is
36        // duplicatable to allow libfunc that adds entries to it (treat it similarly to an array).
37        // TODO(Gil): the implementation support values of size 1. Remove when other sizes are
38        // supported.
39        if storable && !zero_sized {
40            Ok(TypeInfo {
41                long_id,
42                storable: true,
43                droppable,
44                duplicatable: false,
45                zero_sized: false,
46            })
47        } else {
48            Err(SpecializationError::UnsupportedGenericArg)
49        }
50    }
51}
52pub type SquashedFelt252DictType = GenericTypeArgGenericTypeWrapper<SquashedFelt252DictTypeWrapped>;
53
54#[derive(Default)]
55pub struct SquashedDictAsEntriesLibfuncWrapped;
56impl SignatureAndTypeGenericLibfunc for SquashedDictAsEntriesLibfuncWrapped {
57    const STR_ID: &'static str = "squashed_felt252_dict_entries";
58
59    fn specialize_signature(
60        &self,
61        context: &dyn SignatureSpecializationContext,
62        ty: ConcreteTypeId,
63    ) -> Result<LibfuncSignature, SpecializationError> {
64        let squashed_dict_ty =
65            context.get_wrapped_concrete_type(SquashedFelt252DictType::id(), ty.clone())?;
66        let felt252_ty = context.get_concrete_type(Felt252Type::id(), &[])?;
67        let tuple_ty = context.get_concrete_type(
68            StructType::id(),
69            &[
70                GenericArg::UserType(UserTypeId::from_string("Tuple")),
71                GenericArg::Type(felt252_ty.clone()),
72                GenericArg::Type(ty.clone()),
73                GenericArg::Type(ty.clone()),
74            ],
75        )?;
76        let array_ty = context.get_wrapped_concrete_type(ArrayType::id(), tuple_ty)?;
77        Ok(reinterpret_cast_signature(squashed_dict_ty, array_ty))
78    }
79}
80pub type SquashedDictIntoEntriesLibfunc =
81    WrapSignatureAndTypeGenericLibfunc<SquashedDictAsEntriesLibfuncWrapped>;