diff --git a/corelib/src/array.cairo b/corelib/src/array.cairo index f6cf5d9b021..4d54bf2af22 100644 --- a/corelib/src/array.cairo +++ b/corelib/src/array.cairo @@ -4,6 +4,7 @@ use core::box::BoxTrait; use core::gas::withdraw_gas; use core::option::OptionTrait; use core::serde::Serde; +use core::metaprogramming::TypeEqual; #[derive(Drop)] pub extern type Array; @@ -133,7 +134,21 @@ pub struct Span { impl SpanCopy of Copy>; impl SpanDrop of Drop>; -impl SpanSerde, +Drop> of Serde> { +impl SpanFelt252Serde of Serde> { + fn serialize(self: @Span, ref output: Array) { + (*self).len().serialize(ref output); + serialize_array_helper(*self, ref output) + } + + fn deserialize(ref serialized: Span) -> Option> { + let length: u32 = (*serialized.pop_front()?).try_into()?; + let res = serialized.slice(0, length); + serialized = serialized.slice(length, serialized.len() - length); + Option::Some(res) + } +} + +impl SpanSerde, +Drop, -TypeEqual> of Serde> { fn serialize(self: @Span, ref output: Array) { (*self).len().serialize(ref output); serialize_array_helper(*self, ref output) diff --git a/corelib/src/lib.cairo b/corelib/src/lib.cairo index efe9f258468..695df7db69d 100644 --- a/corelib/src/lib.cairo +++ b/corelib/src/lib.cairo @@ -351,5 +351,8 @@ mod test; // Module for testing only. pub mod testing; +// Metaprogramming. +pub mod metaprogramming; + // Preludes. mod prelude; diff --git a/corelib/src/metaprogramming.cairo b/corelib/src/metaprogramming.cairo new file mode 100644 index 00000000000..87ed62e9db8 --- /dev/null +++ b/corelib/src/metaprogramming.cairo @@ -0,0 +1,5 @@ +/// A trait that can be used to disable implementations based on the types of the generic args. +/// Assumes that `TypeEqualImpl` is the only implementation of this trait. +pub trait TypeEqual {} + +impl TypeEqualImpl of TypeEqual; diff --git a/crates/cairo-lang-starknet/test_data/account__account.contract_class.json b/crates/cairo-lang-starknet/test_data/account__account.contract_class.json index 9fda530b4e8..64ea53a3f5b 100644 --- a/crates/cairo-lang-starknet/test_data/account__account.contract_class.json +++ b/crates/cairo-lang-starknet/test_data/account__account.contract_class.json @@ -2064,7 +2064,7 @@ ], [ 70, - "function_call, core::array::SpanSerde::, core::array::SpanDrop::>::serialize>" + "function_call, core::array::SpanFelt252Serde, core::array::SpanDrop::>::serialize>" ], [ 71, @@ -2416,7 +2416,7 @@ ], [ 158, - "function_call, core::array::SpanSerde::, core::array::SpanDrop::>>" + "function_call, core::array::SpanFelt252Serde, core::array::SpanDrop::>>" ], [ 159, @@ -2788,7 +2788,7 @@ ], [ 251, - "function_call::serialize>" + "function_call" ], [ 252, @@ -3122,7 +3122,7 @@ ], [ 11, - "core::array::ArraySerde::, core::array::SpanSerde::, core::array::SpanDrop::>::serialize" + "core::array::ArraySerde::, core::array::SpanFelt252Serde, core::array::SpanDrop::>::serialize" ], [ 12, @@ -3158,7 +3158,7 @@ ], [ 20, - "core::array::serialize_array_helper::, core::array::SpanSerde::, core::array::SpanDrop::>" + "core::array::serialize_array_helper::, core::array::SpanFelt252Serde, core::array::SpanDrop::>" ], [ 21, @@ -3194,7 +3194,7 @@ ], [ 29, - "core::array::SpanSerde::::serialize" + "core::array::SpanFelt252Serde::serialize" ], [ 30, diff --git a/crates/cairo-lang-starknet/test_data/account__account.sierra b/crates/cairo-lang-starknet/test_data/account__account.sierra index 6d0698ac43f..6832f985bc4 100644 --- a/crates/cairo-lang-starknet/test_data/account__account.sierra +++ b/crates/cairo-lang-starknet/test_data/account__account.sierra @@ -159,7 +159,7 @@ libfunc struct_deconstruct>> = snapshot_take>>; libfunc drop>> = drop>>; libfunc store_temp>>> = store_temp>>>; -libfunc function_call, core::array::SpanSerde::, core::array::SpanDrop::>::serialize> = function_call, core::array::SpanSerde::, core::array::SpanDrop::>::serialize>; +libfunc function_call, core::array::SpanFelt252Serde, core::array::SpanDrop::>::serialize> = function_call, core::array::SpanFelt252Serde, core::array::SpanDrop::>::serialize>; libfunc enum_match, ())>> = enum_match, ())>>; libfunc struct_deconstruct, Unit>> = struct_deconstruct, Unit>>; libfunc function_call = function_call; @@ -247,7 +247,7 @@ libfunc array_len> = array_len>> = struct_construct>>; libfunc store_temp>> = store_temp>>; -libfunc function_call, core::array::SpanSerde::, core::array::SpanDrop::>> = function_call, core::array::SpanSerde::, core::array::SpanDrop::>>; +libfunc function_call, core::array::SpanFelt252Serde, core::array::SpanDrop::>> = function_call, core::array::SpanFelt252Serde, core::array::SpanDrop::>>; libfunc struct_construct, Unit>> = struct_construct, Unit>>; libfunc enum_init, ())>, 0> = enum_init, ())>, 0>; libfunc store_temp, ())>> = store_temp, ())>>; @@ -340,7 +340,7 @@ libfunc enum_init>>> = store_local>>>; libfunc enum_match>>> = enum_match>>>; libfunc unbox> = unbox>; -libfunc function_call::serialize> = function_call::serialize>; +libfunc function_call = function_call; libfunc drop>>> = drop>>>; libfunc drop>>>> = drop>>>>; libfunc drop>> = drop>>; @@ -898,7 +898,7 @@ store_temp([41]) -> ([41]); // 481 store_temp([42]) -> ([42]); // 482 store_temp>>>([50]) -> ([50]); // 483 store_temp>([46]) -> ([46]); // 484 -function_call, core::array::SpanSerde::, core::array::SpanDrop::>::serialize>([41], [42], [50], [46]) -> ([51], [52], [53]); // 485 +function_call, core::array::SpanFelt252Serde, core::array::SpanDrop::>::serialize>([41], [42], [50], [46]) -> ([51], [52], [53]); // 485 enum_match, ())>>([53]) { fallthrough([54]) 500([55]) }; // 486 branch_align() -> (); // 487 struct_deconstruct, Unit>>([54]) -> ([56], [57]); // 488 @@ -1519,7 +1519,7 @@ store_temp([0]) -> ([0]); // 1102 store_temp([1]) -> ([1]); // 1103 store_temp>>([11]) -> ([11]); // 1104 store_temp>([10]) -> ([10]); // 1105 -function_call, core::array::SpanSerde::, core::array::SpanDrop::>>([0], [1], [11], [10]) -> ([12], [13], [14]); // 1106 +function_call, core::array::SpanFelt252Serde, core::array::SpanDrop::>>([0], [1], [11], [10]) -> ([12], [13], [14]); // 1106 enum_match, ())>>([14]) { fallthrough([15]) 1118([16]) }; // 1107 branch_align() -> (); // 1108 struct_deconstruct, Unit>>([15]) -> ([17], [18]); // 1109 @@ -2062,7 +2062,7 @@ store_temp([7]) -> ([7]); // 1645 store_temp([8]) -> ([8]); // 1646 store_temp>([21]) -> ([21]); // 1647 store_temp>([3]) -> ([3]); // 1648 -function_call::serialize>([7], [8], [21], [3]) -> ([22], [23], [24]); // 1649 +function_call([7], [8], [21], [3]) -> ([22], [23], [24]); // 1649 enum_match, ())>>([24]) { fallthrough([25]) 1674([26]) }; // 1650 branch_align() -> (); // 1651 struct_construct>>([4]) -> ([27]); // 1652 @@ -2072,7 +2072,7 @@ store_temp([22]) -> ([22]); // 1655 store_temp([23]) -> ([23]); // 1656 store_temp>>([27]) -> ([27]); // 1657 store_temp>([28]) -> ([28]); // 1658 -function_call, core::array::SpanSerde::, core::array::SpanDrop::>>([22], [23], [27], [28]) -> ([30], [31], [32]); // 1659 +function_call, core::array::SpanFelt252Serde, core::array::SpanDrop::>>([22], [23], [27], [28]) -> ([30], [31], [32]); // 1659 enum_match, ())>>([32]) { fallthrough([33]) 1668([34]) }; // 1660 branch_align() -> (); // 1661 struct_deconstruct, Unit>>([33]) -> ([35], [36]); // 1662 @@ -2637,7 +2637,7 @@ core::Felt252Serde::serialize@867([0]: felt252, [1]: Array) -> (Array::deserialize@872([0]: RangeCheck, [1]: GasBuiltin, [2]: core::array::Span::) -> (RangeCheck, GasBuiltin, core::panics::PanicResult::<(core::array::Span::, core::option::Option::>)>); cairo_level_tests::contracts::account::account::AccountContractImpl::__validate__@923([0]: RangeCheck, [1]: EcOp, [2]: GasBuiltin, [3]: System, [4]: cairo_level_tests::contracts::account::account::ContractState, [5]: Array) -> (RangeCheck, EcOp, GasBuiltin, System, core::panics::PanicResult::<(cairo_level_tests::contracts::account::account::ContractState, core::felt252)>); cairo_level_tests::contracts::account::account::AccountContractImpl::__execute__@950([0]: RangeCheck, [1]: GasBuiltin, [2]: System, [3]: cairo_level_tests::contracts::account::account::ContractState, [4]: Array) -> (RangeCheck, GasBuiltin, System, core::panics::PanicResult::<(cairo_level_tests::contracts::account::account::ContractState, core::array::Array::>)>); -core::array::ArraySerde::, core::array::SpanSerde::, core::array::SpanDrop::>::serialize@1092([0]: RangeCheck, [1]: GasBuiltin, [2]: Snapshot>>, [3]: Array) -> (RangeCheck, GasBuiltin, core::panics::PanicResult::<(core::array::Array::, ())>); +core::array::ArraySerde::, core::array::SpanFelt252Serde, core::array::SpanDrop::>::serialize@1092([0]: RangeCheck, [1]: GasBuiltin, [2]: Snapshot>>, [3]: Array) -> (RangeCheck, GasBuiltin, core::panics::PanicResult::<(core::array::Array::, ())>); cairo_level_tests::contracts::account::account::constructor@1124([0]: GasBuiltin, [1]: System, [2]: cairo_level_tests::contracts::account::account::ContractState, [3]: felt252) -> (GasBuiltin, System, core::panics::PanicResult::<(cairo_level_tests::contracts::account::account::ContractState, ())>); core::starknet::info::get_tx_info@1147([0]: GasBuiltin, [1]: System) -> (GasBuiltin, System, core::panics::PanicResult::<(core::box::Box::,)>); cairo_level_tests::contracts::account::account::public_key::InternalContractMemberStateImpl::read@1171([0]: GasBuiltin, [1]: System, [2]: cairo_level_tests::contracts::account::account::public_key::ContractMemberState) -> (GasBuiltin, System, core::panics::PanicResult::<(core::felt252,)>); @@ -2646,7 +2646,7 @@ core::ecdsa::check_ecdsa_signature@1223([0]: RangeCheck, [1]: EcOp, [2]: felt252 core::array::deserialize_array_helper::@1407([0]: RangeCheck, [1]: GasBuiltin, [2]: core::array::Span::, [3]: Array, [4]: felt252) -> (RangeCheck, GasBuiltin, core::panics::PanicResult::<(core::array::Span::, core::option::Option::>)>); core::starknet::info::get_caller_address@1492([0]: GasBuiltin, [1]: System) -> (GasBuiltin, System, core::panics::PanicResult::<(core::starknet::contract_address::ContractAddress,)>); cairo_level_tests::contracts::account::account::AccountContractImpl::__execute__[expr34]@1516([0]: RangeCheck, [1]: GasBuiltin, [2]: System, [3]: Array, [4]: Array>) -> (RangeCheck, GasBuiltin, System, core::panics::PanicResult::<(core::array::Array::, core::array::Array::>, ())>); -core::array::serialize_array_helper::, core::array::SpanSerde::, core::array::SpanDrop::>@1619([0]: RangeCheck, [1]: GasBuiltin, [2]: core::array::Span::>, [3]: Array) -> (RangeCheck, GasBuiltin, core::panics::PanicResult::<(core::array::Array::, ())>); +core::array::serialize_array_helper::, core::array::SpanFelt252Serde, core::array::SpanDrop::>@1619([0]: RangeCheck, [1]: GasBuiltin, [2]: core::array::Span::>, [3]: Array) -> (RangeCheck, GasBuiltin, core::panics::PanicResult::<(core::array::Array::, ())>); cairo_level_tests::contracts::account::account::public_key::InternalContractMemberStateImpl::write@1710([0]: GasBuiltin, [1]: System, [2]: cairo_level_tests::contracts::account::account::public_key::ContractMemberState, [3]: felt252) -> (GasBuiltin, System, core::panics::PanicResult::<(cairo_level_tests::contracts::account::account::public_key::ContractMemberState, ())>); core::starknet::info::get_execution_info@1747([0]: GasBuiltin, [1]: System) -> (GasBuiltin, System, core::panics::PanicResult::<(core::box::Box::,)>); core::starknet::SyscallResultTraitImpl::::unwrap_syscall@1775([0]: core::result::Result::>) -> (core::panics::PanicResult::<(core::felt252,)>); @@ -2655,7 +2655,7 @@ core::ec::EcPointAdd::add@1811([0]: EcPoint, [1]: EcPoint) -> (EcPoint); core::ec::EcPointSub::sub@1839([0]: EcPoint, [1]: EcPoint) -> (EcPoint); core::starknet::account::CallSerde::deserialize@1852([0]: RangeCheck, [1]: GasBuiltin, [2]: core::array::Span::) -> (RangeCheck, GasBuiltin, core::panics::PanicResult::<(core::array::Span::, core::option::Option::)>); core::starknet::SyscallResultTraitImpl::>::unwrap_syscall@1922([0]: core::result::Result::, core::array::Array::>) -> (core::panics::PanicResult::<(core::array::Span::,)>); -core::array::SpanSerde::::serialize@1934([0]: RangeCheck, [1]: GasBuiltin, [2]: core::array::Span::, [3]: Array) -> (RangeCheck, GasBuiltin, core::panics::PanicResult::<(core::array::Array::, ())>); +core::array::SpanFelt252Serde::serialize@1934([0]: RangeCheck, [1]: GasBuiltin, [2]: core::array::Span::, [3]: Array) -> (RangeCheck, GasBuiltin, core::panics::PanicResult::<(core::array::Array::, ())>); core::starknet::SyscallResultTraitImpl::<()>::unwrap_syscall@1966([0]: core::result::Result::<(), core::array::Array::>) -> (core::panics::PanicResult::<((),)>); core::starknet::SyscallResultTraitImpl::>::unwrap_syscall@1978([0]: core::result::Result::, core::array::Array::>) -> (core::panics::PanicResult::<(core::box::Box::,)>); core::starknet::contract_address::ContractAddressSerde::deserialize@1990([0]: RangeCheck, [1]: core::array::Span::) -> (RangeCheck, core::array::Span::, core::option::Option::);