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 wrapped_info: &TypeInfo,
35 ) -> Result<TypeInfo, SpecializationError> {
36 if wrapped_info.storable {
37 Ok(TypeInfo {
38 long_id,
39 zero_sized: false,
40 storable: true,
41 droppable: wrapped_info.droppable,
42 duplicatable: wrapped_info.duplicatable,
43 })
44 } else {
45 Err(SpecializationError::UnsupportedGenericArg)
46 }
47 }
48}
49pub type NullableType = GenericTypeArgGenericTypeWrapper<NullableTypeWrapped>;
50
51pub struct NullableConcreteType {
52 pub info: TypeInfo,
53 pub ty: ConcreteTypeId,
54}
55impl ConcreteType for NullableConcreteType {
56 fn info(&self) -> &TypeInfo {
57 &self.info
58 }
59}
60
61pub fn nullable_ty(
63 context: &dyn SignatureSpecializationContext,
64 ty: ConcreteTypeId,
65) -> Result<ConcreteTypeId, SpecializationError> {
66 context.get_wrapped_concrete_type(NullableType::id(), ty)
67}
68
69define_libfunc_hierarchy! {
70 pub enum NullableLibfunc {
71 Null(NullLibfunc),
72 NullableFromBox(NullableFromBoxLibfunc),
73 MatchNullable(MatchNullableLibfunc),
74 ForwardSnapshot(NullableForwardSnapshotLibfunc),
75 }, NullableConcreteLibfunc
76}
77
78#[derive(Default)]
80pub struct NullLibfunc {}
81impl SignatureOnlyGenericLibfunc for NullLibfunc {
82 const STR_ID: &'static str = "null";
83
84 fn specialize_signature(
85 &self,
86 context: &dyn SignatureSpecializationContext,
87 args: &[GenericArg],
88 ) -> Result<LibfuncSignature, SpecializationError> {
89 let ty = args_as_single_type(args)?;
90 Ok(LibfuncSignature::new_non_branch(
91 vec![],
92 vec![OutputVarInfo {
93 ty: nullable_ty(context, ty.clone())?,
94 ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
95 }],
96 SierraApChange::Known { new_vars_only: true },
97 ))
98 }
99}
100
101#[derive(Default)]
103pub struct NullableFromBoxLibfuncWrapped {}
104impl SignatureAndTypeGenericLibfunc for NullableFromBoxLibfuncWrapped {
105 const STR_ID: &'static str = "nullable_from_box";
106
107 fn specialize_signature(
108 &self,
109 context: &dyn SignatureSpecializationContext,
110 ty: ConcreteTypeId,
111 ) -> Result<LibfuncSignature, SpecializationError> {
112 Ok(reinterpret_cast_signature(box_ty(context, ty.clone())?, nullable_ty(context, ty)?))
113 }
114}
115pub type NullableFromBoxLibfunc = WrapSignatureAndTypeGenericLibfunc<NullableFromBoxLibfuncWrapped>;
116
117#[derive(Default)]
119pub struct MatchNullableLibfuncWrapped {}
120impl SignatureAndTypeGenericLibfunc for MatchNullableLibfuncWrapped {
121 const STR_ID: &'static str = "match_nullable";
122
123 fn specialize_signature(
124 &self,
125 context: &dyn SignatureSpecializationContext,
126 ty: ConcreteTypeId,
127 ) -> Result<LibfuncSignature, SpecializationError> {
128 Ok(LibfuncSignature {
129 param_signatures: vec![ParamSignature::new(nullable_ty(context, ty.clone())?)],
130 branch_signatures: vec![
131 BranchSignature {
133 vars: vec![],
134 ap_change: SierraApChange::Known { new_vars_only: true },
135 },
136 BranchSignature {
138 vars: vec![OutputVarInfo {
139 ty: box_ty(context, ty)?,
140 ref_info: OutputVarReferenceInfo::SameAsParam { param_idx: 0 },
141 }],
142 ap_change: SierraApChange::Known { new_vars_only: true },
143 },
144 ],
145 fallthrough: Some(0),
146 })
147 }
148}
149pub type MatchNullableLibfunc = WrapSignatureAndTypeGenericLibfunc<MatchNullableLibfuncWrapped>;
150
151#[derive(Default)]
153pub struct NullableForwardSnapshotLibfuncWrapped {}
154impl SignatureAndTypeGenericLibfunc for NullableForwardSnapshotLibfuncWrapped {
155 const STR_ID: &'static str = "nullable_forward_snapshot";
156 fn specialize_signature(
157 &self,
158 context: &dyn SignatureSpecializationContext,
159 ty: ConcreteTypeId,
160 ) -> Result<LibfuncSignature, SpecializationError> {
161 Ok(reinterpret_cast_signature(
162 snapshot_ty(context, nullable_ty(context, ty.clone())?)?,
163 nullable_ty(context, snapshot_ty(context, ty)?)?,
164 ))
165 }
166}
167
168pub type NullableForwardSnapshotLibfunc =
169 WrapSignatureAndTypeGenericLibfunc<NullableForwardSnapshotLibfuncWrapped>;