cairo_lang_sierra/extensions/modules/
nullable.rs1use super::boxing::box_ty;
2use super::snapshot::snapshot_ty;
3use super::utils::reinterpret_cast_signature;
4use crate::define_libfunc_hierarchy;
5use crate::extensions::lib_func::{
6 BranchSignature, DeferredOutputKind, LibfuncSignature, OutputVarInfo, ParamSignature,
7 SierraApChange, SignatureAndTypeGenericLibfunc, SignatureOnlyGenericLibfunc,
8 SignatureSpecializationContext, WrapSignatureAndTypeGenericLibfunc,
9};
10use crate::extensions::type_specialization_context::TypeSpecializationContext;
11use crate::extensions::types::{
12 GenericTypeArgGenericType, GenericTypeArgGenericTypeWrapper, TypeInfo,
13};
14use crate::extensions::{
15 ConcreteType, NamedType, OutputVarReferenceInfo, SpecializationError, args_as_single_type,
16};
17use crate::ids::{ConcreteTypeId, GenericTypeId};
18use crate::program::GenericArg;
19
20#[derive(Default)]
27pub struct NullableTypeWrapped {}
28impl GenericTypeArgGenericType for NullableTypeWrapped {
29 const ID: GenericTypeId = GenericTypeId::new_inline("Nullable");
30 fn calc_info(
31 &self,
32 _context: &dyn TypeSpecializationContext,
33 long_id: crate::program::ConcreteTypeLongId,
34 TypeInfo { storable, droppable, duplicatable, .. }: TypeInfo,
35 ) -> Result<TypeInfo, SpecializationError> {
36 if storable {
37 Ok(TypeInfo { long_id, zero_sized: false, storable: true, droppable, duplicatable })
38 } else {
39 Err(SpecializationError::UnsupportedGenericArg)
40 }
41 }
42}
43pub type NullableType = GenericTypeArgGenericTypeWrapper<NullableTypeWrapped>;
44
45pub struct NullableConcreteType {
46 pub info: TypeInfo,
47 pub ty: ConcreteTypeId,
48}
49impl ConcreteType for NullableConcreteType {
50 fn info(&self) -> &TypeInfo {
51 &self.info
52 }
53}
54
55pub fn nullable_ty(
57 context: &dyn SignatureSpecializationContext,
58 ty: ConcreteTypeId,
59) -> Result<ConcreteTypeId, SpecializationError> {
60 context.get_wrapped_concrete_type(NullableType::id(), ty)
61}
62
63define_libfunc_hierarchy! {
64 pub enum NullableLibfunc {
65 Null(NullLibfunc),
66 NullableFromBox(NullableFromBoxLibfunc),
67 MatchNullable(MatchNullableLibfunc),
68 ForwardSnapshot(NullableForwardSnapshotLibfunc),
69 }, NullableConcreteLibfunc
70}
71
72#[derive(Default)]
74pub struct NullLibfunc {}
75impl SignatureOnlyGenericLibfunc for NullLibfunc {
76 const STR_ID: &'static str = "null";
77
78 fn specialize_signature(
79 &self,
80 context: &dyn SignatureSpecializationContext,
81 args: &[GenericArg],
82 ) -> Result<LibfuncSignature, SpecializationError> {
83 let ty = args_as_single_type(args)?;
84 Ok(LibfuncSignature::new_non_branch(
85 vec![],
86 vec![OutputVarInfo {
87 ty: nullable_ty(context, ty)?,
88 ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
89 }],
90 SierraApChange::Known { new_vars_only: true },
91 ))
92 }
93}
94
95#[derive(Default)]
97pub struct NullableFromBoxLibfuncWrapped {}
98impl SignatureAndTypeGenericLibfunc for NullableFromBoxLibfuncWrapped {
99 const STR_ID: &'static str = "nullable_from_box";
100
101 fn specialize_signature(
102 &self,
103 context: &dyn SignatureSpecializationContext,
104 ty: ConcreteTypeId,
105 ) -> Result<LibfuncSignature, SpecializationError> {
106 Ok(reinterpret_cast_signature(box_ty(context, ty.clone())?, nullable_ty(context, ty)?))
107 }
108}
109pub type NullableFromBoxLibfunc = WrapSignatureAndTypeGenericLibfunc<NullableFromBoxLibfuncWrapped>;
110
111#[derive(Default)]
113pub struct MatchNullableLibfuncWrapped {}
114impl SignatureAndTypeGenericLibfunc for MatchNullableLibfuncWrapped {
115 const STR_ID: &'static str = "match_nullable";
116
117 fn specialize_signature(
118 &self,
119 context: &dyn SignatureSpecializationContext,
120 ty: ConcreteTypeId,
121 ) -> Result<LibfuncSignature, SpecializationError> {
122 Ok(LibfuncSignature {
123 param_signatures: vec![ParamSignature::new(nullable_ty(context, ty.clone())?)],
124 branch_signatures: vec![
125 BranchSignature {
127 vars: vec![],
128 ap_change: SierraApChange::Known { new_vars_only: true },
129 },
130 BranchSignature {
132 vars: vec![OutputVarInfo {
133 ty: box_ty(context, ty)?,
134 ref_info: OutputVarReferenceInfo::SameAsParam { param_idx: 0 },
135 }],
136 ap_change: SierraApChange::Known { new_vars_only: true },
137 },
138 ],
139 fallthrough: Some(0),
140 })
141 }
142}
143pub type MatchNullableLibfunc = WrapSignatureAndTypeGenericLibfunc<MatchNullableLibfuncWrapped>;
144
145#[derive(Default)]
147pub struct NullableForwardSnapshotLibfuncWrapped {}
148impl SignatureAndTypeGenericLibfunc for NullableForwardSnapshotLibfuncWrapped {
149 const STR_ID: &'static str = "nullable_forward_snapshot";
150 fn specialize_signature(
151 &self,
152 context: &dyn SignatureSpecializationContext,
153 ty: ConcreteTypeId,
154 ) -> Result<LibfuncSignature, SpecializationError> {
155 Ok(reinterpret_cast_signature(
156 snapshot_ty(context, nullable_ty(context, ty.clone())?)?,
157 nullable_ty(context, snapshot_ty(context, ty)?)?,
158 ))
159 }
160}
161
162pub type NullableForwardSnapshotLibfunc =
163 WrapSignatureAndTypeGenericLibfunc<NullableForwardSnapshotLibfuncWrapped>;