From 187146bdc2d7f1defc59fb7810808343da13c898 Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Fri, 5 Apr 2024 10:52:45 +0100 Subject: [PATCH 1/6] Cache in front of check_if_trait_constraints_are_satisfied_for_type (#5827) ## Description Partially fixes https://github.com/FuelLabs/sway/issues/5781. This reduces the problem of millions of `TypeInfo`s being created. For more details see: https://github.com/FuelLabs/sway/pull/5782 ## Checklist - [ ] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [ ] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: Joshua Batty --- .../semantic_analysis/namespace/trait_map.rs | 59 +++++++++++++++++-- .../sway-lib-std-vec/reduced_lib.config | 1 - 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/sway-core/src/semantic_analysis/namespace/trait_map.rs b/sway-core/src/semantic_analysis/namespace/trait_map.rs index 01254f9bee9..84910aa9666 100644 --- a/sway-core/src/semantic_analysis/namespace/trait_map.rs +++ b/sway-core/src/semantic_analysis/namespace/trait_map.rs @@ -2,8 +2,10 @@ use std::{ cmp::Ordering, collections::{BTreeSet, HashMap}, fmt, + hash::{DefaultHasher, Hash, Hasher}, }; +use hashbrown::HashSet; use sway_error::{ error::CompileError, handler::{ErrorEmitted, Handler}, @@ -148,6 +150,7 @@ type TraitImpls = Vec; #[derive(Clone, Debug, Default)] pub(crate) struct TraitMap { trait_impls: TraitImpls, + satisfied_cache: hashbrown::HashSet, } pub(crate) enum IsImplSelf { @@ -425,7 +428,10 @@ impl TraitMap { }; let entry = TraitEntry { key, value }; let trait_impls: TraitImpls = vec![entry]; - let trait_map = TraitMap { trait_impls }; + let trait_map = TraitMap { + trait_impls, + satisfied_cache: HashSet::default(), + }; self.extend(trait_map, engines); } @@ -1176,6 +1182,53 @@ impl TraitMap { ) -> Result<(), ErrorEmitted> { let type_engine = engines.te(); + // resolving trait constraints require a concrete type, we need to default numeric to u64 + type_engine.decay_numeric(handler, engines, type_id, access_span)?; + + if constraints.is_empty() { + return Ok(()); + } + + // Check we can use the cache + let mut hasher = DefaultHasher::default(); + type_id.hash(&mut hasher); + for c in constraints { + c.hash(&mut hasher, engines); + } + let hash = hasher.finish(); + + if self.satisfied_cache.contains(&hash) { + return Ok(()); + } + + // Call the real implementation and cache when true + match self.check_if_trait_constraints_are_satisfied_for_type_inner( + handler, + type_id, + constraints, + access_span, + engines, + try_inserting_trait_impl_on_failure, + ) { + Ok(()) => { + self.satisfied_cache.insert(hash); + Ok(()) + } + r => r, + } + } + + fn check_if_trait_constraints_are_satisfied_for_type_inner( + &mut self, + handler: &Handler, + type_id: TypeId, + constraints: &[TraitConstraint], + access_span: &Span, + engines: &Engines, + try_inserting_trait_impl_on_failure: TryInsertingTraitImplOnFailure, + ) -> Result<(), ErrorEmitted> { + let type_engine = engines.te(); + // If the type is generic/placeholder, its definition needs to contains all // constraints match &*type_engine.get(type_id) { @@ -1207,9 +1260,6 @@ impl TraitMap { let _decl_engine = engines.de(); let unify_check = UnifyCheck::non_dynamic_equality(engines); - // resolving trait constraints require a concrete type, we need to default numeric to u64 - type_engine.decay_numeric(handler, engines, type_id, access_span)?; - let all_impld_traits: BTreeSet<(Ident, TypeId)> = self .trait_impls .iter() @@ -1307,6 +1357,7 @@ impl TraitMap { }); } } + Ok(()) }) } diff --git a/test/src/e2e_vm_tests/reduced_std_libs/sway-lib-std-vec/reduced_lib.config b/test/src/e2e_vm_tests/reduced_std_libs/sway-lib-std-vec/reduced_lib.config index 91eeaf588c4..ab261db638c 100644 --- a/test/src/e2e_vm_tests/reduced_std_libs/sway-lib-std-vec/reduced_lib.config +++ b/test/src/e2e_vm_tests/reduced_std_libs/sway-lib-std-vec/reduced_lib.config @@ -8,4 +8,3 @@ revert.sw vec.sw iterator.sw convert.sw - From 53fdb8d11332d452ab9a892a407f766fb3507022 Mon Sep 17 00:00:00 2001 From: Cameron Carstens Date: Mon, 8 Apr 2024 21:54:31 +0900 Subject: [PATCH 2/6] Add `ZERO_U256` constant (#5829) ## Description We provide a `ZERO_B256` but do not provide a `ZERO_U256` convenience constant. This has added. Closes #5828 ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --- sway-lib-std/src/constants.sw | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sway-lib-std/src/constants.sw b/sway-lib-std/src/constants.sw index 628444afc92..02b8fd77f39 100644 --- a/sway-lib-std/src/constants.sw +++ b/sway-lib-std/src/constants.sw @@ -33,6 +33,19 @@ pub const BASE_ASSET_ID: AssetId = AssetId::from(ZERO_B256); /// ``` pub const ZERO_B256 = 0x0000000000000000000000000000000000000000000000000000000000000000; +/// A u256 of zero value. +/// +/// # Examples +/// +/// ```sway +/// use std::constants::ZERO_U256; +/// +/// fn foo() { +/// assert(ZERO_U256 == u256::from(0_u64)); +/// } +/// ``` +pub const ZERO_U256 = 0x00u256; + /// The default Sub Id for assets. /// /// # Examples From 5e45116727707ddc9fdb85725aaf45443adc7ef5 Mon Sep 17 00:00:00 2001 From: GearedPaladin <98220490+GearedPaladin@users.noreply.github.com> Date: Mon, 8 Apr 2024 19:37:28 +0530 Subject: [PATCH 3/6] Fix ZERO_B256 docs (#5835) ## Description The example wont compile as the function returns a assetid instead of b256, the proposed changes fixes it so the example should compile now. ## Checklist - [ ] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [ ] I have requested a review from the relevant team or maintainers. Co-authored-by: IGI-111 --- sway-lib-std/src/constants.sw | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sway-lib-std/src/constants.sw b/sway-lib-std/src/constants.sw index 02b8fd77f39..a41f6d74426 100644 --- a/sway-lib-std/src/constants.sw +++ b/sway-lib-std/src/constants.sw @@ -20,7 +20,7 @@ use ::asset_id::AssetId; /// ``` pub const BASE_ASSET_ID: AssetId = AssetId::from(ZERO_B256); -/// A B256 of zero value. +/// A b256 of zero value. /// /// # Examples /// @@ -28,7 +28,7 @@ pub const BASE_ASSET_ID: AssetId = AssetId::from(ZERO_B256); /// use std::{call_frames::msg_asset_id, constants::ZERO_B256}; /// /// fn foo() { -/// assert(ZERO_B256 == msg_asset_id()); +/// assert(ZERO_B256 == msg_asset_id().bits()); /// } /// ``` pub const ZERO_B256 = 0x0000000000000000000000000000000000000000000000000000000000000000; From a386e7be4df4d2f2e7cd04900dac9f44e2e61298 Mon Sep 17 00:00:00 2001 From: Cameron Carstens Date: Tue, 9 Apr 2024 07:54:18 +0900 Subject: [PATCH 4/6] Expand Native Asset Docs (#5808) ## Description - Additional docs covering Native Assets including: - EVM vs FuelVM Assets - What `AssetId` is - How to use `AssetId` - What `SubId` is - What the default asset is - How to mint coins - How to burn coins - How to transfer coins - How to check contract balances - How to check transaction values - How to receive assets in contracts - ERC-20 equivalent example - ERC-1155 equivalent example - The Liquidity Pool example has been moved to its own section in examples These changes were originally included in https://github.com/FuelLabs/sway/pull/5806 but have been pulled out into a separate PR ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [x] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --------- Co-authored-by: K1-R1 <77465250+K1-R1@users.noreply.github.com> --- docs/book/spell-check-custom-words.txt | 3 +- docs/book/src/SUMMARY.md | 1 + .../blockchain-development/native_assets.md | 451 +++++++++++++++++- docs/book/src/examples/liquidity_pool.md | 11 + examples/native_asset/src/main.sw | 87 +++- 5 files changed, 521 insertions(+), 32 deletions(-) create mode 100644 docs/book/src/examples/liquidity_pool.md diff --git a/docs/book/spell-check-custom-words.txt b/docs/book/spell-check-custom-words.txt index ce6fe64966b..680eb4f7762 100644 --- a/docs/book/spell-check-custom-words.txt +++ b/docs/book/spell-check-custom-words.txt @@ -187,4 +187,5 @@ arity tuple's unary SRC -DEX \ No newline at end of file +DEX +SubId \ No newline at end of file diff --git a/docs/book/src/SUMMARY.md b/docs/book/src/SUMMARY.md index 3db1d0b8ddc..786770abed2 100644 --- a/docs/book/src/SUMMARY.md +++ b/docs/book/src/SUMMARY.md @@ -11,6 +11,7 @@ - [Counter](./examples/counter.md) - [`FizzBuzz`](./examples/fizzbuzz.md) - [Wallet Smart Contract](./examples/wallet_smart_contract.md) + - [Liquidity Pool](./examples/liquidity_pool.md) - [Program Types](./sway-program-types/index.md) - [Contracts](./sway-program-types/smart_contracts.md) - [Libraries](./sway-program-types/libraries.md) diff --git a/docs/book/src/blockchain-development/native_assets.md b/docs/book/src/blockchain-development/native_assets.md index 6796e77cc45..143ac06adf7 100644 --- a/docs/book/src/blockchain-development/native_assets.md +++ b/docs/book/src/blockchain-development/native_assets.md @@ -1,32 +1,457 @@ -# Native Support for Multiple Asset Types +# Native Assets The FuelVM has built-in support for working with multiple assets. -What does this mean in practice? +## Key Differences Between EVM and FuelVM Assets -As in the EVM, sending ETH to an address or contract is an operation built into the FuelVM, meaning it doesn't rely on the existence of some token smart contract to update balances to track ownership. +### ERC-20 vs Native Asset -However, unlike the EVM, the process for sending _any_ native asset is the same. This means that while you would still need a smart contract to handle the minting and burning of fungible assets, the sending and receiving of these assets can be done independently of the asset contract. - +On the EVM, Ether is the native asset. As such, sending ETH to an address or contract is an operation built into the EVM, meaning it doesn't rely on the existence of a smart contract to update balances to track ownership as with ERC-20 tokens. + +On the FuelVM, _all_ assets are native and the process for sending _any_ native asset is the same. + +While you would still need a smart contract to handle the minting and burning of assets, the sending and receiving of these assets can be done independently of the asset contract. + +> **NOTE** It is important to note that Fuel does not have tokens. + +### No Token Approvals + +An advantage Native Assets bring is that there is no need for token approvals; as with Ether on the EVM. With millions of dollars hacked every year due to misused token approvals, the FuelVM eliminates this attack vector. + +### Asset vs Coin vs Token + +An "Asset" is a Native Asset on Fuel and has the associated `AssetId` type. Assets are distinguishable from one another. A "Coin" represents a singular unit of an Asset. Coins of the same Asset are not distinguishable from one another. + +Fuel does not use tokens like other ecosystems such as Ethereum and uses Native Assets with a UTXO design instead. + +## The `AssetId` type + +The `AssetId` type represents any Native Asset on Fuel. An `AssetId` is used for interacting with an asset on the network. + +The `AssetId` of any Native Asset on Fuel is calculated by taking the SHA256 hash digest of the originating `ContractId` that minted the asset and a `SubId` i.e. `sha256((contract_id, sub_id))`. + +### Creating a New `AssetId` + +There are 3 ways to instantiate a new `AssetId`: + +#### Default + +When a contract will only ever mint a single asset, it is recommended to use the `DEFAULT_ASSET_ID` sub id. This is referred to as the default asset of a contract. + +To get the default asset from an internal contract call, call the `default()` function: + +```sway +{{#include ../../../../examples/native_asset/src/main.sw:default_asset_id}} +``` + +#### New + +If a contract mints multiple assets or if the asset has been minted by an external contract, the `new()` function will be needed. The `new()` function takes the `ContractId` of the contract which minted the token as well as a `SubId`. + +To create a new `AssetId` using a `ContractId` and `SubId`, call the `new()` function: + +```sway +{{#include ../../../../examples/native_asset/src/main.sw:new_asset_id}} +``` + +#### From + +In the case where the `b256` value of an asset is already known, you may call the `from()` function with the `b256` value. + +```sway +{{#include ../../../../examples/native_asset/src/main.sw:from_asset_id}} +``` + +## The `SubId` type + +The SubId is used to differentiate between different assets that are created by the same contract. The `SubId` is a `b256` value. + +When creating an single new asset on Fuel, we recommend using the `DEFAULT_ASSET_ID`. + +## The Base Asset + +On the Fuel Network, the base asset is Ether. This is the only asset on the Fuel Network that does not have a `SubId`. + +The Base Asset can be returned anytime by calling the `base_asset_id()` function of the `AssetId` type. + +```sway +{{#include ../../../../examples/native_asset/src/main.sw:base_asset}} +``` + +## Basic Native Asset Functionality + +### Minting A Native Asset + +To mint a new asset, the `std::asset::mint()` function must be called internally within a contract. A `SubId` and amount of coins must be provided. These newly minted coins will be owned by the contract which minted them. To mint another asset from the same contract, replace the `DEFAULT_SUB_ID` with your desired `SubId`. + +```sway +{{#include ../../../../examples/native_asset/src/main.sw:mint_asset}} +``` + +You may also mint an asset to a specific entity with the `std::asset::mint_to()` function. Be sure to provide a target `Identity` that will own the newly minted coins. + +```sway +{{#include ../../../../examples/native_asset/src/main.sw:mint_to_asset}} +``` + +### Burning a Native Asset + +To burn an asset, the `std::asset::burn()` function must be called internally from the contract which minted them. The `SubId` used to mint the coins and amount must be provided. The burned coins must be owned by the contract. When an asset is burned it doesn't exist anymore. + +```sway +{{#include ../../../../examples/native_asset/src/main.sw:burn_asset}} +``` + +### Transfer a Native Asset + +To internally transfer a Native Asset, the `std::asset::transfer()` function must be called. A target `Identity` or user must be provided as well as the `AssetId` of the asset and an amount. + +```sway +{{#include ../../../../examples/native_asset/src/main.sw:transfer_asset}} +``` + +### Native Asset And Transactions -## Liquidity Pool Example +#### Getting The Transaction Asset -All contracts in Fuel can mint and burn their own native asset. Contracts can also receive and transfer any native asset including their own. Internal balances of all native assets pushed through calls or minted by the contract are tracked by the FuelVM and can be queried at any point using the balance_of function from the `std` library. Therefore, there is no need for any manual accounting of the contract's balances using persistent storage. +To query for the Native Asset sent in a transaction, you may call the `std::call_frames::msg_asset_id()` function. -The `std` library provides handy methods for accessing Fuel's native asset operations. +```sway +{{#include ../../../../examples/native_asset/src/main.sw:msg_asset_id}} +``` + +#### Getting The Transaction Amount + +To query for the amount of coins sent in a transaction, you may call the `std::context::msg_amount()` function. + +```sway +{{#include ../../../../examples/native_asset/src/main.sw:msg_amount}} +``` + +### Native Assets and Contracts -In this example, we show a basic liquidity pool contract minting its own native asset LP asset. +#### Checking A Contract's Balance + +To internally check a contract's balance, call the `std::context::this_balance()` function with the corresponding `AssetId`. + +```sway +{{#include ../../../../examples/native_asset/src/main.sw:this_balance}} +``` + +To check the balance of an external contract, call the `std::context::balance_of()` function with the corresponding `AssetId`. ```sway -{{#include ../../../../examples/liquidity_pool/src/main.sw}} +{{#include ../../../../examples/native_asset/src/main.sw:balance_of}} ``` -## Native Asset Example +> **NOTE** Due to the FuelVM's UTXO design, balances of `Address`'s cannot be returned in the Sway Language. This must be done off-chain using the SDK. + +#### Receiving Native Assets In A Contract -In this example, we show a native asset contract with more minting, burning and transferring capabilities. +By default, a contract may not receive a Native Asset in a contract call. To allow transferring of assets to the contract, add the `#[payable]` attribute to the function. ```sway -{{#include ../../../../examples/native_asset/src/main.sw}} +{{#include ../../../../examples/native_asset/src/main.sw:payable}} +``` + +## Native Asset Standards + +There are a number of standards developed to enable further functionality for Native Assets and help cross contract functionality. Information on standards can be found in the [Sway Standards Repo](https://github.com/FuelLabs/sway-standards). + +We currently have the following standards for Native Assets: + +- [SRC-20; Native Asset Standard](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-20.md) defines the implementation of a standard API for Native Assets using the Sway Language. +- [SRC-3; Mint and Burn Standard](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-3.md) is used to enable mint and burn functionality for Native Assets. +- [SRC-7; Arbitrary Asset Metadata Standard](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-7.md) is used to store metadata for Native Assets. +- [SRC-6; Vault Standard](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-6.md) defines the implementation of a standard API for asset vaults developed in Sway. + + +## Single Native Asset Example + +In this fully fleshed out example, we show a native asset contract which mints a single asset. This is the equivalent to the ERC-20 Standard use in Ethereum. Note there are no token approval functions. + +It implements the [SRC-20; Native Asset](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-20.md), [SRC-3; Mint and Burn](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-3.md), and [SRC-5; Ownership](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-5.md) standards. + +```sway +// ERC20 equivalent in Sway. +contract; + +use src3::SRC3; +use src5::{SRC5, State, AccessError}; +use src20::SRC20; +use std::{ + asset::{ + burn, + mint_to, + }, + call_frames::{ + contract_id, + msg_asset_id, + }, + constants::DEFAULT_SUB_ID, + context::msg_amount, + string::String, +}; + +configurable { + DECIMALS: u8 = 9u8, + NAME: str[7] = __to_str_array("MyAsset"), + SYMBOL: str[5] = __to_str_array("MYTKN"), +} + +storage { + total_supply: u64 = 0, + owner: State = State::Uninitialized, +} + +// Native Asset Standard +impl SRC20 for Contract { + #[storage(read)] + fn total_assets() -> u64 { + 1 + } + + #[storage(read)] + fn total_supply(asset: AssetId) -> Option { + if asset == AssetId::default() { + Some(storage.total_supply.read()) + } else { + None + } + } + + #[storage(read)] + fn name(asset: AssetId) -> Option { + if asset == AssetId::default() { + Some(String::from_ascii_str(from_str_array(NAME))) + } else { + None + } + } + + #[storage(read)] + fn symbol(asset: AssetId) -> Option { + if asset == AssetId::default() { + Some(String::from_ascii_str(from_str_array(SYMBOL))) + } else { + None + } + } + + #[storage(read)] + fn decimals(asset: AssetId) -> Option { + if asset == AssetId::default() { + Some(DECIMALS) + } else { + None + } + } +} + +// Ownership Standard +impl SRC5 for Contract { + #[storage(read)] + fn owner() -> State { + storage.owner.read() + } +} + +// Mint and Burn Standard +impl SRC3 for Contract { + #[storage(read, write)] + fn mint(recipient: Identity, sub_id: SubId, amount: u64) { + require(sub_id == DEFAULT_SUB_ID, "incorrect-sub-id"); + require_access_owner(); + + storage + .total_supply + .write(amount + storage.total_supply.read()); + mint_to(recipient, DEFAULT_SUB_ID, amount); + } + + #[storage(read, write)] + fn burn(sub_id: SubId, amount: u64) { + require(sub_id == DEFAULT_SUB_ID, "incorrect-sub-id"); + require(msg_amount() >= amount, "incorrect-amount-provided"); + require( + msg_asset_id() == AssetId::default(), + "incorrect-asset-provided", + ); + require_access_owner(); + + storage + .total_supply + .write(storage.total_supply.read() - amount); + burn(DEFAULT_SUB_ID, amount); + } +} + +abi SingleAsset { + #[storage(read, write)] + fn constructor(owner_: Identity); +} + +impl SingleAsset for Contract { + #[storage(read, write)] + fn constructor(owner_: Identity) { + require(storage.owner.read() == State::Uninitialized, "owner-initialized"); + storage.owner.write(State::Initialized(owner_)); + } +} + +#[storage(read)] +fn require_access_owner() { + require( + storage.owner.read() == State::Initialized(msg_sender().unwrap()), + AccessError::NotOwner, + ); +} +``` + +## Multi Native Asset Example + +In this fully fleshed out example, we show a native asset contract which mints multiple assets. This is the equivalent to the ERC-1155 Standard use in Ethereum. Note there are no token approval functions. + +It implements the [SRC-20; Native Asset](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-20.md), [SRC-3; Mint and Burn](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-3.md), and [SRC-5; Ownership](https://github.com/FuelLabs/sway-standards/blob/master/SRCs/src-5.md) standards. + +```sway +// ERC1155 equivalent in Sway. +contract; + +use src5::{SRC5, State, AccessError}; +use src20::SRC20; +use src3::SRC3; +use std::{ + asset::{ + burn, + mint_to, + }, + call_frames::{ + contract_id, + msg_asset_id, + }, + hash::{ + Hash, + }, + context::this_balance, + storage::storage_string::*, + string::String +}; + +storage { + total_assets: u64 = 0, + total_supply: StorageMap = StorageMap {}, + name: StorageMap = StorageMap {}, + symbol: StorageMap = StorageMap {}, + decimals: StorageMap = StorageMap {}, + owner: State = State::Uninitialized, +} + +// Native Asset Standard +impl SRC20 for Contract { + #[storage(read)] + fn total_assets() -> u64 { + storage.total_assets.read() + } + + #[storage(read)] + fn total_supply(asset: AssetId) -> Option { + storage.total_supply.get(asset).try_read() + } + + #[storage(read)] + fn name(asset: AssetId) -> Option { + storage.name.get(asset).read_slice() + } + + #[storage(read)] + fn symbol(asset: AssetId) -> Option { + storage.symbol.get(asset).read_slice() + } + + #[storage(read)] + fn decimals(asset: AssetId) -> Option { + storage.decimals.get(asset).try_read() + } +} + +// Mint and Burn Standard +impl SRC3 for Contract { + #[storage(read, write)] + fn mint(recipient: Identity, sub_id: SubId, amount: u64) { + require_access_owner(); + let asset_id = AssetId::new(contract_id(), sub_id); + let supply = storage.total_supply.get(asset_id).try_read(); + if supply.is_none() { + storage.total_assets.write(storage.total_assets.try_read().unwrap_or(0) + 1); + } + let current_supply = supply.unwrap_or(0); + storage.total_supply.insert(asset_id, current_supply + amount); + mint_to(recipient, sub_id, amount); + } + + #[storage(read, write)] + fn burn(sub_id: SubId, amount: u64) { + require_access_owner(); + let asset_id = AssetId::new(contract_id(), sub_id); + require(this_balance(asset_id) >= amount, "not-enough-coins"); + + let supply = storage.total_supply.get(asset_id).try_read(); + let current_supply = supply.unwrap_or(0); + storage.total_supply.insert(asset_id, current_supply - amount); + burn(sub_id, amount); + } +} + +abi MultiAsset { + #[storage(read, write)] + fn constructor(owner_: Identity); + + #[storage(read, write)] + fn set_name(asset: AssetId, name: String); + + #[storage(read, write)] + fn set_symbol(asset: AssetId, symbol: String); + + #[storage(read, write)] + fn set_decimals(asset: AssetId, decimals: u8); +} + +impl MultiAsset for Contract { + #[storage(read, write)] + fn constructor(owner_: Identity) { + require(storage.owner.read() == State::Uninitialized, "owner-initialized"); + storage.owner.write(State::Initialized(owner_)); + } + + #[storage(read, write)] + fn set_name(asset: AssetId, name: String) { + require_access_owner(); + storage.name.insert(asset, StorageString {}); + storage.name.get(asset).write_slice(name); + } + + #[storage(read, write)] + fn set_symbol(asset: AssetId, symbol: String) { + require_access_owner(); + storage.symbol.insert(asset, StorageString {}); + storage.symbol.get(asset).write_slice(symbol); + } + + #[storage(read, write)] + fn set_decimals(asset: AssetId, decimals: u8) { + require_access_owner(); + storage.decimals.insert(asset, decimals); + } +} + +#[storage(read)] +fn require_access_owner() { + require( + storage.owner.read() == State::Initialized(msg_sender().unwrap()), + AccessError::NotOwner, + ); +} ``` diff --git a/docs/book/src/examples/liquidity_pool.md b/docs/book/src/examples/liquidity_pool.md new file mode 100644 index 00000000000..36dabba7f86 --- /dev/null +++ b/docs/book/src/examples/liquidity_pool.md @@ -0,0 +1,11 @@ +# Liquidity Pool Example + +All contracts in Fuel can mint and burn their own native asset. Contracts can also receive and transfer any native asset including their own. Internal balances of all native assets pushed through calls or minted by the contract are tracked by the FuelVM and can be queried at any point using the `balance_of` function from the `std` library. Therefore, there is no need for any manual accounting of the contract's balances using persistent storage. + +The `std` library provides handy methods for accessing Fuel's native asset operations. + +In this example, we show a basic liquidity pool contract minting its own native asset LP asset. + +```sway +{{#include ../../../../examples/liquidity_pool/src/main.sw}} +``` diff --git a/examples/native_asset/src/main.sw b/examples/native_asset/src/main.sw index d0645407173..8b7ca26bc44 100644 --- a/examples/native_asset/src/main.sw +++ b/examples/native_asset/src/main.sw @@ -1,56 +1,107 @@ contract; -use std::{asset::*, constants::DEFAULT_SUB_ID, context::*}; +use std::{asset::*, call_frames::msg_asset_id, constants::DEFAULT_SUB_ID, context::*}; abi NativeAsset { fn mint_coins(mint_amount: u64); fn burn_coins(burn_amount: u64); - fn force_transfer_coins(coins: u64, asset_id: AssetId, target: ContractId); - fn transfer_coins_to_output(coins: u64, asset_id: AssetId, recipient: Address); + fn transfer_coins(coins: u64, asset_id: AssetId, target: Identity); + #[payable] fn deposit(); fn get_balance(target: ContractId, asset_id: AssetId) -> u64; - fn mint_and_send_to_contract(amount: u64, destination: ContractId); - fn mint_and_send_to_address(amount: u64, recipient: Address); + fn get_msg_amount(); + fn this_balance(asset_id: AssetId) -> u64; + fn get_msg_asset_id(); + fn mint_coins_to(target_identity: Identity, mint_amount: u64); } impl NativeAsset for Contract { /// Mint an amount of this contracts native asset to the contracts balance. fn mint_coins(mint_amount: u64) { + // ANCHOR: mint_asset mint(DEFAULT_SUB_ID, mint_amount); + // ANCHOR_END: mint_asset + } + + fn mint_coins_to(target_identity: Identity, mint_amount: u64) { + // ANCHOR: mint_to_asset + mint_to(target_identity, DEFAULT_SUB_ID, mint_amount); + // ANCHOR_END: mint_to_asset } /// Burn an amount of this contracts native asset. fn burn_coins(burn_amount: u64) { + // ANCHOR: burn_asset burn(DEFAULT_SUB_ID, burn_amount); + // ANCHOR_END: burn_asset } /// Transfer coins to a target contract. - fn force_transfer_coins(coins: u64, asset_id: AssetId, target: ContractId) { - force_transfer_to_contract(target, asset_id, coins); + fn transfer_coins(coins: u64, asset_id: AssetId, target: Identity) { + // ANCHOR: transfer_asset + transfer(target, asset_id, coins); + // ANCHOR_END: transfer_asset } - /// Transfer coins to a transaction output to be spent later. - fn transfer_coins_to_output(coins: u64, asset_id: AssetId, recipient: Address) { - transfer_to_address(recipient, asset_id, coins); + /// Get the internal balance of a specific coin at a specific contract. + fn get_balance(target_contract: ContractId, asset_id: AssetId) -> u64 { + // ANCHOR: balance_of + balance_of(target_contract, asset_id) + // ANCHOR_END: balance_of } /// Get the internal balance of a specific coin at a specific contract. - fn get_balance(target: ContractId, asset_id: AssetId) -> u64 { - balance_of(target, asset_id) + fn this_balance(asset_id: AssetId) -> u64 { + // ANCHOR: this_balance + this_balance(asset_id) + // ANCHOR_END: this_balance } /// Deposit coins back into the contract. + // ANCHOR: payable + #[payable] fn deposit() { assert(msg_amount() > 0); } - + // ANCHOR_END: payable /// Mint and send this contracts native asset to a destination contract. - fn mint_and_send_to_contract(amount: u64, destination: ContractId) { - mint_to_contract(destination, DEFAULT_SUB_ID, amount); + fn get_msg_amount() { + // ANCHOR: msg_amount + let amount = msg_amount(); + // ANCHOR_END: msg_amount } - /// Mind and send this contracts native asset to a destination address. - fn mint_and_send_to_address(amount: u64, recipient: Address) { - mint_to_address(recipient, DEFAULT_SUB_ID, amount); + /// Mint and send this contracts native asset to a destination contract. + fn get_msg_asset_id() { + // ANCHOR: msg_asset_id + let amount = msg_asset_id(); + // ANCHOR_END: msg_asset_id } } + +fn get_base_asset() { + // ANCHOR: base_asset + let base_asset: AssetId = AssetId::base_asset_id(); + // ANCHOR_END: base_asset +} + +fn default_asset_id() { + // ANCHOR: default_asset_id + let asset_id: AssetId = AssetId::default(); + // ANCHOR_END: default_asset_id +} + +fn new_asset_id(my_contract_id: ContractId, my_sub_id: SubId) { + // ANCHOR: new_asset_id + let my_contract_id: ContractId = ContractId::from(0x1000000000000000000000000000000000000000000000000000000000000000); + let my_sub_id: SubId = 0x2000000000000000000000000000000000000000000000000000000000000000; + + let asset_id: AssetId = AssetId::new(my_contract_id, my_sub_id); + // ANCHOR_END: new_asset_id +} + +fn from_asset_id() { + // ANCHOR: from_asset_id + let asset_id: AssetId = AssetId::from(0x0000000000000000000000000000000000000000000000000000000000000000); + // ANCHOR_END: from_asset_id +} From 80f3fd3ab3a8f878c929a66c5e66ae0f229fb985 Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Tue, 9 Apr 2024 02:30:04 +0100 Subject: [PATCH 5/6] change ConcurrentSlab to use Vec (#5838) ## Description Partially addresses https://github.com/FuelLabs/sway/issues/5781. This reduces the time spent retrieving items in slabs. For more details see: https://github.com/FuelLabs/sway/pull/5782 ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. Co-authored-by: Joshua Batty --- sway-core/src/concurrent_slab.rs | 76 +++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 22 deletions(-) diff --git a/sway-core/src/concurrent_slab.rs b/sway-core/src/concurrent_slab.rs index 79f67d678f2..e1934bb9813 100644 --- a/sway-core/src/concurrent_slab.rs +++ b/sway-core/src/concurrent_slab.rs @@ -1,15 +1,26 @@ use std::{ - collections::HashMap, fmt, sync::{Arc, RwLock}, }; -use itertools::Itertools; +#[derive(Debug, Clone)] +pub struct Inner { + pub items: Vec>>, + pub free_list: Vec, +} + +impl Default for Inner { + fn default() -> Self { + Self { + items: Default::default(), + free_list: Default::default(), + } + } +} #[derive(Debug)] pub(crate) struct ConcurrentSlab { - inner: RwLock>>, - last_id: Arc>, + pub inner: RwLock>, } impl Clone for ConcurrentSlab @@ -20,7 +31,6 @@ where let inner = self.inner.read().unwrap(); Self { inner: RwLock::new(inner.clone()), - last_id: self.last_id.clone(), } } } @@ -29,7 +39,6 @@ impl Default for ConcurrentSlab { fn default() -> Self { Self { inner: Default::default(), - last_id: Default::default(), } } } @@ -58,46 +67,69 @@ impl ConcurrentSlab where T: Clone, { + #[allow(dead_code)] + pub fn len(&self) -> usize { + let inner = self.inner.read().unwrap(); + inner.items.len() + } + pub fn values(&self) -> Vec> { let inner = self.inner.read().unwrap(); - inner.values().cloned().collect_vec() + inner.items.iter().filter_map(|x| x.clone()).collect() } pub fn insert(&self, value: T) -> usize { - let mut inner = self.inner.write().unwrap(); - let mut last_id = self.last_id.write().unwrap(); - *last_id += 1; - inner.insert(*last_id, Arc::new(value)); - *last_id + self.insert_arc(Arc::new(value)) } pub fn insert_arc(&self, value: Arc) -> usize { let mut inner = self.inner.write().unwrap(); - let mut last_id = self.last_id.write().unwrap(); - *last_id += 1; - inner.insert(*last_id, value); - *last_id + + if let Some(free) = inner.free_list.pop() { + assert!(inner.items[free].is_none()); + inner.items[free] = Some(value); + free + } else { + inner.items.push(Some(value)); + inner.items.len() - 1 + } } pub fn replace(&self, index: usize, new_value: T) -> Option { let mut inner = self.inner.write().unwrap(); - inner.insert(index, Arc::new(new_value)); - None + let item = inner.items.get_mut(index)?; + let old = item.replace(Arc::new(new_value))?; + Arc::into_inner(old) } pub fn get(&self, index: usize) -> Arc { let inner = self.inner.read().unwrap(); - inner[&index].clone() + inner.items[index] + .as_ref() + .expect("invalid slab index for ConcurrentSlab::get") + .clone() } pub fn retain(&self, predicate: impl Fn(&usize, &mut Arc) -> bool) { let mut inner = self.inner.write().unwrap(); - inner.retain(predicate); + + let Inner { items, free_list } = &mut *inner; + for (idx, item) in items.iter_mut().enumerate() { + if let Some(arc) = item { + if !predicate(&idx, arc) { + free_list.push(idx); + item.take(); + } + } + } } pub fn clear(&self) { let mut inner = self.inner.write().unwrap(); - inner.clear(); - inner.shrink_to(0); + inner.items.clear(); + inner.items.shrink_to(0); + + inner.free_list.clear(); + inner.free_list.shrink_to(0); } } From 89e5708402108fa383b6f7a7351f5ae5f357bbe1 Mon Sep 17 00:00:00 2001 From: Daniel Frederico Lins Leite Date: Tue, 9 Apr 2024 14:24:12 +0100 Subject: [PATCH 6/6] Fix and improve errors when the entry fns cannot be generated (#5824) ## Description This PR improves fix a problem when a type cannot be auto-impled and improve error messages for this case. This can be seen on `tests/types/contracts/type_inside_enum` in the Rust SDK repo. ``` Running `target/debug/forc build --path /home/xunilrj/github/fuels-rs/packages/fuels --experimental-new-encoding` thread 'main' panicked at sway-ir/src/constant.rs:172:14: Enums are aggregates. note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ``` Given that this PR also improve implementation of arrays for `AbiEncode` and `AbiDecode`, the entry function is actually generated. But in case of error, it will fail like: ``` error --> /home/xunilrj/.forc/git/checkouts/std-9be0d6062747ea7/5645f10143243e1fd64a55002cd5c09730636ece/sway-lib-core/src/codec.sw:2192:8 | 2190 | 2191 | pub trait AbiDecode { 2192 | fn abi_decode(ref mut buffer: BufferReader) -> Self; | ^^^^^^^^^^ No method named "abi_decode" found for type "SomeEnum". 2193 | } | ____ error --> :5:61 | 3 | 4 | let args: (SomeEnum,) = decode_second_param::<(SomeEnum,)>(); 5 | let result_arr_inside_enum: raw_slice = encode::(__contract_entry_arr_inside_enum(args.0)); | ^^^^^^^^^^^^^^^^^^ Trait "AbiEncode" is not implemented for type "SomeEnum". 6 | __contract_ret(result_arr_inside_enum.ptr(), result_arr_inside_enum.len::()); 7 | } | ____ error --> :24:61 | 22 | 23 | let args: (SomeEnum,) = decode_second_param::<(SomeEnum,)>(); 24 | let result_str_inside_enum: raw_slice = encode::(__contract_entry_str_inside_enum(args.0)); | ^^^^^^^^^^^^^^^^^^ Trait "AbiEncode" is not implemented for type "SomeEnum". 25 | __contract_ret(result_str_inside_enum.ptr(), result_str_inside_enum.len::()); 26 | } | ____ error: Could not generate the entry method because one of the arguments does not implement AbiEncode/AbiDecode ____ Aborting due to 4 errors. Error: Failed to compile type_inside_enum ```` ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --- sway-core/src/ir_generation/const_eval.rs | 29 +- .../ast_node/declaration/auto_impl.rs | 235 +- sway-core/src/semantic_analysis/module.rs | 41 +- .../semantic_analysis/type_check_context.rs | 28 + sway-core/src/type_system/engine.rs | 4 +- sway-error/src/error.rs | 3 + sway-ir/src/parser.rs | 1 + sway-lib-core/generate.sh | 16 + sway-lib-core/src/codec.sw | 4049 ++++++++++++----- sway-parse/src/attribute.rs | 2 +- sway-parse/src/parse.rs | 2 +- swayfmt/src/utils/map/byte_span.rs | 2 +- .../array_of_structs_caller/src/main.sw | 2 +- .../src/main.sw | 2 +- 14 files changed, 3058 insertions(+), 1358 deletions(-) diff --git a/sway-core/src/ir_generation/const_eval.rs b/sway-core/src/ir_generation/const_eval.rs index 921f2ed6562..ad01563a8f4 100644 --- a/sway-core/src/ir_generation/const_eval.rs +++ b/sway-core/src/ir_generation/const_eval.rs @@ -31,7 +31,7 @@ use sway_types::{ident::Ident, integer_bits::IntegerBits, span::Spanned, Span}; use sway_utils::mapped_stack::MappedStack; enum ConstEvalError { - CompileError(CompileError), + CompileError, CannotBeEvaluatedToConst { // This is not used at the moment because we do not give detailed description of why a // const eval failed. @@ -640,13 +640,7 @@ fn const_eval_typed_expr( if index < count { Some(items[index as usize].clone()) } else { - return Err(ConstEvalError::CompileError( - CompileError::ArrayOutOfBounds { - index, - count, - span: expr.span.clone(), - }, - )); + return Err(ConstEvalError::CompileError); } } _ => { @@ -657,10 +651,7 @@ fn const_eval_typed_expr( } } ty::TyExpressionVariant::Ref(_) | ty::TyExpressionVariant::Deref(_) => { - return Err(ConstEvalError::CompileError(CompileError::Unimplemented( - "Constant references are currently not supported.", - expr.span.clone(), - ))); + return Err(ConstEvalError::CompileError); } ty::TyExpressionVariant::Reassignment(_) | ty::TyExpressionVariant::FunctionParameter @@ -993,7 +984,7 @@ fn const_eval_intrinsic( &targ.type_id, &targ.span, ) - .map_err(ConstEvalError::CompileError)?; + .map_err(|_| ConstEvalError::CompileError)?; Ok(Some(Constant { ty: Type::get_uint64(lookup.context), value: ConstantValue::Uint(ir_type.size(lookup.context).in_bytes()), @@ -1009,7 +1000,7 @@ fn const_eval_intrinsic( &type_id, &val.span, ) - .map_err(ConstEvalError::CompileError)?; + .map_err(|_| ConstEvalError::CompileError)?; Ok(Some(Constant { ty: Type::get_uint64(lookup.context), value: ConstantValue::Uint(ir_type.size(lookup.context).in_bytes()), @@ -1024,7 +1015,7 @@ fn const_eval_intrinsic( &targ.type_id, &targ.span, ) - .map_err(ConstEvalError::CompileError)?; + .map_err(|_| ConstEvalError::CompileError)?; Ok(Some(Constant { ty: Type::get_uint64(lookup.context), value: ConstantValue::Uint( @@ -1041,17 +1032,13 @@ fn const_eval_intrinsic( &targ.type_id, &targ.span, ) - .map_err(ConstEvalError::CompileError)?; + .map_err(|_| ConstEvalError::CompileError)?; match ir_type.get_content(lookup.context) { TypeContent::StringSlice | TypeContent::StringArray(_) => Ok(Some(Constant { ty: Type::get_unit(lookup.context), value: ConstantValue::Unit, })), - _ => Err(ConstEvalError::CompileError( - CompileError::NonStrGenericType { - span: targ.span.clone(), - }, - )), + _ => Err(ConstEvalError::CompileError), } } Intrinsic::ToStrArray => { diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs b/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs index 479d130f4ca..67eef140672 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs @@ -10,19 +10,22 @@ use crate::{ Engines, TypeId, TypeInfo, TypeParameter, }; use itertools::Itertools; -use sway_error::handler::Handler; +use sway_error::{ + error::CompileError, + handler::{ErrorEmitted, Handler}, +}; use sway_parse::Parse; -use sway_types::{integer_bits::IntegerBits, BaseIdent, ModuleId, Named, Spanned}; +use sway_types::{integer_bits::IntegerBits, BaseIdent, ModuleId, Named, Span, Spanned}; /// Contains all information needed to implement AbiEncode -pub struct AutoImplAbiEncodeContext<'a, 'b> +pub struct EncodingAutoImplContext<'a, 'b> where 'a: 'b, { ctx: &'b mut TypeCheckContext<'a>, } -impl<'a, 'b> AutoImplAbiEncodeContext<'a, 'b> +impl<'a, 'b> EncodingAutoImplContext<'a, 'b> where 'a: 'b, { @@ -30,7 +33,7 @@ where Some(Self { ctx }) } - pub fn parse(engines: &Engines, module_id: Option, input: &str) -> T + fn parse(engines: &Engines, module_id: Option, input: &str) -> T where T: Parse, { @@ -201,16 +204,20 @@ where let arms = decl.variants.iter() .map(|x| { let name = x.name.as_str(); - if engines.te().get(x.type_argument.type_id).is_unit() { - format!("{} => {}::{}, \n", x.tag, enum_name, name) - } else { - let variant_type_name = Self::generate_type(engines, x.type_argument.type_id); - format!("{tag_value} => {enum_name}::{variant_name}(buffer.decode::<{variant_type}>()), \n", - tag_value = x.tag, - enum_name = enum_name, - variant_name = name, - variant_type = variant_type_name - ) + match &*engines.te().get(x.type_argument.type_id) { + // unit + TypeInfo::Tuple(fiels) if fiels.is_empty() => { + format!("{} => {}::{}, \n", x.tag, enum_name, name) + }, + _ => { + let variant_type_name = Self::generate_type(engines, x.type_argument.type_id); + format!("{tag_value} => {enum_name}::{variant_name}(buffer.decode::<{variant_type}>()), \n", + tag_value = x.tag, + enum_name = enum_name, + variant_name = name, + variant_type = variant_type_name + ) + } } }) .collect::(); @@ -230,25 +237,29 @@ where .iter() .map(|x| { let name = x.name.as_str(); - if engines.te().get(x.type_argument.type_id).is_unit() { - format!( - "{enum_name}::{variant_name} => {{ - {tag_value}u64.abi_encode(buffer); - }}, \n", - tag_value = x.tag, - enum_name = enum_name, - variant_name = name - ) - } else { - format!( - "{enum_name}::{variant_name}(value) => {{ - {tag_value}u64.abi_encode(buffer); - value.abi_encode(buffer); - }}, \n", - tag_value = x.tag, - enum_name = enum_name, - variant_name = name, - ) + match &*engines.te().get(x.type_argument.type_id) { + // Unit + TypeInfo::Tuple(fields) if fields.is_empty() => { + format!( + "{enum_name}::{variant_name} => {{ + {tag_value}u64.abi_encode(buffer); + }}, \n", + tag_value = x.tag, + enum_name = enum_name, + variant_name = name + ) + } + _ => { + format!( + "{enum_name}::{variant_name}(value) => {{ + {tag_value}u64.abi_encode(buffer); + value.abi_encode(buffer); + }}, \n", + tag_value = x.tag, + enum_name = enum_name, + variant_name = name, + ) + } } }) .collect::(); @@ -256,13 +267,13 @@ where format!("match self {{ {arms} }}") } - pub fn parse_item_fn_to_typed_ast_node( + pub fn parse_fn_to_ty_ast_node( &mut self, engines: &Engines, module_id: Option, kind: FunctionDeclarationKind, code: &str, - ) -> Option { + ) -> Result { let mut ctx = crate::transform::to_parsed_lang::Context::new( crate::BuildTarget::Fuel, self.ctx.experimental, @@ -302,40 +313,38 @@ where assert!(!handler.has_warnings(), "{:?}", handler); let ctx = self.ctx.by_ref(); - let decl = TyDecl::type_check( - &handler, - ctx, - parsed::Declaration::FunctionDeclaration(decl), - ) - .unwrap(); + let (decl, namespace) = ctx + .scoped_and_namespace(|ctx| { + TyDecl::type_check( + &handler, + ctx, + parsed::Declaration::FunctionDeclaration(decl), + ) + }) + .unwrap(); - if handler.has_errors() { - panic!( - "{:?} {} {:?}", - handler, - code, - module_id - .and_then(|x| engines.se().get_source_ids_from_module_id(x)) - .unwrap() - .iter() - .map(|x| engines.se().get_path(x)) - .collect::>() - ); - } assert!(!handler.has_warnings(), "{:?}", handler); - Some(TyAstNode { - span: decl.span(), - content: ty::TyAstNodeContent::Declaration(decl), - }) + // Uncomment this to understand why an entry function was not generated + // println!("{:#?}", handler); + + if handler.has_errors() || matches!(decl, TyDecl::ErrorRecovery(_, _)) { + Err(handler) + } else { + *self.ctx.namespace = namespace; + Ok(TyAstNode { + span: decl.span(), + content: ty::TyAstNodeContent::Declaration(decl), + }) + } } - fn parse_item_impl_to_typed_ast_node( + fn parse_impl_trait_to_ty_ast_node( &mut self, engines: &Engines, module_id: Option, code: &str, - ) -> Option { + ) -> Result { let mut ctx = crate::transform::to_parsed_lang::Context::new( crate::BuildTarget::Fuel, self.ctx.experimental, @@ -357,12 +366,20 @@ where assert!(!handler.has_errors(), "{:?}", handler); let ctx = self.ctx.by_ref(); - let decl = TyDecl::type_check(&handler, ctx, Declaration::ImplTrait(decl)).unwrap(); + let (decl, namespace) = ctx + .scoped_and_namespace(|ctx| { + TyDecl::type_check(&handler, ctx, Declaration::ImplTrait(decl)) + }) + .unwrap(); - if handler.has_errors() { - None + // Uncomment this to understand why auto impl failed for a type. + // println!("{:#?}", handler); + + if handler.has_errors() || matches!(decl, TyDecl::ErrorRecovery(_, _)) { + Err(handler) } else { - Some(TyAstNode { + *self.ctx.namespace = namespace; + Ok(TyAstNode { span: decl.span(), content: ty::TyAstNodeContent::Declaration(decl), }) @@ -392,7 +409,7 @@ where abi_encode_body, ); let abi_encode_node = - self.parse_item_impl_to_typed_ast_node(engines, module_id, &abi_encode_code); + self.parse_impl_trait_to_ty_ast_node(engines, module_id, &abi_encode_code); let abi_decode_body = self.generate_abi_decode_struct_body(engines, &struct_decl); let abi_decode_code = self.generate_abi_decode_code( @@ -401,9 +418,9 @@ where abi_decode_body, ); let abi_decode_node = - self.parse_item_impl_to_typed_ast_node(engines, module_id, &abi_decode_code); + self.parse_impl_trait_to_ty_ast_node(engines, module_id, &abi_decode_code); - (abi_encode_node, abi_decode_node) + (abi_encode_node.ok(), abi_decode_node.ok()) } fn auto_impl_enum( @@ -421,14 +438,14 @@ where let module_id = enum_decl.span().source_id().map(|sid| sid.module_id()); - let abi_decode_body = self.generate_abi_encode_enum_body(engines, &enum_decl); - let abi_decode_code = self.generate_abi_encode_code( + let abi_encode_body = self.generate_abi_encode_enum_body(engines, &enum_decl); + let abi_encode_code = self.generate_abi_encode_code( enum_decl.name(), &enum_decl.type_parameters, - abi_decode_body, + abi_encode_body, ); let abi_encode_node = - self.parse_item_impl_to_typed_ast_node(engines, module_id, &abi_decode_code); + self.parse_impl_trait_to_ty_ast_node(engines, module_id, &abi_encode_code); let abi_decode_body = self.generate_abi_decode_enum_body(engines, &enum_decl); let abi_decode_code = self.generate_abi_decode_code( @@ -437,9 +454,9 @@ where abi_decode_body, ); let abi_decode_node = - self.parse_item_impl_to_typed_ast_node(engines, module_id, &abi_decode_code); + self.parse_impl_trait_to_ty_ast_node(engines, module_id, &abi_decode_code); - (abi_encode_node, abi_decode_node) + (abi_encode_node.ok(), abi_decode_node.ok()) } pub fn generate( @@ -538,7 +555,8 @@ where module_id: Option, contract_fns: &[DeclRef>], fallback_fn: Option>, - ) -> Option { + handler: &Handler, + ) -> Result { let mut code = String::new(); let mut reads = false; @@ -591,7 +609,7 @@ where }}\n")); } else { code.push_str(&format!("if method_name == \"{method_name}\" {{ - let args = decode_second_param::<{args_types}>(); + let args: {args_types} = decode_second_param::<{args_types}>(); let result_{method_name}: raw_slice = encode::<{return_type}>(__contract_entry_{method_name}({expanded_args})); __contract_ret(result_{method_name}.ptr(), result_{method_name}.len::()); }}\n")); @@ -624,19 +642,27 @@ where {fallback} }}" ); - self.parse_item_fn_to_typed_ast_node( - engines, - module_id, - FunctionDeclarationKind::Entry, - &code, - ) + + let entry_fn = + self.parse_fn_to_ty_ast_node(engines, module_id, FunctionDeclarationKind::Entry, &code); + + match entry_fn { + Ok(entry_fn) => Ok(entry_fn), + Err(gen_handler) => { + handler.append(gen_handler); + Err(handler.emit_err(CompileError::CouldNotGenerateEntry { + span: Span::dummy(), + })) + } + } } pub(crate) fn generate_predicate_entry( &mut self, engines: &Engines, decl: &TyFunctionDecl, - ) -> Option { + handler: &Handler, + ) -> Result { let module_id = decl.span.source_id().map(|sid| sid.module_id()); let args_types = itertools::intersperse( @@ -662,25 +688,32 @@ where let args_types = format!("({args_types},)"); format!( "pub fn __entry() -> bool {{ - let args = decode_predicate_data::<{args_types}>(); + let args: {args_types} = decode_predicate_data::<{args_types}>(); main({expanded_args}) }}" ) }; - self.parse_item_fn_to_typed_ast_node( - engines, - module_id, - FunctionDeclarationKind::Entry, - &code, - ) + let entry_fn = + self.parse_fn_to_ty_ast_node(engines, module_id, FunctionDeclarationKind::Entry, &code); + + match entry_fn { + Ok(entry_fn) => Ok(entry_fn), + Err(gen_handler) => { + handler.append(gen_handler); + Err(handler.emit_err(CompileError::CouldNotGenerateEntry { + span: Span::dummy(), + })) + } + } } pub(crate) fn generate_script_entry( &mut self, engines: &Engines, decl: &TyFunctionDecl, - ) -> Option { + handler: &Handler, + ) -> Result { let module_id = decl.span.source_id().map(|sid| sid.module_id()); let args_types = itertools::intersperse( @@ -718,18 +751,24 @@ where } else { format!( "pub fn __entry() -> raw_slice {{ - let args = decode_script_data::<{args_types}>(); + let args: {args_types} = decode_script_data::<{args_types}>(); let result: {return_type} = main({expanded_args}); encode::<{return_type}>(result) }}" ) }; - self.parse_item_fn_to_typed_ast_node( - engines, - module_id, - FunctionDeclarationKind::Entry, - &code, - ) + let entry_fn = + self.parse_fn_to_ty_ast_node(engines, module_id, FunctionDeclarationKind::Entry, &code); + + match entry_fn { + Ok(entry_fn) => Ok(entry_fn), + Err(gen_handler) => { + handler.append(gen_handler); + Err(handler.emit_err(CompileError::CouldNotGenerateEntry { + span: Span::dummy(), + })) + } + } } } diff --git a/sway-core/src/semantic_analysis/module.rs b/sway-core/src/semantic_analysis/module.rs index 986de04ce1d..5158858e7ad 100644 --- a/sway-core/src/semantic_analysis/module.rs +++ b/sway-core/src/semantic_analysis/module.rs @@ -25,7 +25,7 @@ use crate::{ use super::{ collection_context::SymbolCollectionContext, - declaration::auto_impl::{self, AutoImplAbiEncodeContext}, + declaration::auto_impl::{self, EncodingAutoImplContext}, }; #[derive(Clone, Debug)] @@ -327,18 +327,22 @@ impl ty::TyModule { match (&kind, main_decl.is_some()) { (TreeType::Predicate, true) => { let mut fn_generator = - auto_impl::AutoImplAbiEncodeContext::new(&mut ctx).unwrap(); - let node = fn_generator - .generate_predicate_entry(engines, main_decl.as_ref().unwrap()) - .unwrap(); + auto_impl::EncodingAutoImplContext::new(&mut ctx).unwrap(); + let node = fn_generator.generate_predicate_entry( + engines, + main_decl.as_ref().unwrap(), + handler, + )?; all_nodes.push(node) } (TreeType::Script, true) => { let mut fn_generator = - auto_impl::AutoImplAbiEncodeContext::new(&mut ctx).unwrap(); - let node = fn_generator - .generate_script_entry(engines, main_decl.as_ref().unwrap()) - .unwrap(); + auto_impl::EncodingAutoImplContext::new(&mut ctx).unwrap(); + let node = fn_generator.generate_script_entry( + engines, + main_decl.as_ref().unwrap(), + handler, + )?; all_nodes.push(node) } (TreeType::Contract, _) => { @@ -351,15 +355,14 @@ impl ty::TyModule { .collect::>(); let mut fn_generator = - auto_impl::AutoImplAbiEncodeContext::new(&mut ctx).unwrap(); - let node = fn_generator - .generate_contract_entry( - engines, - parsed.span.source_id().map(|x| x.module_id()), - &contract_fns, - fallback_fn, - ) - .unwrap(); + auto_impl::EncodingAutoImplContext::new(&mut ctx).unwrap(); + let node = fn_generator.generate_contract_entry( + engines, + parsed.span.source_id().map(|x| x.module_id()), + &contract_fns, + fallback_fn, + handler, + )?; all_nodes.push(node) } _ => {} @@ -449,7 +452,7 @@ impl ty::TyModule { let mut generated = vec![]; if let (true, Some(mut ctx)) = ( auto_impl_encoding_traits, - AutoImplAbiEncodeContext::new(&mut ctx), + EncodingAutoImplContext::new(&mut ctx), ) { match &node.content { TyAstNodeContent::Declaration(decl @ TyDecl::StructDecl(_)) diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index 9e81b565120..5994196b9fd 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -233,6 +233,34 @@ impl<'a> TypeCheckContext<'a> { with_scoped_ctx(ctx) } + /// Scope the `TypeCheckContext` with a new namespace and returns it in case of success. + pub fn scoped_and_namespace( + self, + with_scoped_ctx: impl FnOnce(TypeCheckContext) -> Result, + ) -> Result<(T, Namespace), ErrorEmitted> { + let mut namespace = self.namespace.clone(); + let ctx = TypeCheckContext { + namespace: &mut namespace, + type_annotation: self.type_annotation, + function_type_annotation: self.function_type_annotation, + unify_generic: self.unify_generic, + self_type: self.self_type, + type_subst: self.type_subst, + abi_mode: self.abi_mode, + const_shadowing_mode: self.const_shadowing_mode, + generic_shadowing_mode: self.generic_shadowing_mode, + help_text: self.help_text, + purity: self.purity, + kind: self.kind, + engines: self.engines, + disallow_functions: self.disallow_functions, + defer_monomorphization: self.defer_monomorphization, + storage_declaration: self.storage_declaration, + experimental: self.experimental, + }; + Ok((with_scoped_ctx(ctx)?, namespace)) + } + /// Enter the submodule with the given name and produce a type-check context ready for /// type-checking its content. /// diff --git a/sway-core/src/type_system/engine.rs b/sway-core/src/type_system/engine.rs index 5fc92e14977..ef0b459055d 100644 --- a/sway-core/src/type_system/engine.rs +++ b/sway-core/src/type_system/engine.rs @@ -40,9 +40,7 @@ impl TypeEngine { ty: TypeInfo, source_id: Option<&SourceId>, ) -> TypeId { - let source_id = source_id - .map(Clone::clone) - .or_else(|| info_to_source_id(&ty)); + let source_id = source_id.copied().or_else(|| info_to_source_id(&ty)); let tsi = TypeSourceInfo { type_info: ty.clone().into(), source_id, diff --git a/sway-error/src/error.rs b/sway-error/src/error.rs index 3a6fa30b947..d02e04466e4 100644 --- a/sway-error/src/error.rs +++ b/sway-error/src/error.rs @@ -866,6 +866,8 @@ pub enum CompileError { FallbackFnsAreContractOnly { span: Span }, #[error("Fallback functions cannot have parameters")] FallbackFnsCannotHaveParameters { span: Span }, + #[error("Could not generate the entry method because one of the arguments does not implement AbiEncode/AbiDecode")] + CouldNotGenerateEntry { span: Span }, } impl std::convert::From for CompileError { @@ -1067,6 +1069,7 @@ impl Spanned for CompileError { ExpressionCannotBeDereferenced { span, .. } => span.clone(), FallbackFnsAreContractOnly { span } => span.clone(), FallbackFnsCannotHaveParameters { span } => span.clone(), + CouldNotGenerateEntry { span } => span.clone(), } } } diff --git a/sway-ir/src/parser.rs b/sway-ir/src/parser.rs index 6ec9ef8e9e5..d12124e704f 100644 --- a/sway-ir/src/parser.rs +++ b/sway-ir/src/parser.rs @@ -764,6 +764,7 @@ mod ir_builder { #[derive(Debug)] enum IrAstConstValue { + #[allow(dead_code)] Undef(IrAstTy), Unit, Bool(bool), diff --git a/sway-lib-core/generate.sh b/sway-lib-core/generate.sh index 6a66a8482a4..3ed838d9988 100755 --- a/sway-lib-core/generate.sh +++ b/sway-lib-core/generate.sh @@ -9,6 +9,22 @@ remove_generated_code() { sed -i "$((START+1)),$((END-1))d" ./src/codec.sw } +remove_generated_code "ARRAY_ENCODE" +START=1 +END=64 +for ((i=END;i>=START;i--)); do + CODE="impl AbiEncode for [T; $i] where T: AbiEncode { fn abi_encode(self, ref mut buffer: Buffer) { let mut i = 0; while i < $i { self[i].abi_encode(buffer); i += 1; } } }" + sed -i "s/\/\/ BEGIN ARRAY_ENCODE/\/\/ BEGIN ARRAY_ENCODE\n$CODE/g" ./src/codec.sw +done + +remove_generated_code "ARRAY_DECODE" +START=1 +END=64 +for ((i=END;i>=START;i--)); do + CODE="impl AbiDecode for [T; $i] where T: AbiDecode { fn abi_decode(ref mut buffer: BufferReader) -> [T; $i] { let first: T = buffer.decode::(); let mut array = [first; $i]; let mut i = 1; while i < $i { array[i] = buffer.decode::(); i += 1; }; array } }" + sed -i "s/\/\/ BEGIN ARRAY_DECODE/\/\/ BEGIN ARRAY_DECODE\n$CODE/g" ./src/codec.sw +done + remove_generated_code "STRARRAY_ENCODE" START=1 END=64 diff --git a/sway-lib-core/src/codec.sw b/sway-lib-core/src/codec.sw index 64fd264698f..8749d5fc02a 100644 --- a/sway-lib-core/src/codec.sw +++ b/sway-lib-core/src/codec.sw @@ -1222,1610 +1222,3214 @@ impl AbiEncode for raw_slice { } } -impl AbiEncode for [T; 0] -where - T: AbiEncode, -{ - fn abi_encode(self, ref mut _buffer: Buffer) {} -} - +// BEGIN ARRAY_ENCODE impl AbiEncode for [T; 1] where T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self[0].abi_encode(buffer); + let mut i = 0; + while i < 1 { + self[i].abi_encode(buffer); + i += 1; + } } } - impl AbiEncode for [T; 2] where T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self[0].abi_encode(buffer); - self[1].abi_encode(buffer); + let mut i = 0; + while i < 2 { + self[i].abi_encode(buffer); + i += 1; + } } } - impl AbiEncode for [T; 3] where T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self[0].abi_encode(buffer); - self[1].abi_encode(buffer); - self[2].abi_encode(buffer); + let mut i = 0; + while i < 3 { + self[i].abi_encode(buffer); + i += 1; + } } } - impl AbiEncode for [T; 4] where T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self[0].abi_encode(buffer); - self[1].abi_encode(buffer); - self[2].abi_encode(buffer); - self[3].abi_encode(buffer); + let mut i = 0; + while i < 4 { + self[i].abi_encode(buffer); + i += 1; + } } } - impl AbiEncode for [T; 5] where T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self[0].abi_encode(buffer); - self[1].abi_encode(buffer); - self[2].abi_encode(buffer); - self[3].abi_encode(buffer); - self[4].abi_encode(buffer); + let mut i = 0; + while i < 5 { + self[i].abi_encode(buffer); + i += 1; + } } } - -impl AbiEncode for [T; 9] +impl AbiEncode for [T; 6] where T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self[0].abi_encode(buffer); - self[1].abi_encode(buffer); - self[2].abi_encode(buffer); - self[3].abi_encode(buffer); - self[4].abi_encode(buffer); - self[5].abi_encode(buffer); - self[6].abi_encode(buffer); - self[7].abi_encode(buffer); - self[8].abi_encode(buffer); + let mut i = 0; + while i < 6 { + self[i].abi_encode(buffer); + i += 1; + } } } - -// Encode Tuples - - -impl AbiEncode for () { - fn abi_encode(self, ref mut _buffer: Buffer) {} -} - -// BEGIN TUPLES_ENCODE -impl AbiEncode for (A, ) +impl AbiEncode for [T; 7] where - A: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); + let mut i = 0; + while i < 7 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B) +impl AbiEncode for [T; 8] where - A: AbiEncode, - B: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); + let mut i = 0; + while i < 8 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C) +impl AbiEncode for [T; 9] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); + let mut i = 0; + while i < 9 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D) +impl AbiEncode for [T; 10] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); + let mut i = 0; + while i < 10 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E) +impl AbiEncode for [T; 11] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); + let mut i = 0; + while i < 11 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F) +impl AbiEncode for [T; 12] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); + let mut i = 0; + while i < 12 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G) +impl AbiEncode for [T; 13] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); + let mut i = 0; + while i < 13 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H) +impl AbiEncode for [T; 14] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); + let mut i = 0; + while i < 14 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H, I) +impl AbiEncode for [T; 15] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, - I: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); - self.8.abi_encode(buffer); + let mut i = 0; + while i < 15 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H, I, J) +impl AbiEncode for [T; 16] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, - I: AbiEncode, - J: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); - self.8.abi_encode(buffer); - self.9.abi_encode(buffer); + let mut i = 0; + while i < 16 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K) +impl AbiEncode for [T; 17] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, - I: AbiEncode, - J: AbiEncode, - K: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); - self.8.abi_encode(buffer); - self.9.abi_encode(buffer); - self.10.abi_encode(buffer); + let mut i = 0; + while i < 17 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L) +impl AbiEncode for [T; 18] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, - I: AbiEncode, - J: AbiEncode, - K: AbiEncode, - L: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); - self.8.abi_encode(buffer); - self.9.abi_encode(buffer); - self.10.abi_encode(buffer); - self.11.abi_encode(buffer); + let mut i = 0; + while i < 18 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M) +impl AbiEncode for [T; 19] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, - I: AbiEncode, - J: AbiEncode, - K: AbiEncode, - L: AbiEncode, - M: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); - self.8.abi_encode(buffer); - self.9.abi_encode(buffer); - self.10.abi_encode(buffer); - self.11.abi_encode(buffer); - self.12.abi_encode(buffer); + let mut i = 0; + while i < 19 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N) +impl AbiEncode for [T; 20] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, - I: AbiEncode, - J: AbiEncode, - K: AbiEncode, - L: AbiEncode, - M: AbiEncode, - N: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); - self.8.abi_encode(buffer); - self.9.abi_encode(buffer); - self.10.abi_encode(buffer); - self.11.abi_encode(buffer); - self.12.abi_encode(buffer); - self.13.abi_encode(buffer); + let mut i = 0; + while i < 20 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O) +impl AbiEncode for [T; 21] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, - I: AbiEncode, - J: AbiEncode, - K: AbiEncode, - L: AbiEncode, - M: AbiEncode, - N: AbiEncode, - O: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); - self.8.abi_encode(buffer); - self.9.abi_encode(buffer); - self.10.abi_encode(buffer); - self.11.abi_encode(buffer); - self.12.abi_encode(buffer); - self.13.abi_encode(buffer); - self.14.abi_encode(buffer); + let mut i = 0; + while i < 21 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) +impl AbiEncode for [T; 22] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, - I: AbiEncode, - J: AbiEncode, - K: AbiEncode, - L: AbiEncode, - M: AbiEncode, - N: AbiEncode, - O: AbiEncode, - P: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); - self.8.abi_encode(buffer); - self.9.abi_encode(buffer); - self.10.abi_encode(buffer); - self.11.abi_encode(buffer); - self.12.abi_encode(buffer); - self.13.abi_encode(buffer); - self.14.abi_encode(buffer); - self.15.abi_encode(buffer); + let mut i = 0; + while i < 22 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q) +impl AbiEncode for [T; 23] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, - I: AbiEncode, - J: AbiEncode, - K: AbiEncode, - L: AbiEncode, - M: AbiEncode, - N: AbiEncode, - O: AbiEncode, - P: AbiEncode, - Q: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); - self.8.abi_encode(buffer); - self.9.abi_encode(buffer); - self.10.abi_encode(buffer); - self.11.abi_encode(buffer); - self.12.abi_encode(buffer); - self.13.abi_encode(buffer); - self.14.abi_encode(buffer); - self.15.abi_encode(buffer); - self.16.abi_encode(buffer); + let mut i = 0; + while i < 23 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R) +impl AbiEncode for [T; 24] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, - I: AbiEncode, - J: AbiEncode, - K: AbiEncode, - L: AbiEncode, - M: AbiEncode, - N: AbiEncode, - O: AbiEncode, - P: AbiEncode, - Q: AbiEncode, - R: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); - self.8.abi_encode(buffer); - self.9.abi_encode(buffer); - self.10.abi_encode(buffer); - self.11.abi_encode(buffer); - self.12.abi_encode(buffer); - self.13.abi_encode(buffer); - self.14.abi_encode(buffer); - self.15.abi_encode(buffer); - self.16.abi_encode(buffer); - self.17.abi_encode(buffer); + let mut i = 0; + while i < 24 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S) +impl AbiEncode for [T; 25] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, - I: AbiEncode, - J: AbiEncode, - K: AbiEncode, - L: AbiEncode, - M: AbiEncode, - N: AbiEncode, - O: AbiEncode, - P: AbiEncode, - Q: AbiEncode, - R: AbiEncode, - S: AbiEncode, + T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); - self.8.abi_encode(buffer); - self.9.abi_encode(buffer); - self.10.abi_encode(buffer); - self.11.abi_encode(buffer); - self.12.abi_encode(buffer); - self.13.abi_encode(buffer); - self.14.abi_encode(buffer); - self.15.abi_encode(buffer); - self.16.abi_encode(buffer); - self.17.abi_encode(buffer); - self.18.abi_encode(buffer); + let mut i = 0; + while i < 25 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T) +impl AbiEncode for [T; 26] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, - I: AbiEncode, - J: AbiEncode, - K: AbiEncode, - L: AbiEncode, - M: AbiEncode, - N: AbiEncode, - O: AbiEncode, - P: AbiEncode, - Q: AbiEncode, - R: AbiEncode, - S: AbiEncode, T: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); - self.8.abi_encode(buffer); - self.9.abi_encode(buffer); - self.10.abi_encode(buffer); - self.11.abi_encode(buffer); - self.12.abi_encode(buffer); - self.13.abi_encode(buffer); - self.14.abi_encode(buffer); - self.15.abi_encode(buffer); - self.16.abi_encode(buffer); - self.17.abi_encode(buffer); - self.18.abi_encode(buffer); - self.19.abi_encode(buffer); + let mut i = 0; + while i < 26 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U) +impl AbiEncode for [T; 27] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, - I: AbiEncode, - J: AbiEncode, - K: AbiEncode, - L: AbiEncode, - M: AbiEncode, - N: AbiEncode, - O: AbiEncode, - P: AbiEncode, - Q: AbiEncode, - R: AbiEncode, - S: AbiEncode, T: AbiEncode, - U: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); - self.8.abi_encode(buffer); - self.9.abi_encode(buffer); - self.10.abi_encode(buffer); - self.11.abi_encode(buffer); - self.12.abi_encode(buffer); - self.13.abi_encode(buffer); - self.14.abi_encode(buffer); - self.15.abi_encode(buffer); - self.16.abi_encode(buffer); - self.17.abi_encode(buffer); - self.18.abi_encode(buffer); - self.19.abi_encode(buffer); - self.20.abi_encode(buffer); + let mut i = 0; + while i < 27 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V) +impl AbiEncode for [T; 28] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, - I: AbiEncode, - J: AbiEncode, - K: AbiEncode, - L: AbiEncode, - M: AbiEncode, - N: AbiEncode, - O: AbiEncode, - P: AbiEncode, - Q: AbiEncode, - R: AbiEncode, - S: AbiEncode, T: AbiEncode, - U: AbiEncode, - V: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); - self.8.abi_encode(buffer); - self.9.abi_encode(buffer); - self.10.abi_encode(buffer); - self.11.abi_encode(buffer); - self.12.abi_encode(buffer); - self.13.abi_encode(buffer); - self.14.abi_encode(buffer); - self.15.abi_encode(buffer); - self.16.abi_encode(buffer); - self.17.abi_encode(buffer); - self.18.abi_encode(buffer); - self.19.abi_encode(buffer); - self.20.abi_encode(buffer); - self.21.abi_encode(buffer); + let mut i = 0; + while i < 28 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W) +impl AbiEncode for [T; 29] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, - I: AbiEncode, - J: AbiEncode, - K: AbiEncode, - L: AbiEncode, - M: AbiEncode, - N: AbiEncode, - O: AbiEncode, - P: AbiEncode, - Q: AbiEncode, - R: AbiEncode, - S: AbiEncode, T: AbiEncode, - U: AbiEncode, - V: AbiEncode, - W: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); - self.8.abi_encode(buffer); - self.9.abi_encode(buffer); - self.10.abi_encode(buffer); - self.11.abi_encode(buffer); - self.12.abi_encode(buffer); - self.13.abi_encode(buffer); - self.14.abi_encode(buffer); - self.15.abi_encode(buffer); - self.16.abi_encode(buffer); - self.17.abi_encode(buffer); - self.18.abi_encode(buffer); - self.19.abi_encode(buffer); - self.20.abi_encode(buffer); - self.21.abi_encode(buffer); - self.22.abi_encode(buffer); + let mut i = 0; + while i < 29 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X) +impl AbiEncode for [T; 30] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, - I: AbiEncode, - J: AbiEncode, - K: AbiEncode, - L: AbiEncode, - M: AbiEncode, - N: AbiEncode, - O: AbiEncode, - P: AbiEncode, - Q: AbiEncode, - R: AbiEncode, - S: AbiEncode, T: AbiEncode, - U: AbiEncode, - V: AbiEncode, - W: AbiEncode, - X: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); - self.8.abi_encode(buffer); - self.9.abi_encode(buffer); - self.10.abi_encode(buffer); - self.11.abi_encode(buffer); - self.12.abi_encode(buffer); - self.13.abi_encode(buffer); - self.14.abi_encode(buffer); - self.15.abi_encode(buffer); - self.16.abi_encode(buffer); - self.17.abi_encode(buffer); - self.18.abi_encode(buffer); - self.19.abi_encode(buffer); - self.20.abi_encode(buffer); - self.21.abi_encode(buffer); - self.22.abi_encode(buffer); - self.23.abi_encode(buffer); + let mut i = 0; + while i < 30 { + self[i].abi_encode(buffer); + i += 1; + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y) +impl AbiEncode for [T; 31] where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, - I: AbiEncode, - J: AbiEncode, - K: AbiEncode, - L: AbiEncode, - M: AbiEncode, - N: AbiEncode, - O: AbiEncode, - P: AbiEncode, - Q: AbiEncode, - R: AbiEncode, - S: AbiEncode, T: AbiEncode, - U: AbiEncode, - V: AbiEncode, - W: AbiEncode, - X: AbiEncode, - Y: AbiEncode, { fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); - self.8.abi_encode(buffer); - self.9.abi_encode(buffer); - self.10.abi_encode(buffer); - self.11.abi_encode(buffer); - self.12.abi_encode(buffer); - self.13.abi_encode(buffer); - self.14.abi_encode(buffer); - self.15.abi_encode(buffer); - self.16.abi_encode(buffer); - self.17.abi_encode(buffer); - self.18.abi_encode(buffer); - self.19.abi_encode(buffer); - self.20.abi_encode(buffer); - self.21.abi_encode(buffer); - self.22.abi_encode(buffer); - self.23.abi_encode(buffer); - self.24.abi_encode(buffer); + let mut i = 0; + while i < 31 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 32] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 32 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 33] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 33 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 34] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 34 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 35] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 35 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 36] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 36 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 37] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 37 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 38] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 38 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 39] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 39 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 40] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 40 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 41] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 41 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 42] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 42 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 43] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 43 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 44] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 44 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 45] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 45 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 46] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 46 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 47] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 47 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 48] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 48 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 49] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 49 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 50] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 50 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 51] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 51 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 52] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 52 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 53] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 53 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 54] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 54 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 55] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 55 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 56] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 56 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 57] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 57 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 58] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 58 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 59] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 59 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 60] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 60 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 61] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 61 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 62] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 62 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 63] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 63 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +impl AbiEncode for [T; 64] +where + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + let mut i = 0; + while i < 64 { + self[i].abi_encode(buffer); + i += 1; + } + } +} +// END ARRAY_ENCODE + +// Encode Tuples + +impl AbiEncode for () { + fn abi_encode(self, ref mut _buffer: Buffer) {} +} + +// BEGIN TUPLES_ENCODE +impl AbiEncode for (A, ) +where + A: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + } +} +impl AbiEncode for (A, B) +where + A: AbiEncode, + B: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H, I) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, + I: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + self.8.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H, I, J) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, + I: AbiEncode, + J: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + self.8.abi_encode(buffer); + self.9.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, + I: AbiEncode, + J: AbiEncode, + K: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + self.8.abi_encode(buffer); + self.9.abi_encode(buffer); + self.10.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, + I: AbiEncode, + J: AbiEncode, + K: AbiEncode, + L: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + self.8.abi_encode(buffer); + self.9.abi_encode(buffer); + self.10.abi_encode(buffer); + self.11.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, + I: AbiEncode, + J: AbiEncode, + K: AbiEncode, + L: AbiEncode, + M: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + self.8.abi_encode(buffer); + self.9.abi_encode(buffer); + self.10.abi_encode(buffer); + self.11.abi_encode(buffer); + self.12.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, + I: AbiEncode, + J: AbiEncode, + K: AbiEncode, + L: AbiEncode, + M: AbiEncode, + N: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + self.8.abi_encode(buffer); + self.9.abi_encode(buffer); + self.10.abi_encode(buffer); + self.11.abi_encode(buffer); + self.12.abi_encode(buffer); + self.13.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, + I: AbiEncode, + J: AbiEncode, + K: AbiEncode, + L: AbiEncode, + M: AbiEncode, + N: AbiEncode, + O: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + self.8.abi_encode(buffer); + self.9.abi_encode(buffer); + self.10.abi_encode(buffer); + self.11.abi_encode(buffer); + self.12.abi_encode(buffer); + self.13.abi_encode(buffer); + self.14.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, + I: AbiEncode, + J: AbiEncode, + K: AbiEncode, + L: AbiEncode, + M: AbiEncode, + N: AbiEncode, + O: AbiEncode, + P: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + self.8.abi_encode(buffer); + self.9.abi_encode(buffer); + self.10.abi_encode(buffer); + self.11.abi_encode(buffer); + self.12.abi_encode(buffer); + self.13.abi_encode(buffer); + self.14.abi_encode(buffer); + self.15.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, + I: AbiEncode, + J: AbiEncode, + K: AbiEncode, + L: AbiEncode, + M: AbiEncode, + N: AbiEncode, + O: AbiEncode, + P: AbiEncode, + Q: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + self.8.abi_encode(buffer); + self.9.abi_encode(buffer); + self.10.abi_encode(buffer); + self.11.abi_encode(buffer); + self.12.abi_encode(buffer); + self.13.abi_encode(buffer); + self.14.abi_encode(buffer); + self.15.abi_encode(buffer); + self.16.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, + I: AbiEncode, + J: AbiEncode, + K: AbiEncode, + L: AbiEncode, + M: AbiEncode, + N: AbiEncode, + O: AbiEncode, + P: AbiEncode, + Q: AbiEncode, + R: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + self.8.abi_encode(buffer); + self.9.abi_encode(buffer); + self.10.abi_encode(buffer); + self.11.abi_encode(buffer); + self.12.abi_encode(buffer); + self.13.abi_encode(buffer); + self.14.abi_encode(buffer); + self.15.abi_encode(buffer); + self.16.abi_encode(buffer); + self.17.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, + I: AbiEncode, + J: AbiEncode, + K: AbiEncode, + L: AbiEncode, + M: AbiEncode, + N: AbiEncode, + O: AbiEncode, + P: AbiEncode, + Q: AbiEncode, + R: AbiEncode, + S: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + self.8.abi_encode(buffer); + self.9.abi_encode(buffer); + self.10.abi_encode(buffer); + self.11.abi_encode(buffer); + self.12.abi_encode(buffer); + self.13.abi_encode(buffer); + self.14.abi_encode(buffer); + self.15.abi_encode(buffer); + self.16.abi_encode(buffer); + self.17.abi_encode(buffer); + self.18.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, + I: AbiEncode, + J: AbiEncode, + K: AbiEncode, + L: AbiEncode, + M: AbiEncode, + N: AbiEncode, + O: AbiEncode, + P: AbiEncode, + Q: AbiEncode, + R: AbiEncode, + S: AbiEncode, + T: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + self.8.abi_encode(buffer); + self.9.abi_encode(buffer); + self.10.abi_encode(buffer); + self.11.abi_encode(buffer); + self.12.abi_encode(buffer); + self.13.abi_encode(buffer); + self.14.abi_encode(buffer); + self.15.abi_encode(buffer); + self.16.abi_encode(buffer); + self.17.abi_encode(buffer); + self.18.abi_encode(buffer); + self.19.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, + I: AbiEncode, + J: AbiEncode, + K: AbiEncode, + L: AbiEncode, + M: AbiEncode, + N: AbiEncode, + O: AbiEncode, + P: AbiEncode, + Q: AbiEncode, + R: AbiEncode, + S: AbiEncode, + T: AbiEncode, + U: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + self.8.abi_encode(buffer); + self.9.abi_encode(buffer); + self.10.abi_encode(buffer); + self.11.abi_encode(buffer); + self.12.abi_encode(buffer); + self.13.abi_encode(buffer); + self.14.abi_encode(buffer); + self.15.abi_encode(buffer); + self.16.abi_encode(buffer); + self.17.abi_encode(buffer); + self.18.abi_encode(buffer); + self.19.abi_encode(buffer); + self.20.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, + I: AbiEncode, + J: AbiEncode, + K: AbiEncode, + L: AbiEncode, + M: AbiEncode, + N: AbiEncode, + O: AbiEncode, + P: AbiEncode, + Q: AbiEncode, + R: AbiEncode, + S: AbiEncode, + T: AbiEncode, + U: AbiEncode, + V: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + self.8.abi_encode(buffer); + self.9.abi_encode(buffer); + self.10.abi_encode(buffer); + self.11.abi_encode(buffer); + self.12.abi_encode(buffer); + self.13.abi_encode(buffer); + self.14.abi_encode(buffer); + self.15.abi_encode(buffer); + self.16.abi_encode(buffer); + self.17.abi_encode(buffer); + self.18.abi_encode(buffer); + self.19.abi_encode(buffer); + self.20.abi_encode(buffer); + self.21.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, + I: AbiEncode, + J: AbiEncode, + K: AbiEncode, + L: AbiEncode, + M: AbiEncode, + N: AbiEncode, + O: AbiEncode, + P: AbiEncode, + Q: AbiEncode, + R: AbiEncode, + S: AbiEncode, + T: AbiEncode, + U: AbiEncode, + V: AbiEncode, + W: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + self.8.abi_encode(buffer); + self.9.abi_encode(buffer); + self.10.abi_encode(buffer); + self.11.abi_encode(buffer); + self.12.abi_encode(buffer); + self.13.abi_encode(buffer); + self.14.abi_encode(buffer); + self.15.abi_encode(buffer); + self.16.abi_encode(buffer); + self.17.abi_encode(buffer); + self.18.abi_encode(buffer); + self.19.abi_encode(buffer); + self.20.abi_encode(buffer); + self.21.abi_encode(buffer); + self.22.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, + I: AbiEncode, + J: AbiEncode, + K: AbiEncode, + L: AbiEncode, + M: AbiEncode, + N: AbiEncode, + O: AbiEncode, + P: AbiEncode, + Q: AbiEncode, + R: AbiEncode, + S: AbiEncode, + T: AbiEncode, + U: AbiEncode, + V: AbiEncode, + W: AbiEncode, + X: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + self.8.abi_encode(buffer); + self.9.abi_encode(buffer); + self.10.abi_encode(buffer); + self.11.abi_encode(buffer); + self.12.abi_encode(buffer); + self.13.abi_encode(buffer); + self.14.abi_encode(buffer); + self.15.abi_encode(buffer); + self.16.abi_encode(buffer); + self.17.abi_encode(buffer); + self.18.abi_encode(buffer); + self.19.abi_encode(buffer); + self.20.abi_encode(buffer); + self.21.abi_encode(buffer); + self.22.abi_encode(buffer); + self.23.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, + I: AbiEncode, + J: AbiEncode, + K: AbiEncode, + L: AbiEncode, + M: AbiEncode, + N: AbiEncode, + O: AbiEncode, + P: AbiEncode, + Q: AbiEncode, + R: AbiEncode, + S: AbiEncode, + T: AbiEncode, + U: AbiEncode, + V: AbiEncode, + W: AbiEncode, + X: AbiEncode, + Y: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + self.8.abi_encode(buffer); + self.9.abi_encode(buffer); + self.10.abi_encode(buffer); + self.11.abi_encode(buffer); + self.12.abi_encode(buffer); + self.13.abi_encode(buffer); + self.14.abi_encode(buffer); + self.15.abi_encode(buffer); + self.16.abi_encode(buffer); + self.17.abi_encode(buffer); + self.18.abi_encode(buffer); + self.19.abi_encode(buffer); + self.20.abi_encode(buffer); + self.21.abi_encode(buffer); + self.22.abi_encode(buffer); + self.23.abi_encode(buffer); + self.24.abi_encode(buffer); + } +} +impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z) +where + A: AbiEncode, + B: AbiEncode, + C: AbiEncode, + D: AbiEncode, + E: AbiEncode, + F: AbiEncode, + G: AbiEncode, + H: AbiEncode, + I: AbiEncode, + J: AbiEncode, + K: AbiEncode, + L: AbiEncode, + M: AbiEncode, + N: AbiEncode, + O: AbiEncode, + P: AbiEncode, + Q: AbiEncode, + R: AbiEncode, + S: AbiEncode, + T: AbiEncode, + U: AbiEncode, + V: AbiEncode, + W: AbiEncode, + X: AbiEncode, + Y: AbiEncode, + Z: AbiEncode, +{ + fn abi_encode(self, ref mut buffer: Buffer) { + self.0.abi_encode(buffer); + self.1.abi_encode(buffer); + self.2.abi_encode(buffer); + self.3.abi_encode(buffer); + self.4.abi_encode(buffer); + self.5.abi_encode(buffer); + self.6.abi_encode(buffer); + self.7.abi_encode(buffer); + self.8.abi_encode(buffer); + self.9.abi_encode(buffer); + self.10.abi_encode(buffer); + self.11.abi_encode(buffer); + self.12.abi_encode(buffer); + self.13.abi_encode(buffer); + self.14.abi_encode(buffer); + self.15.abi_encode(buffer); + self.16.abi_encode(buffer); + self.17.abi_encode(buffer); + self.18.abi_encode(buffer); + self.19.abi_encode(buffer); + self.20.abi_encode(buffer); + self.21.abi_encode(buffer); + self.22.abi_encode(buffer); + self.23.abi_encode(buffer); + self.24.abi_encode(buffer); + self.25.abi_encode(buffer); + } +} +// END TUPLES_ENCODE + +pub fn encode(item: T) -> raw_slice +where + T: AbiEncode, +{ + let mut buffer = Buffer::new(); + item.abi_encode(buffer); + buffer.as_raw_slice() +} + +pub fn abi_decode(data: raw_slice) -> T +where + T: AbiDecode, +{ + let mut buffer = BufferReader::from_parts(data.ptr(), data.len::()); + T::abi_decode(buffer) +} + +// Decode + +pub trait AbiDecode { + fn abi_decode(ref mut buffer: BufferReader) -> Self; +} + +impl AbiDecode for b256 { + fn abi_decode(ref mut buffer: BufferReader) -> b256 { + buffer.read::() + } +} + +impl AbiDecode for u256 { + fn abi_decode(ref mut buffer: BufferReader) -> u256 { + buffer.read::() + } +} + +impl AbiDecode for u64 { + fn abi_decode(ref mut buffer: BufferReader) -> u64 { + buffer.read::() + } +} + +impl AbiDecode for u32 { + fn abi_decode(ref mut buffer: BufferReader) -> u32 { + use ::primitive_conversions::*; + let a = buffer.read::().as_u32(); + let b = buffer.read::().as_u32(); + let c = buffer.read::().as_u32(); + let d = buffer.read::().as_u32(); + (a << 24) | (b << 16) | (c << 8) | d + } +} + +impl AbiDecode for u16 { + fn abi_decode(ref mut buffer: BufferReader) -> u16 { + use ::primitive_conversions::*; + let a = buffer.read::().as_u16(); + let b = buffer.read::().as_u16(); + (a << 8) | b + } +} + +impl AbiDecode for u8 { + fn abi_decode(ref mut buffer: BufferReader) -> u8 { + buffer.read::() + } +} + +impl AbiDecode for bool { + fn abi_decode(ref mut buffer: BufferReader) -> bool { + buffer.read::() + } +} + +impl AbiDecode for raw_slice { + fn abi_decode(ref mut buffer: BufferReader) -> raw_slice { + let len = u64::abi_decode(buffer); + let data = buffer.read_bytes(len); + asm(s: (data.ptr(), len)) { + s: raw_slice + } + } +} + +impl AbiDecode for str { + fn abi_decode(ref mut buffer: BufferReader) -> str { + let len = u64::abi_decode(buffer); + let data = buffer.read_bytes(len); + asm(s: (data.ptr(), len)) { + s: str + } + } +} + +// BEGIN STRARRAY_DECODE +impl AbiDecode for str[1] { + fn abi_decode(ref mut buffer: BufferReader) -> str[1] { + let data = buffer.read_bytes(1); + asm(s: data.ptr()) { + s: str[1] + } + } +} +impl AbiDecode for str[2] { + fn abi_decode(ref mut buffer: BufferReader) -> str[2] { + let data = buffer.read_bytes(2); + asm(s: data.ptr()) { + s: str[2] + } + } +} +impl AbiDecode for str[3] { + fn abi_decode(ref mut buffer: BufferReader) -> str[3] { + let data = buffer.read_bytes(3); + asm(s: data.ptr()) { + s: str[3] + } + } +} +impl AbiDecode for str[4] { + fn abi_decode(ref mut buffer: BufferReader) -> str[4] { + let data = buffer.read_bytes(4); + asm(s: data.ptr()) { + s: str[4] + } + } +} +impl AbiDecode for str[5] { + fn abi_decode(ref mut buffer: BufferReader) -> str[5] { + let data = buffer.read_bytes(5); + asm(s: data.ptr()) { + s: str[5] + } + } +} +impl AbiDecode for str[6] { + fn abi_decode(ref mut buffer: BufferReader) -> str[6] { + let data = buffer.read_bytes(6); + asm(s: data.ptr()) { + s: str[6] + } + } +} +impl AbiDecode for str[7] { + fn abi_decode(ref mut buffer: BufferReader) -> str[7] { + let data = buffer.read_bytes(7); + asm(s: data.ptr()) { + s: str[7] + } + } +} +impl AbiDecode for str[8] { + fn abi_decode(ref mut buffer: BufferReader) -> str[8] { + let data = buffer.read_bytes(8); + asm(s: data.ptr()) { + s: str[8] + } + } +} +impl AbiDecode for str[9] { + fn abi_decode(ref mut buffer: BufferReader) -> str[9] { + let data = buffer.read_bytes(9); + asm(s: data.ptr()) { + s: str[9] + } + } +} +impl AbiDecode for str[10] { + fn abi_decode(ref mut buffer: BufferReader) -> str[10] { + let data = buffer.read_bytes(10); + asm(s: data.ptr()) { + s: str[10] + } + } +} +impl AbiDecode for str[11] { + fn abi_decode(ref mut buffer: BufferReader) -> str[11] { + let data = buffer.read_bytes(11); + asm(s: data.ptr()) { + s: str[11] + } + } +} +impl AbiDecode for str[12] { + fn abi_decode(ref mut buffer: BufferReader) -> str[12] { + let data = buffer.read_bytes(12); + asm(s: data.ptr()) { + s: str[12] + } + } +} +impl AbiDecode for str[13] { + fn abi_decode(ref mut buffer: BufferReader) -> str[13] { + let data = buffer.read_bytes(13); + asm(s: data.ptr()) { + s: str[13] + } + } +} +impl AbiDecode for str[14] { + fn abi_decode(ref mut buffer: BufferReader) -> str[14] { + let data = buffer.read_bytes(14); + asm(s: data.ptr()) { + s: str[14] + } + } +} +impl AbiDecode for str[15] { + fn abi_decode(ref mut buffer: BufferReader) -> str[15] { + let data = buffer.read_bytes(15); + asm(s: data.ptr()) { + s: str[15] + } + } +} +impl AbiDecode for str[16] { + fn abi_decode(ref mut buffer: BufferReader) -> str[16] { + let data = buffer.read_bytes(16); + asm(s: data.ptr()) { + s: str[16] + } + } +} +impl AbiDecode for str[17] { + fn abi_decode(ref mut buffer: BufferReader) -> str[17] { + let data = buffer.read_bytes(17); + asm(s: data.ptr()) { + s: str[17] + } + } +} +impl AbiDecode for str[18] { + fn abi_decode(ref mut buffer: BufferReader) -> str[18] { + let data = buffer.read_bytes(18); + asm(s: data.ptr()) { + s: str[18] + } + } +} +impl AbiDecode for str[19] { + fn abi_decode(ref mut buffer: BufferReader) -> str[19] { + let data = buffer.read_bytes(19); + asm(s: data.ptr()) { + s: str[19] + } + } +} +impl AbiDecode for str[20] { + fn abi_decode(ref mut buffer: BufferReader) -> str[20] { + let data = buffer.read_bytes(20); + asm(s: data.ptr()) { + s: str[20] + } + } +} +impl AbiDecode for str[21] { + fn abi_decode(ref mut buffer: BufferReader) -> str[21] { + let data = buffer.read_bytes(21); + asm(s: data.ptr()) { + s: str[21] + } + } +} +impl AbiDecode for str[22] { + fn abi_decode(ref mut buffer: BufferReader) -> str[22] { + let data = buffer.read_bytes(22); + asm(s: data.ptr()) { + s: str[22] + } + } +} +impl AbiDecode for str[23] { + fn abi_decode(ref mut buffer: BufferReader) -> str[23] { + let data = buffer.read_bytes(23); + asm(s: data.ptr()) { + s: str[23] + } + } +} +impl AbiDecode for str[24] { + fn abi_decode(ref mut buffer: BufferReader) -> str[24] { + let data = buffer.read_bytes(24); + asm(s: data.ptr()) { + s: str[24] + } + } +} +impl AbiDecode for str[25] { + fn abi_decode(ref mut buffer: BufferReader) -> str[25] { + let data = buffer.read_bytes(25); + asm(s: data.ptr()) { + s: str[25] + } + } +} +impl AbiDecode for str[26] { + fn abi_decode(ref mut buffer: BufferReader) -> str[26] { + let data = buffer.read_bytes(26); + asm(s: data.ptr()) { + s: str[26] + } + } +} +impl AbiDecode for str[27] { + fn abi_decode(ref mut buffer: BufferReader) -> str[27] { + let data = buffer.read_bytes(27); + asm(s: data.ptr()) { + s: str[27] + } + } +} +impl AbiDecode for str[28] { + fn abi_decode(ref mut buffer: BufferReader) -> str[28] { + let data = buffer.read_bytes(28); + asm(s: data.ptr()) { + s: str[28] + } } } -impl AbiEncode for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z) -where - A: AbiEncode, - B: AbiEncode, - C: AbiEncode, - D: AbiEncode, - E: AbiEncode, - F: AbiEncode, - G: AbiEncode, - H: AbiEncode, - I: AbiEncode, - J: AbiEncode, - K: AbiEncode, - L: AbiEncode, - M: AbiEncode, - N: AbiEncode, - O: AbiEncode, - P: AbiEncode, - Q: AbiEncode, - R: AbiEncode, - S: AbiEncode, - T: AbiEncode, - U: AbiEncode, - V: AbiEncode, - W: AbiEncode, - X: AbiEncode, - Y: AbiEncode, - Z: AbiEncode, -{ - fn abi_encode(self, ref mut buffer: Buffer) { - self.0.abi_encode(buffer); - self.1.abi_encode(buffer); - self.2.abi_encode(buffer); - self.3.abi_encode(buffer); - self.4.abi_encode(buffer); - self.5.abi_encode(buffer); - self.6.abi_encode(buffer); - self.7.abi_encode(buffer); - self.8.abi_encode(buffer); - self.9.abi_encode(buffer); - self.10.abi_encode(buffer); - self.11.abi_encode(buffer); - self.12.abi_encode(buffer); - self.13.abi_encode(buffer); - self.14.abi_encode(buffer); - self.15.abi_encode(buffer); - self.16.abi_encode(buffer); - self.17.abi_encode(buffer); - self.18.abi_encode(buffer); - self.19.abi_encode(buffer); - self.20.abi_encode(buffer); - self.21.abi_encode(buffer); - self.22.abi_encode(buffer); - self.23.abi_encode(buffer); - self.24.abi_encode(buffer); - self.25.abi_encode(buffer); +impl AbiDecode for str[29] { + fn abi_decode(ref mut buffer: BufferReader) -> str[29] { + let data = buffer.read_bytes(29); + asm(s: data.ptr()) { + s: str[29] + } } } -// END TUPLES_ENCODE - -pub fn encode(item: T) -> raw_slice -where - T: AbiEncode, -{ - let mut buffer = Buffer::new(); - item.abi_encode(buffer); - buffer.as_raw_slice() +impl AbiDecode for str[30] { + fn abi_decode(ref mut buffer: BufferReader) -> str[30] { + let data = buffer.read_bytes(30); + asm(s: data.ptr()) { + s: str[30] + } + } } - -pub fn abi_decode(data: raw_slice) -> T -where - T: AbiDecode, -{ - let mut buffer = BufferReader::from_parts(data.ptr(), data.len::()); - T::abi_decode(buffer) +impl AbiDecode for str[31] { + fn abi_decode(ref mut buffer: BufferReader) -> str[31] { + let data = buffer.read_bytes(31); + asm(s: data.ptr()) { + s: str[31] + } + } } - -// Decode - -pub trait AbiDecode { - fn abi_decode(ref mut buffer: BufferReader) -> Self; +impl AbiDecode for str[32] { + fn abi_decode(ref mut buffer: BufferReader) -> str[32] { + let data = buffer.read_bytes(32); + asm(s: data.ptr()) { + s: str[32] + } + } } - -impl AbiDecode for b256 { - fn abi_decode(ref mut buffer: BufferReader) -> b256 { - buffer.read::() +impl AbiDecode for str[33] { + fn abi_decode(ref mut buffer: BufferReader) -> str[33] { + let data = buffer.read_bytes(33); + asm(s: data.ptr()) { + s: str[33] + } } } - -impl AbiDecode for u256 { - fn abi_decode(ref mut buffer: BufferReader) -> u256 { - buffer.read::() +impl AbiDecode for str[34] { + fn abi_decode(ref mut buffer: BufferReader) -> str[34] { + let data = buffer.read_bytes(34); + asm(s: data.ptr()) { + s: str[34] + } } } - -impl AbiDecode for u64 { - fn abi_decode(ref mut buffer: BufferReader) -> u64 { - buffer.read::() +impl AbiDecode for str[35] { + fn abi_decode(ref mut buffer: BufferReader) -> str[35] { + let data = buffer.read_bytes(35); + asm(s: data.ptr()) { + s: str[35] + } } } - -impl AbiDecode for u32 { - fn abi_decode(ref mut buffer: BufferReader) -> u32 { - use ::primitive_conversions::*; - let a = buffer.read::().as_u32(); - let b = buffer.read::().as_u32(); - let c = buffer.read::().as_u32(); - let d = buffer.read::().as_u32(); - (a << 24) | (b << 16) | (c << 8) | d +impl AbiDecode for str[36] { + fn abi_decode(ref mut buffer: BufferReader) -> str[36] { + let data = buffer.read_bytes(36); + asm(s: data.ptr()) { + s: str[36] + } } } - -impl AbiDecode for u16 { - fn abi_decode(ref mut buffer: BufferReader) -> u16 { - use ::primitive_conversions::*; - let a = buffer.read::().as_u16(); - let b = buffer.read::().as_u16(); - (a << 8) | b +impl AbiDecode for str[37] { + fn abi_decode(ref mut buffer: BufferReader) -> str[37] { + let data = buffer.read_bytes(37); + asm(s: data.ptr()) { + s: str[37] + } } } - -impl AbiDecode for u8 { - fn abi_decode(ref mut buffer: BufferReader) -> u8 { - buffer.read::() +impl AbiDecode for str[38] { + fn abi_decode(ref mut buffer: BufferReader) -> str[38] { + let data = buffer.read_bytes(38); + asm(s: data.ptr()) { + s: str[38] + } } } - -impl AbiDecode for bool { - fn abi_decode(ref mut buffer: BufferReader) -> bool { - buffer.read::() +impl AbiDecode for str[39] { + fn abi_decode(ref mut buffer: BufferReader) -> str[39] { + let data = buffer.read_bytes(39); + asm(s: data.ptr()) { + s: str[39] + } } } - -impl AbiDecode for raw_slice { - fn abi_decode(ref mut buffer: BufferReader) -> raw_slice { - let len = u64::abi_decode(buffer); - let data = buffer.read_bytes(len); - asm(s: (data.ptr(), len)) { - s: raw_slice +impl AbiDecode for str[40] { + fn abi_decode(ref mut buffer: BufferReader) -> str[40] { + let data = buffer.read_bytes(40); + asm(s: data.ptr()) { + s: str[40] } } } - -impl AbiDecode for str { - fn abi_decode(ref mut buffer: BufferReader) -> str { - let len = u64::abi_decode(buffer); - let data = buffer.read_bytes(len); - asm(s: (data.ptr(), len)) { - s: str +impl AbiDecode for str[41] { + fn abi_decode(ref mut buffer: BufferReader) -> str[41] { + let data = buffer.read_bytes(41); + asm(s: data.ptr()) { + s: str[41] } } } - -// BEGIN STRARRAY_DECODE -impl AbiDecode for str[1] { - fn abi_decode(ref mut buffer: BufferReader) -> str[1] { - let data = buffer.read_bytes(1); +impl AbiDecode for str[42] { + fn abi_decode(ref mut buffer: BufferReader) -> str[42] { + let data = buffer.read_bytes(42); asm(s: data.ptr()) { - s: str[1] + s: str[42] } } } -impl AbiDecode for str[2] { - fn abi_decode(ref mut buffer: BufferReader) -> str[2] { - let data = buffer.read_bytes(2); +impl AbiDecode for str[43] { + fn abi_decode(ref mut buffer: BufferReader) -> str[43] { + let data = buffer.read_bytes(43); asm(s: data.ptr()) { - s: str[2] + s: str[43] } } } -impl AbiDecode for str[3] { - fn abi_decode(ref mut buffer: BufferReader) -> str[3] { - let data = buffer.read_bytes(3); +impl AbiDecode for str[44] { + fn abi_decode(ref mut buffer: BufferReader) -> str[44] { + let data = buffer.read_bytes(44); asm(s: data.ptr()) { - s: str[3] + s: str[44] } } } -impl AbiDecode for str[4] { - fn abi_decode(ref mut buffer: BufferReader) -> str[4] { - let data = buffer.read_bytes(4); +impl AbiDecode for str[45] { + fn abi_decode(ref mut buffer: BufferReader) -> str[45] { + let data = buffer.read_bytes(45); asm(s: data.ptr()) { - s: str[4] + s: str[45] + } + } +} +impl AbiDecode for str[46] { + fn abi_decode(ref mut buffer: BufferReader) -> str[46] { + let data = buffer.read_bytes(46); + asm(s: data.ptr()) { + s: str[46] + } + } +} +impl AbiDecode for str[47] { + fn abi_decode(ref mut buffer: BufferReader) -> str[47] { + let data = buffer.read_bytes(47); + asm(s: data.ptr()) { + s: str[47] } } } -impl AbiDecode for str[5] { - fn abi_decode(ref mut buffer: BufferReader) -> str[5] { - let data = buffer.read_bytes(5); +impl AbiDecode for str[48] { + fn abi_decode(ref mut buffer: BufferReader) -> str[48] { + let data = buffer.read_bytes(48); asm(s: data.ptr()) { - s: str[5] + s: str[48] } } } -impl AbiDecode for str[6] { - fn abi_decode(ref mut buffer: BufferReader) -> str[6] { - let data = buffer.read_bytes(6); +impl AbiDecode for str[49] { + fn abi_decode(ref mut buffer: BufferReader) -> str[49] { + let data = buffer.read_bytes(49); asm(s: data.ptr()) { - s: str[6] + s: str[49] } } } -impl AbiDecode for str[7] { - fn abi_decode(ref mut buffer: BufferReader) -> str[7] { - let data = buffer.read_bytes(7); +impl AbiDecode for str[50] { + fn abi_decode(ref mut buffer: BufferReader) -> str[50] { + let data = buffer.read_bytes(50); asm(s: data.ptr()) { - s: str[7] + s: str[50] } } } -impl AbiDecode for str[8] { - fn abi_decode(ref mut buffer: BufferReader) -> str[8] { - let data = buffer.read_bytes(8); +impl AbiDecode for str[51] { + fn abi_decode(ref mut buffer: BufferReader) -> str[51] { + let data = buffer.read_bytes(51); asm(s: data.ptr()) { - s: str[8] + s: str[51] } } } -impl AbiDecode for str[9] { - fn abi_decode(ref mut buffer: BufferReader) -> str[9] { - let data = buffer.read_bytes(9); +impl AbiDecode for str[52] { + fn abi_decode(ref mut buffer: BufferReader) -> str[52] { + let data = buffer.read_bytes(52); asm(s: data.ptr()) { - s: str[9] + s: str[52] } } } -impl AbiDecode for str[10] { - fn abi_decode(ref mut buffer: BufferReader) -> str[10] { - let data = buffer.read_bytes(10); +impl AbiDecode for str[53] { + fn abi_decode(ref mut buffer: BufferReader) -> str[53] { + let data = buffer.read_bytes(53); asm(s: data.ptr()) { - s: str[10] + s: str[53] } } } -impl AbiDecode for str[11] { - fn abi_decode(ref mut buffer: BufferReader) -> str[11] { - let data = buffer.read_bytes(11); +impl AbiDecode for str[54] { + fn abi_decode(ref mut buffer: BufferReader) -> str[54] { + let data = buffer.read_bytes(54); asm(s: data.ptr()) { - s: str[11] + s: str[54] } } } -impl AbiDecode for str[12] { - fn abi_decode(ref mut buffer: BufferReader) -> str[12] { - let data = buffer.read_bytes(12); +impl AbiDecode for str[55] { + fn abi_decode(ref mut buffer: BufferReader) -> str[55] { + let data = buffer.read_bytes(55); asm(s: data.ptr()) { - s: str[12] + s: str[55] } } } -impl AbiDecode for str[13] { - fn abi_decode(ref mut buffer: BufferReader) -> str[13] { - let data = buffer.read_bytes(13); +impl AbiDecode for str[56] { + fn abi_decode(ref mut buffer: BufferReader) -> str[56] { + let data = buffer.read_bytes(56); asm(s: data.ptr()) { - s: str[13] + s: str[56] } } } -impl AbiDecode for str[14] { - fn abi_decode(ref mut buffer: BufferReader) -> str[14] { - let data = buffer.read_bytes(14); +impl AbiDecode for str[57] { + fn abi_decode(ref mut buffer: BufferReader) -> str[57] { + let data = buffer.read_bytes(57); asm(s: data.ptr()) { - s: str[14] + s: str[57] } } } -impl AbiDecode for str[15] { - fn abi_decode(ref mut buffer: BufferReader) -> str[15] { - let data = buffer.read_bytes(15); +impl AbiDecode for str[58] { + fn abi_decode(ref mut buffer: BufferReader) -> str[58] { + let data = buffer.read_bytes(58); asm(s: data.ptr()) { - s: str[15] + s: str[58] } } } -impl AbiDecode for str[16] { - fn abi_decode(ref mut buffer: BufferReader) -> str[16] { - let data = buffer.read_bytes(16); +impl AbiDecode for str[59] { + fn abi_decode(ref mut buffer: BufferReader) -> str[59] { + let data = buffer.read_bytes(59); asm(s: data.ptr()) { - s: str[16] + s: str[59] } } } -impl AbiDecode for str[17] { - fn abi_decode(ref mut buffer: BufferReader) -> str[17] { - let data = buffer.read_bytes(17); +impl AbiDecode for str[60] { + fn abi_decode(ref mut buffer: BufferReader) -> str[60] { + let data = buffer.read_bytes(60); asm(s: data.ptr()) { - s: str[17] + s: str[60] } } } -impl AbiDecode for str[18] { - fn abi_decode(ref mut buffer: BufferReader) -> str[18] { - let data = buffer.read_bytes(18); +impl AbiDecode for str[61] { + fn abi_decode(ref mut buffer: BufferReader) -> str[61] { + let data = buffer.read_bytes(61); asm(s: data.ptr()) { - s: str[18] + s: str[61] } } } -impl AbiDecode for str[19] { - fn abi_decode(ref mut buffer: BufferReader) -> str[19] { - let data = buffer.read_bytes(19); +impl AbiDecode for str[62] { + fn abi_decode(ref mut buffer: BufferReader) -> str[62] { + let data = buffer.read_bytes(62); asm(s: data.ptr()) { - s: str[19] + s: str[62] } } } -impl AbiDecode for str[20] { - fn abi_decode(ref mut buffer: BufferReader) -> str[20] { - let data = buffer.read_bytes(20); +impl AbiDecode for str[63] { + fn abi_decode(ref mut buffer: BufferReader) -> str[63] { + let data = buffer.read_bytes(63); asm(s: data.ptr()) { - s: str[20] + s: str[63] } } } -impl AbiDecode for str[21] { - fn abi_decode(ref mut buffer: BufferReader) -> str[21] { - let data = buffer.read_bytes(21); +impl AbiDecode for str[64] { + fn abi_decode(ref mut buffer: BufferReader) -> str[64] { + let data = buffer.read_bytes(64); asm(s: data.ptr()) { - s: str[21] + s: str[64] } } } -impl AbiDecode for str[22] { - fn abi_decode(ref mut buffer: BufferReader) -> str[22] { - let data = buffer.read_bytes(22); - asm(s: data.ptr()) { - s: str[22] - } +// END STRARRAY_DECODE + +// BEGIN ARRAY_DECODE +impl AbiDecode for [T; 1] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 1] { + let first: T = buffer.decode::(); + let mut array = [first; 1]; + let mut i = 1; + while i < 1 { + array[i] = buffer.decode::(); + i += 1; + }; + array + } +} +impl AbiDecode for [T; 2] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 2] { + let first: T = buffer.decode::(); + let mut array = [first; 2]; + let mut i = 1; + while i < 2 { + array[i] = buffer.decode::(); + i += 1; + }; + array + } +} +impl AbiDecode for [T; 3] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 3] { + let first: T = buffer.decode::(); + let mut array = [first; 3]; + let mut i = 1; + while i < 3 { + array[i] = buffer.decode::(); + i += 1; + }; + array + } +} +impl AbiDecode for [T; 4] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 4] { + let first: T = buffer.decode::(); + let mut array = [first; 4]; + let mut i = 1; + while i < 4 { + array[i] = buffer.decode::(); + i += 1; + }; + array + } +} +impl AbiDecode for [T; 5] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 5] { + let first: T = buffer.decode::(); + let mut array = [first; 5]; + let mut i = 1; + while i < 5 { + array[i] = buffer.decode::(); + i += 1; + }; + array + } +} +impl AbiDecode for [T; 6] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 6] { + let first: T = buffer.decode::(); + let mut array = [first; 6]; + let mut i = 1; + while i < 6 { + array[i] = buffer.decode::(); + i += 1; + }; + array + } +} +impl AbiDecode for [T; 7] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 7] { + let first: T = buffer.decode::(); + let mut array = [first; 7]; + let mut i = 1; + while i < 7 { + array[i] = buffer.decode::(); + i += 1; + }; + array + } +} +impl AbiDecode for [T; 8] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 8] { + let first: T = buffer.decode::(); + let mut array = [first; 8]; + let mut i = 1; + while i < 8 { + array[i] = buffer.decode::(); + i += 1; + }; + array + } +} +impl AbiDecode for [T; 9] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 9] { + let first: T = buffer.decode::(); + let mut array = [first; 9]; + let mut i = 1; + while i < 9 { + array[i] = buffer.decode::(); + i += 1; + }; + array + } +} +impl AbiDecode for [T; 10] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 10] { + let first: T = buffer.decode::(); + let mut array = [first; 10]; + let mut i = 1; + while i < 10 { + array[i] = buffer.decode::(); + i += 1; + }; + array + } +} +impl AbiDecode for [T; 11] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 11] { + let first: T = buffer.decode::(); + let mut array = [first; 11]; + let mut i = 1; + while i < 11 { + array[i] = buffer.decode::(); + i += 1; + }; + array + } +} +impl AbiDecode for [T; 12] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 12] { + let first: T = buffer.decode::(); + let mut array = [first; 12]; + let mut i = 1; + while i < 12 { + array[i] = buffer.decode::(); + i += 1; + }; + array + } +} +impl AbiDecode for [T; 13] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 13] { + let first: T = buffer.decode::(); + let mut array = [first; 13]; + let mut i = 1; + while i < 13 { + array[i] = buffer.decode::(); + i += 1; + }; + array + } +} +impl AbiDecode for [T; 14] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 14] { + let first: T = buffer.decode::(); + let mut array = [first; 14]; + let mut i = 1; + while i < 14 { + array[i] = buffer.decode::(); + i += 1; + }; + array + } +} +impl AbiDecode for [T; 15] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 15] { + let first: T = buffer.decode::(); + let mut array = [first; 15]; + let mut i = 1; + while i < 15 { + array[i] = buffer.decode::(); + i += 1; + }; + array + } +} +impl AbiDecode for [T; 16] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 16] { + let first: T = buffer.decode::(); + let mut array = [first; 16]; + let mut i = 1; + while i < 16 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[23] { - fn abi_decode(ref mut buffer: BufferReader) -> str[23] { - let data = buffer.read_bytes(23); - asm(s: data.ptr()) { - s: str[23] - } +impl AbiDecode for [T; 17] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 17] { + let first: T = buffer.decode::(); + let mut array = [first; 17]; + let mut i = 1; + while i < 17 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[24] { - fn abi_decode(ref mut buffer: BufferReader) -> str[24] { - let data = buffer.read_bytes(24); - asm(s: data.ptr()) { - s: str[24] - } +impl AbiDecode for [T; 18] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 18] { + let first: T = buffer.decode::(); + let mut array = [first; 18]; + let mut i = 1; + while i < 18 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[25] { - fn abi_decode(ref mut buffer: BufferReader) -> str[25] { - let data = buffer.read_bytes(25); - asm(s: data.ptr()) { - s: str[25] - } +impl AbiDecode for [T; 19] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 19] { + let first: T = buffer.decode::(); + let mut array = [first; 19]; + let mut i = 1; + while i < 19 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[26] { - fn abi_decode(ref mut buffer: BufferReader) -> str[26] { - let data = buffer.read_bytes(26); - asm(s: data.ptr()) { - s: str[26] - } +impl AbiDecode for [T; 20] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 20] { + let first: T = buffer.decode::(); + let mut array = [first; 20]; + let mut i = 1; + while i < 20 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[27] { - fn abi_decode(ref mut buffer: BufferReader) -> str[27] { - let data = buffer.read_bytes(27); - asm(s: data.ptr()) { - s: str[27] - } +impl AbiDecode for [T; 21] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 21] { + let first: T = buffer.decode::(); + let mut array = [first; 21]; + let mut i = 1; + while i < 21 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[28] { - fn abi_decode(ref mut buffer: BufferReader) -> str[28] { - let data = buffer.read_bytes(28); - asm(s: data.ptr()) { - s: str[28] - } +impl AbiDecode for [T; 22] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 22] { + let first: T = buffer.decode::(); + let mut array = [first; 22]; + let mut i = 1; + while i < 22 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[29] { - fn abi_decode(ref mut buffer: BufferReader) -> str[29] { - let data = buffer.read_bytes(29); - asm(s: data.ptr()) { - s: str[29] - } +impl AbiDecode for [T; 23] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 23] { + let first: T = buffer.decode::(); + let mut array = [first; 23]; + let mut i = 1; + while i < 23 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[30] { - fn abi_decode(ref mut buffer: BufferReader) -> str[30] { - let data = buffer.read_bytes(30); - asm(s: data.ptr()) { - s: str[30] - } +impl AbiDecode for [T; 24] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 24] { + let first: T = buffer.decode::(); + let mut array = [first; 24]; + let mut i = 1; + while i < 24 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[31] { - fn abi_decode(ref mut buffer: BufferReader) -> str[31] { - let data = buffer.read_bytes(31); - asm(s: data.ptr()) { - s: str[31] - } +impl AbiDecode for [T; 25] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 25] { + let first: T = buffer.decode::(); + let mut array = [first; 25]; + let mut i = 1; + while i < 25 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[32] { - fn abi_decode(ref mut buffer: BufferReader) -> str[32] { - let data = buffer.read_bytes(32); - asm(s: data.ptr()) { - s: str[32] - } +impl AbiDecode for [T; 26] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 26] { + let first: T = buffer.decode::(); + let mut array = [first; 26]; + let mut i = 1; + while i < 26 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[33] { - fn abi_decode(ref mut buffer: BufferReader) -> str[33] { - let data = buffer.read_bytes(33); - asm(s: data.ptr()) { - s: str[33] - } +impl AbiDecode for [T; 27] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 27] { + let first: T = buffer.decode::(); + let mut array = [first; 27]; + let mut i = 1; + while i < 27 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[34] { - fn abi_decode(ref mut buffer: BufferReader) -> str[34] { - let data = buffer.read_bytes(34); - asm(s: data.ptr()) { - s: str[34] - } +impl AbiDecode for [T; 28] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 28] { + let first: T = buffer.decode::(); + let mut array = [first; 28]; + let mut i = 1; + while i < 28 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[35] { - fn abi_decode(ref mut buffer: BufferReader) -> str[35] { - let data = buffer.read_bytes(35); - asm(s: data.ptr()) { - s: str[35] - } +impl AbiDecode for [T; 29] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 29] { + let first: T = buffer.decode::(); + let mut array = [first; 29]; + let mut i = 1; + while i < 29 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[36] { - fn abi_decode(ref mut buffer: BufferReader) -> str[36] { - let data = buffer.read_bytes(36); - asm(s: data.ptr()) { - s: str[36] - } +impl AbiDecode for [T; 30] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 30] { + let first: T = buffer.decode::(); + let mut array = [first; 30]; + let mut i = 1; + while i < 30 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[37] { - fn abi_decode(ref mut buffer: BufferReader) -> str[37] { - let data = buffer.read_bytes(37); - asm(s: data.ptr()) { - s: str[37] - } +impl AbiDecode for [T; 31] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 31] { + let first: T = buffer.decode::(); + let mut array = [first; 31]; + let mut i = 1; + while i < 31 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[38] { - fn abi_decode(ref mut buffer: BufferReader) -> str[38] { - let data = buffer.read_bytes(38); - asm(s: data.ptr()) { - s: str[38] - } +impl AbiDecode for [T; 32] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 32] { + let first: T = buffer.decode::(); + let mut array = [first; 32]; + let mut i = 1; + while i < 32 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[39] { - fn abi_decode(ref mut buffer: BufferReader) -> str[39] { - let data = buffer.read_bytes(39); - asm(s: data.ptr()) { - s: str[39] - } +impl AbiDecode for [T; 33] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 33] { + let first: T = buffer.decode::(); + let mut array = [first; 33]; + let mut i = 1; + while i < 33 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[40] { - fn abi_decode(ref mut buffer: BufferReader) -> str[40] { - let data = buffer.read_bytes(40); - asm(s: data.ptr()) { - s: str[40] - } +impl AbiDecode for [T; 34] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 34] { + let first: T = buffer.decode::(); + let mut array = [first; 34]; + let mut i = 1; + while i < 34 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[41] { - fn abi_decode(ref mut buffer: BufferReader) -> str[41] { - let data = buffer.read_bytes(41); - asm(s: data.ptr()) { - s: str[41] - } +impl AbiDecode for [T; 35] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 35] { + let first: T = buffer.decode::(); + let mut array = [first; 35]; + let mut i = 1; + while i < 35 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[42] { - fn abi_decode(ref mut buffer: BufferReader) -> str[42] { - let data = buffer.read_bytes(42); - asm(s: data.ptr()) { - s: str[42] - } +impl AbiDecode for [T; 36] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 36] { + let first: T = buffer.decode::(); + let mut array = [first; 36]; + let mut i = 1; + while i < 36 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[43] { - fn abi_decode(ref mut buffer: BufferReader) -> str[43] { - let data = buffer.read_bytes(43); - asm(s: data.ptr()) { - s: str[43] - } +impl AbiDecode for [T; 37] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 37] { + let first: T = buffer.decode::(); + let mut array = [first; 37]; + let mut i = 1; + while i < 37 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[44] { - fn abi_decode(ref mut buffer: BufferReader) -> str[44] { - let data = buffer.read_bytes(44); - asm(s: data.ptr()) { - s: str[44] - } +impl AbiDecode for [T; 38] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 38] { + let first: T = buffer.decode::(); + let mut array = [first; 38]; + let mut i = 1; + while i < 38 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[45] { - fn abi_decode(ref mut buffer: BufferReader) -> str[45] { - let data = buffer.read_bytes(45); - asm(s: data.ptr()) { - s: str[45] - } +impl AbiDecode for [T; 39] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 39] { + let first: T = buffer.decode::(); + let mut array = [first; 39]; + let mut i = 1; + while i < 39 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[46] { - fn abi_decode(ref mut buffer: BufferReader) -> str[46] { - let data = buffer.read_bytes(46); - asm(s: data.ptr()) { - s: str[46] - } +impl AbiDecode for [T; 40] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 40] { + let first: T = buffer.decode::(); + let mut array = [first; 40]; + let mut i = 1; + while i < 40 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[47] { - fn abi_decode(ref mut buffer: BufferReader) -> str[47] { - let data = buffer.read_bytes(47); - asm(s: data.ptr()) { - s: str[47] - } +impl AbiDecode for [T; 41] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 41] { + let first: T = buffer.decode::(); + let mut array = [first; 41]; + let mut i = 1; + while i < 41 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[48] { - fn abi_decode(ref mut buffer: BufferReader) -> str[48] { - let data = buffer.read_bytes(48); - asm(s: data.ptr()) { - s: str[48] - } +impl AbiDecode for [T; 42] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 42] { + let first: T = buffer.decode::(); + let mut array = [first; 42]; + let mut i = 1; + while i < 42 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[49] { - fn abi_decode(ref mut buffer: BufferReader) -> str[49] { - let data = buffer.read_bytes(49); - asm(s: data.ptr()) { - s: str[49] - } +impl AbiDecode for [T; 43] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 43] { + let first: T = buffer.decode::(); + let mut array = [first; 43]; + let mut i = 1; + while i < 43 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[50] { - fn abi_decode(ref mut buffer: BufferReader) -> str[50] { - let data = buffer.read_bytes(50); - asm(s: data.ptr()) { - s: str[50] - } +impl AbiDecode for [T; 44] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 44] { + let first: T = buffer.decode::(); + let mut array = [first; 44]; + let mut i = 1; + while i < 44 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[51] { - fn abi_decode(ref mut buffer: BufferReader) -> str[51] { - let data = buffer.read_bytes(51); - asm(s: data.ptr()) { - s: str[51] - } +impl AbiDecode for [T; 45] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 45] { + let first: T = buffer.decode::(); + let mut array = [first; 45]; + let mut i = 1; + while i < 45 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[52] { - fn abi_decode(ref mut buffer: BufferReader) -> str[52] { - let data = buffer.read_bytes(52); - asm(s: data.ptr()) { - s: str[52] - } +impl AbiDecode for [T; 46] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 46] { + let first: T = buffer.decode::(); + let mut array = [first; 46]; + let mut i = 1; + while i < 46 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[53] { - fn abi_decode(ref mut buffer: BufferReader) -> str[53] { - let data = buffer.read_bytes(53); - asm(s: data.ptr()) { - s: str[53] - } +impl AbiDecode for [T; 47] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 47] { + let first: T = buffer.decode::(); + let mut array = [first; 47]; + let mut i = 1; + while i < 47 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[54] { - fn abi_decode(ref mut buffer: BufferReader) -> str[54] { - let data = buffer.read_bytes(54); - asm(s: data.ptr()) { - s: str[54] - } +impl AbiDecode for [T; 48] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 48] { + let first: T = buffer.decode::(); + let mut array = [first; 48]; + let mut i = 1; + while i < 48 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[55] { - fn abi_decode(ref mut buffer: BufferReader) -> str[55] { - let data = buffer.read_bytes(55); - asm(s: data.ptr()) { - s: str[55] - } +impl AbiDecode for [T; 49] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 49] { + let first: T = buffer.decode::(); + let mut array = [first; 49]; + let mut i = 1; + while i < 49 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[56] { - fn abi_decode(ref mut buffer: BufferReader) -> str[56] { - let data = buffer.read_bytes(56); - asm(s: data.ptr()) { - s: str[56] - } +impl AbiDecode for [T; 50] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 50] { + let first: T = buffer.decode::(); + let mut array = [first; 50]; + let mut i = 1; + while i < 50 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[57] { - fn abi_decode(ref mut buffer: BufferReader) -> str[57] { - let data = buffer.read_bytes(57); - asm(s: data.ptr()) { - s: str[57] - } +impl AbiDecode for [T; 51] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 51] { + let first: T = buffer.decode::(); + let mut array = [first; 51]; + let mut i = 1; + while i < 51 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[58] { - fn abi_decode(ref mut buffer: BufferReader) -> str[58] { - let data = buffer.read_bytes(58); - asm(s: data.ptr()) { - s: str[58] - } +impl AbiDecode for [T; 52] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 52] { + let first: T = buffer.decode::(); + let mut array = [first; 52]; + let mut i = 1; + while i < 52 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[59] { - fn abi_decode(ref mut buffer: BufferReader) -> str[59] { - let data = buffer.read_bytes(59); - asm(s: data.ptr()) { - s: str[59] - } +impl AbiDecode for [T; 53] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 53] { + let first: T = buffer.decode::(); + let mut array = [first; 53]; + let mut i = 1; + while i < 53 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[60] { - fn abi_decode(ref mut buffer: BufferReader) -> str[60] { - let data = buffer.read_bytes(60); - asm(s: data.ptr()) { - s: str[60] - } +impl AbiDecode for [T; 54] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 54] { + let first: T = buffer.decode::(); + let mut array = [first; 54]; + let mut i = 1; + while i < 54 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[61] { - fn abi_decode(ref mut buffer: BufferReader) -> str[61] { - let data = buffer.read_bytes(61); - asm(s: data.ptr()) { - s: str[61] - } +impl AbiDecode for [T; 55] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 55] { + let first: T = buffer.decode::(); + let mut array = [first; 55]; + let mut i = 1; + while i < 55 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[62] { - fn abi_decode(ref mut buffer: BufferReader) -> str[62] { - let data = buffer.read_bytes(62); - asm(s: data.ptr()) { - s: str[62] - } +impl AbiDecode for [T; 56] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 56] { + let first: T = buffer.decode::(); + let mut array = [first; 56]; + let mut i = 1; + while i < 56 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[63] { - fn abi_decode(ref mut buffer: BufferReader) -> str[63] { - let data = buffer.read_bytes(63); - asm(s: data.ptr()) { - s: str[63] - } +impl AbiDecode for [T; 57] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 57] { + let first: T = buffer.decode::(); + let mut array = [first; 57]; + let mut i = 1; + while i < 57 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -impl AbiDecode for str[64] { - fn abi_decode(ref mut buffer: BufferReader) -> str[64] { - let data = buffer.read_bytes(64); - asm(s: data.ptr()) { - s: str[64] - } +impl AbiDecode for [T; 58] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 58] { + let first: T = buffer.decode::(); + let mut array = [first; 58]; + let mut i = 1; + while i < 58 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } -// END STRARRAY_DECODE - -impl AbiDecode for [T; 0] +impl AbiDecode for [T; 59] where T: AbiDecode, { - fn abi_decode(ref mut _buffer: BufferReader) -> [T; 0] { - [] + fn abi_decode(ref mut buffer: BufferReader) -> [T; 59] { + let first: T = buffer.decode::(); + let mut array = [first; 59]; + let mut i = 1; + while i < 59 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } - -impl AbiDecode for [T; 1] +impl AbiDecode for [T; 60] where T: AbiDecode, { - fn abi_decode(ref mut buffer: BufferReader) -> [T; 1] { - [T::abi_decode(buffer)] + fn abi_decode(ref mut buffer: BufferReader) -> [T; 60] { + let first: T = buffer.decode::(); + let mut array = [first; 60]; + let mut i = 1; + while i < 60 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } - -impl AbiDecode for [T; 2] +impl AbiDecode for [T; 61] where T: AbiDecode, { - fn abi_decode(ref mut buffer: BufferReader) -> [T; 2] { - [T::abi_decode(buffer), T::abi_decode(buffer)] + fn abi_decode(ref mut buffer: BufferReader) -> [T; 61] { + let first: T = buffer.decode::(); + let mut array = [first; 61]; + let mut i = 1; + while i < 61 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } - -impl AbiDecode for [T; 3] +impl AbiDecode for [T; 62] where T: AbiDecode, { - fn abi_decode(ref mut buffer: BufferReader) -> [T; 3] { - [T::abi_decode(buffer), T::abi_decode(buffer), T::abi_decode(buffer)] + fn abi_decode(ref mut buffer: BufferReader) -> [T; 62] { + let first: T = buffer.decode::(); + let mut array = [first; 62]; + let mut i = 1; + while i < 62 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } - -impl AbiDecode for [T; 4] +impl AbiDecode for [T; 63] where T: AbiDecode, { - fn abi_decode(ref mut buffer: BufferReader) -> [T; 4] { - [ - T::abi_decode(buffer), - T::abi_decode(buffer), - T::abi_decode(buffer), - T::abi_decode(buffer), - ] + fn abi_decode(ref mut buffer: BufferReader) -> [T; 63] { + let first: T = buffer.decode::(); + let mut array = [first; 63]; + let mut i = 1; + while i < 63 { + array[i] = buffer.decode::(); + i += 1; + }; + array } } +impl AbiDecode for [T; 64] +where + T: AbiDecode, +{ + fn abi_decode(ref mut buffer: BufferReader) -> [T; 64] { + let first: T = buffer.decode::(); + let mut array = [first; 64]; + let mut i = 1; + while i < 64 { + array[i] = buffer.decode::(); + i += 1; + }; + array + } +} +// END ARRAY_DECODE impl AbiDecode for () { fn abi_decode(ref mut _buffer: BufferReader) -> () { @@ -3811,6 +5415,20 @@ where } } +fn to_slice(array: T) -> raw_slice { + let len = __size_of::(); + raw_slice::from_parts::(__addr_of(array), len) +} + +fn assert_eq(a: T, b: T) +where + T: Eq, +{ + if a != b { + __revert(0) + } +} + #[test] fn ok_abi_encoding() { // bool @@ -3891,6 +5509,13 @@ fn ok_abi_encoding() { assert_encoding([255u8; 3], [255u8; 3]); assert_encoding([255u8; 4], [255u8; 4]); assert_encoding([255u8; 5], [255u8; 5]); + + let array = abi_decode::<[u8; 1]>(to_slice([255u8])); + assert_eq(array[0], 255u8); + + let array = abi_decode::<[u8; 2]>(to_slice([255u8, 254u8])); + assert_eq(array[0], 255u8); + assert_eq(array[1], 254u8); } pub fn contract_call( diff --git a/sway-parse/src/attribute.rs b/sway-parse/src/attribute.rs index d6f683d06c0..84a174f3bf2 100644 --- a/sway-parse/src/attribute.rs +++ b/sway-parse/src/attribute.rs @@ -14,7 +14,7 @@ use sway_types::{Ident, Spanned}; impl Peek for DocComment { fn peek(peeker: Peeker<'_>) -> Option { - peeker.peek_doc_comment().ok().map(Clone::clone) + peeker.peek_doc_comment().ok().cloned() } } diff --git a/sway-parse/src/parse.rs b/sway-parse/src/parse.rs index 986f22bbf73..f96ffa0d132 100644 --- a/sway-parse/src/parse.rs +++ b/sway-parse/src/parse.rs @@ -125,7 +125,7 @@ where impl Peek for Ident { fn peek(peeker: Peeker<'_>) -> Option { - peeker.peek_ident().ok().map(Ident::clone) + peeker.peek_ident().ok().cloned() } } diff --git a/swayfmt/src/utils/map/byte_span.rs b/swayfmt/src/utils/map/byte_span.rs index 63ddf12b3f6..36578739dcf 100644 --- a/swayfmt/src/utils/map/byte_span.rs +++ b/swayfmt/src/utils/map/byte_span.rs @@ -233,7 +233,7 @@ mod tests { let second_span = ByteSpan { start: 2, end: 4 }; let third_span = ByteSpan { start: 4, end: 7 }; - let mut vec = vec![second_span.clone(), third_span.clone(), first_span.clone()]; + let mut vec = [second_span.clone(), third_span.clone(), first_span.clone()]; vec.sort(); assert_eq!(vec[0], first_span); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw index e892312cdfb..6ee9ff1d949 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/array_of_structs_caller/src/main.sw @@ -6,7 +6,7 @@ use std::hash::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x7fae96947a8cad59cc2a25239f9f80897955d4c1b10d31510681f15842b93265; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0x53de34b4a064de1a09fb9eb8ed407fd2c3b205c27ad5d8e0c63b28c752a09bbc; +const CONTRACT_ID = 0x54996ea6be619740d315438a413cf060d858fd548ffb75a54408fd8af1519ff8; fn main() -> u64 { let addr = abi(TestContract, CONTRACT_ID); diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw index f999d23e8ac..30f2c556ac8 100644 --- a/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw +++ b/test/src/e2e_vm_tests/test_programs/should_pass/require_contract_deployment/call_contract_with_type_aliases/src/main.sw @@ -5,7 +5,7 @@ use contract_with_type_aliases_abi::*; #[cfg(experimental_new_encoding = false)] const CONTRACT_ID = 0x9d76ecbf446c30ef659efd1157d67d156de02b1e6c2ac2f9c744125571efa229; #[cfg(experimental_new_encoding = true)] -const CONTRACT_ID = 0xdf7ff45bea6a49aa2b6ba9f12eac13dafa349b9c57cd8f7d4892bb0ebcc3782a; +const CONTRACT_ID = 0x02ab63e5c022d26c890c2adff800623b10a09612d6da902c12afa11705b9c5cd; fn main() { let caller = abi(MyContract, CONTRACT_ID);