Unverified Commit 1e312d1e authored by Hero Bird's avatar Hero Bird Committed by GitHub

Make ink! lang use ink_core::storage2 module (#422)

* [abi] create new layout trait and structures

* [abi] remove unused import

* [abi] add missing license header

* [abi] fix clippy warning

* [primitives] add KeyPtr to ink_primitives

* [core] use KeyPtr through ink_primitives and add ExtKeyPtr trait

* [abi] use KeyPtr of ink_primitives

* [abi] make EnumLayout use StructLayout

* [abi] implement custom serde::Serialize for LayoutKey

* [abi] implement IntoCompact for layout2 module types

* [abi] add doc comment

* [abi] apply rustfmt

* [abi] add unit test for LayoutKey serialization

* [abi] rename ArrayLayout::array -> new

* [abi] add dispatch_key field to enum layout

* [abi] derive From for all Layout variants

* [abi] add unit tests for the new layout traits and data structures

* [abi] add experimental CellLayout

* [abi] make tests work again for layout2

* [abi] use specialized serializer function for LayoutKey

* [abi] refactor UnboundedLayout

* [abi] add unit test for UnboundedLayout

* [abi] apply rustfmt

* [core/derive] slightly refactor code

* [abi] simplify enum test

* [primitives] derive Debug, Copy and Clone for KeyPtr

* [abi] simplify CellLayout::new

* [abi] fix calling incorrect constructor for LayoutKey

* [abi] move layout2 module file into directory

* [core] add StorageLayout trait to storage2 module

* [abi_derive, core_derive] remove unnecessary extern crate proc_macro

* [core] imply ink-generate-abi feature by std feature

* [core] derive Metadata for env types for std feature

* [core] add Key, Hash, AccountId and String StorageLayout impls

* [core/derive] add initial structure for StorageLayout derive

* [core] add StorageLayout impls for some more prelude types

* [core] fix Box<T> impl for StorageLayout trait

* [core] implement StorageLayout for storage2::{Memory, Pack, LazyArray}

* [core] fix StorageLayout impl for LazyArray

* [core] implement StorageLayout for LazyIndexMap

* [abi] add HashLayout

* [abi] rewrite UnboundedLayout test to HashLayout test

* [abi] remove unbounded layout

* [abi, core] apply rustfmt

* [core] add initial skeleton for StorageLayout tests

* [core] add StorageLayout impls for Lazy, LazyCell and LazyHashMap

* [core] add StorageLayout impls for Option and Result

* [core] add LayoutCryptoHasher trait

* [core] fix StorageLayout impl for LazyHashMap

* [core] apply rustfmt

* [core] add StorageLayout impl for storage2::Vec

* [core] add StorageLayout for storage2::SmallVec

* [core] implement StorageLayout for storage2::Stash

* [core] implement StorageLayout for storage BitStash, Bitvec and HashMap

* [core] improve StorageLayout impl for storage2::Vec

* [core] apply rustfmt

* [abi] fix clippy warning

* [core] add StorageLayout impl for storage2::alloc::Box

* [core] add StorageLayout impl for DynamicAllocator

* [core/derive] impl StorageLayout derive for struct items

* [core/derive] make StorageLayout derive work for enum items

* [core/derive] fix expansion for nested enums

* [core/derive] fix a bug with nested enums

* [core/derive] add unit test for MixedEnum

* [core/derive] apply rustfmt

* [lang] add revision 2 module

* [core] remove generic T: EnvTypes param from Dispatch trait

* [lang] remove unnecessary import

* [lang] remove unnecessary generic parameter

* [lang/macro] generate codegen for the new v2 traits

* [core] re-export SpreadLayout and PackedLayout macros from within ink_core

* [lang] further adjustments to make ink_lang_macro work with storage2

* [lang, core] apply rustfmt

* [lang] fix clippy warning

* [lang] fix some bugs with constructors without inputs

* [examples] adjust the Flipper example contract for the changes

* [lang] remove codegen for testing ink! contracts

No longer needed.

* [lang] remove test-env crate feature

* [lang] minor improvements to EnvAccess utility type

* [examples] remove unused import for Flipper

* [examples] remove test-env crate feature for Flipper

* [lang] remove unused IdentType::span method

* [examples] Flipper: adjust contract for ink_lang changes

* [examples] adjust Erc20 for the ink_lang changes

* [examples] fix some indentation in Cargo.toml

* [examples] adjust DNS contract for ink_lang changes

* [examples] adjust ERC721 for ink_lang changes

There is still a bug that we need to fix in ink_core.

* [example] adjust lib.rs of ERC721 to ink_lang changes

* [examples] adjust Delegator example contract for ink_lang changes

* [lang_macro] generate SpreadLayout and PackedLayout impls for cross-calling wrappers

* [core] release storage2::Stash::entries() iterator for non-testing API

* [core] add SpreadLayout and PackedLayout impls for () type

* [examples] convert multisig contract example to new ink_lang

* [examples] fix incrementer Cargo.toml indentations

* [examples] adjust runtime-storage example contract for ink_lang changes

* [core] apply rustfmt

* [lang] generate correct attributes for messages

* [examples] make use of derive(Default) for DNS example

* [lang_macro] improve some ink! error messages

* [lang_macro] update all compile tests

* [examples] multisig: ignore doc test

This needs serious fixing later! @athei

* [lang] remove old ink_lang abstractions

* [lang] remove no longer needed ink_lang modules

* [lang_macro] add compile test for derive on storage struct

* [examples] ignore failing doc test

* [examples] actually ignore the failing doc-test for multi-sig

* [lang] move v2 module back to origin

* [lang_macro] adjust codegen for new dispatch module structure of ink_lang

* [lang_macro] no longer impl ink_core::{Flush, AllocateUsing} for ink! dependencies

* [lang_macro] use root namespaces in codegen everywhere

* [lang] apply rustfmt

* [lang_macro] use only root namespaces in codegen (forgot some)

* [lang] remove nightly Rust feature usage

* [core] re-export StorageLayout from ink_core::storage2::traits

* [lang,abi] adjust ink! metadata generation codegen to new layout

* [lang] use root namespaces in codegen

* [examples] apply rustfmt

* [lang] update cross-calling codegen for new storage layout

* [examples] update Delegator example contract

* [examples] apply rustfmt

* [abi] remove StorageLayout trait from ink_abi crate

* [examples] apply rustfmt

* [examples] fix clippy warning

* [examples] fix multisig_plain contract

* [examples] apply rustfmt

* [examples] fix clippy warning

* [examples] remove commented out code from multisig_plain example

* [lang] refactor codegen for contract storage struct

* [lang] fix unused import warning

* [lang] eliminate CrossCallingConflictCfg

* [lang] do not generate normal storage struct as dependency

* [lang] re-introduce cross calling conflict cfg codegen

* [lang/macro] refactor codegen for cross-calling

* [lang] add new traits for Event connectors

* [lang/macro] use connectors API for event codegen

* [lang/macro] apply rustfmt

* [lang/macro] remove out-of-ink-module export

* [abi] fix selector encoding

* [lang/macro] fix unused warning

* [examples] adjust example smart contracts for recents ink_lang_macro changes

* [abi] fix unit test for selector

* [chores] update README ink! example

* [alloc] silence warnings of unused unsafe for core::intrinsics::abort

* [examples] apply rustfmt

* [lang/macro] fix codegen for `cargo test`

* [*] replace ink-generate-abi crate feature everywhere with std

* [examples] fix Cargo.toml for generating metadata

* [examples] move flipper/src/lib.rs one up

* [examples] move lib.rs to root folder

* [examples] fix Cargo.toml of ERC721

* [examples] apply rustfmt to ERC20

* [examples] apply rustfmt to ERC721

* [examples] apply rustfmt to all examples

* [abi] remove unused serialize_selector function

* [examples] fix bug that DNS example still used type-metadata crate

* [example] fix bug in multisig_plain example
parent 5a7b7e5e
Pipeline #96624 passed with stages
in 8 minutes and 16 seconds
......@@ -94,32 +94,34 @@ mod flipper {
#[ink(storage)]
struct Flipper {
/// The single `bool` value.
value: storage::Value<bool>,
value: bool,
}
impl Flipper {
/// Instantiates a new Flipper contract and initializes `value` to `init_value`.
#[ink(constructor)]
fn new(&mut self, init_value: bool) {
self.value.set(init_value);
fn new(init_value: bool) -> Self {
Self {
value: init_value,
}
}
/// Instantiates a new Flipper contract and initializes `value` to `false` by default.
#[ink(constructor)]
fn default(&mut self) {
self.new(false)
fn default() -> Self {
Self::new(false)
}
/// Flips `value` from `true` to `false` or vice versa.
#[ink(message)]
fn flip(&mut self) {
*self.value = !self.get();
self.value = !self.value;
}
/// Returns the current state of `value`.
#[ink(message)]
fn get(&self) -> bool {
*self.value
self.value
}
}
......
......@@ -16,7 +16,6 @@
#[cfg(not(feature = "std"))]
extern crate alloc;
extern crate proc_macro;
#[macro_use]
mod error;
......
This diff is collapsed.
This diff is collapsed.
......@@ -21,10 +21,9 @@ extern crate alloc;
mod tests;
mod layout;
pub mod layout2;
mod specs;
#[cfg(feature = "derive")]
pub use ink_abi_derive::HasLayout;
mod utils;
pub use self::{
layout::{
......@@ -53,8 +52,9 @@ pub use self::{
TypeSpec,
},
};
use core::fmt::Write as _;
#[cfg(feature = "derive")]
pub use ink_abi_derive::HasLayout;
use scale_info::{
form::CompactForm,
IntoCompact as _,
......@@ -70,7 +70,7 @@ use serde::{
pub struct InkProject {
registry: Registry,
#[serde(rename = "storage")]
layout: StorageLayout<CompactForm>,
layout: layout2::Layout<CompactForm>,
#[serde(rename = "contract")]
spec: ContractSpec<CompactForm>,
}
......@@ -79,7 +79,7 @@ impl InkProject {
/// Creates a new ink! project.
pub fn new<L, S>(layout: L, spec: S) -> Self
where
L: Into<StorageLayout>,
L: Into<layout2::Layout>,
S: Into<ContractSpec>,
{
let mut registry = Registry::new();
......
......@@ -14,6 +14,7 @@
#![allow(clippy::new_ret_no_self)]
use crate::utils::serialize_as_byte_str;
#[cfg(not(feature = "std"))]
use alloc::{
format,
......@@ -21,7 +22,6 @@ use alloc::{
vec::Vec,
};
use core::marker::PhantomData;
use scale_info::{
form::{
CompactForm,
......@@ -32,10 +32,7 @@ use scale_info::{
Metadata,
Registry,
};
use serde::{
Serialize,
Serializer,
};
use serde::Serialize;
/// Describes a contract.
#[derive(Debug, PartialEq, Eq, Serialize)]
......@@ -194,7 +191,7 @@ pub struct ConstructorSpec<F: Form = MetaForm> {
/// The name of the message.
name: F::String,
/// The selector hash of the message.
#[serde(serialize_with = "serialize_selector")]
#[serde(serialize_with = "serialize_as_byte_str")]
selector: [u8; 4],
/// The parameters of the deploy handler.
args: Vec<MessageParamSpec<F>>,
......@@ -300,7 +297,7 @@ pub struct MessageSpec<F: Form = MetaForm> {
/// The name of the message.
name: F::String,
/// The selector hash of the message.
#[serde(serialize_with = "serialize_selector")]
#[serde(serialize_with = "serialize_as_byte_str")]
selector: [u8; 4],
/// If the message is allowed to mutate the contract state.
mutates: bool,
......@@ -827,11 +824,3 @@ impl MessageParamSpecBuilder {
self.spec
}
}
#[allow(clippy::trivially_copy_pass_by_ref)]
fn serialize_selector<S>(s: &[u8; 4], serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
super::hex_encode(&s[..], serializer)
}
// Copyright 2018-2020 Parity Technologies (UK) Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use core::fmt::Write;
/// Serializes the given bytes as byte string.
pub fn serialize_as_byte_str<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if bytes.is_empty() {
// Return empty string without prepended `0x`.
return serializer.serialize_str("")
}
let mut hex = String::with_capacity(bytes.len() * 2 + 2);
write!(hex, "0x").expect("failed writing to string");
for byte in bytes {
write!(hex, "{:02x}", byte).expect("failed writing to string");
}
serializer.serialize_str(&hex)
}
......@@ -47,11 +47,13 @@ itertools = "0.9"
[features]
default = ["std"]
std = [
"ink_abi",
"ink_abi/std",
"ink_alloc/std",
"ink_prelude/std",
"ink_primitives/std",
"scale/std",
"scale-info",
"scale-info/std",
"rand",
"rand/std",
......@@ -61,8 +63,3 @@ std = [
"sha3",
"blake2",
]
ink-generate-abi = [
"ink_abi",
"scale-info",
"std",
]
......@@ -18,5 +18,6 @@ synstructure = "0.12"
[dev-dependencies]
ink_primitives = { version = "2.1.0", path = "../../primitives" }
ink_abi = { version = "2.1.0", path = "../../abi" }
ink_core = { version = "2.1.0", path = ".." }
trybuild = "1.0.24"
......@@ -12,12 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
extern crate proc_macro;
mod allocate_using;
mod flush;
mod packed_layout;
mod spread_layout;
mod storage_layout;
#[cfg(test)]
mod tests;
......@@ -27,8 +26,10 @@ use self::{
flush::flush_derive,
packed_layout::packed_layout_derive,
spread_layout::spread_layout_derive,
storage_layout::storage_layout_derive,
};
synstructure::decl_derive!([Flush] => flush_derive);
synstructure::decl_derive!([AllocateUsing] => allocate_using_derive);
synstructure::decl_derive!([SpreadLayout] => spread_layout_derive);
synstructure::decl_derive!([PackedLayout] => packed_layout_derive);
synstructure::decl_derive!([StorageLayout] => storage_layout_derive);
......@@ -199,13 +199,13 @@ fn spread_layout_enum_derive(s: &synstructure::Structure) -> TokenStream2 {
pub fn spread_layout_derive(mut s: synstructure::Structure) -> TokenStream2 {
s.bind_with(|_| synstructure::BindStyle::Move);
s.add_bounds(synstructure::AddBounds::Generics);
let is_enum = s.variants().len() >= 2;
if is_enum {
spread_layout_enum_derive(&s)
} else if s.variants().len() == 1 {
spread_layout_struct_derive(&s)
} else {
panic!("empty enums are not supported");
match s.ast().data {
syn::Data::Struct(_) => spread_layout_struct_derive(&s),
syn::Data::Enum(_) => spread_layout_enum_derive(&s),
_ => {
panic!(
"cannot derive `SpreadLayout` or `PackedLayout` for Rust `union` items"
)
}
}
}
// Copyright 2018-2020 Parity Technologies (UK) Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
fn field_layout<'a>(
variant: &'a synstructure::VariantInfo,
) -> impl Iterator<Item = TokenStream2> + 'a {
variant.ast().fields.iter().map(|field| {
let ident = match field.ident.as_ref() {
Some(ident) => {
let ident_str = ident.to_string();
quote! { Some(#ident_str) }
}
None => quote! { None },
};
let ty = &field.ty;
quote! {
::ink_abi::layout2::FieldLayout::new(
#ident,
<#ty as ::ink_core::storage2::traits::StorageLayout>::layout(__key_ptr),
)
}
})
}
fn storage_layout_struct(s: &synstructure::Structure) -> TokenStream2 {
assert!(
matches!(s.ast().data, syn::Data::Struct(_)),
"s must be a struct item"
);
assert!(
s.variants().len() == 1,
"structs must have at most one variant"
);
let variant: &synstructure::VariantInfo = &s.variants()[0];
let field_layouts = field_layout(variant);
s.gen_impl(quote! {
gen impl ::ink_core::storage2::traits::StorageLayout for @Self {
fn layout(__key_ptr: &mut ::ink_core::storage2::traits::KeyPtr) -> ::ink_abi::layout2::Layout {
::ink_abi::layout2::Layout::Struct(
::ink_abi::layout2::StructLayout::new(vec![
#(#field_layouts ,)*
])
)
}
}
})
}
fn storage_layout_enum(s: &synstructure::Structure) -> TokenStream2 {
assert!(
matches!(s.ast().data, syn::Data::Enum(_)),
"s must be an enum item"
);
let variant_layouts = s.variants().iter().enumerate().map(|(n, variant)| {
let discriminant = variant
.ast()
.discriminant
.as_ref()
.map(|(_, expr)| quote! { #expr })
.unwrap_or_else(|| quote! { #n });
let field_layouts = field_layout(variant);
quote! {
{
let mut __variant_key_ptr = __key_ptr.clone();
let mut __key_ptr = &mut __variant_key_ptr;
(
::ink_abi::layout2::Discriminant::from(#discriminant),
::ink_abi::layout2::StructLayout::new(vec![
#(#field_layouts ,)*
]),
)
}
}
});
s.gen_impl(quote! {
gen impl ::ink_core::storage2::traits::StorageLayout for @Self {
fn layout(__key_ptr: &mut ::ink_core::storage2::traits::KeyPtr) -> ::ink_abi::layout2::Layout {
let dispatch_key = __key_ptr.advance_by(1);
::ink_abi::layout2::Layout::Enum(
::ink_abi::layout2::EnumLayout::new(
::ink_abi::layout2::LayoutKey::from(dispatch_key),
vec![
#(#variant_layouts ,)*
]
)
)
}
}
})
}
pub fn storage_layout_derive(mut s: synstructure::Structure) -> TokenStream2 {
s.bind_with(|_| synstructure::BindStyle::Move);
s.add_bounds(synstructure::AddBounds::Generics);
match s.ast().data {
syn::Data::Struct(_) => storage_layout_struct(&s),
syn::Data::Enum(_) => storage_layout_enum(&s),
_ => panic!("cannot derive `StorageLayout` for Rust `union` items"),
}
}
......@@ -14,3 +14,4 @@
mod packed_layout;
mod spread_layout;
mod storage_layout;
This diff is collapsed.
......@@ -24,31 +24,30 @@ use crate::storage::Flush;
use core::{
array::TryFromSliceError,
convert::TryFrom,
ops::{
Add,
AddAssign,
Div,
DivAssign,
Mul,
MulAssign,
Sub,
SubAssign,
},
};
use derive_more::From;
use ink_prelude::vec::Vec;
use scale::{
Decode,
Encode,
};
#[cfg(feature = "ink-generate-abi")]
use scale_info::Metadata;
use core::ops::{
Add,
AddAssign,
Div,
DivAssign,
Mul,
MulAssign,
Sub,
SubAssign,
};
use num_traits::{
Bounded,
One,
Zero,
};
use scale::{
Decode,
Encode,
};
#[cfg(feature = "std")]
use scale_info::Metadata;
/// Types that allow for simple arithmetic operations.
///
......@@ -180,7 +179,7 @@ where
/// The fundamental types of the default configuration.
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "ink-generate-abi", derive(Metadata))]
#[cfg_attr(feature = "std", derive(Metadata))]
pub enum DefaultEnvTypes {}
impl EnvTypes for DefaultEnvTypes {
......@@ -254,7 +253,7 @@ impl scale::Decode for Call {
From,
Default,
)]
#[cfg_attr(feature = "ink-generate-abi", derive(Metadata))]
#[cfg_attr(feature = "std", derive(Metadata))]
pub struct AccountId([u8; 32]);
impl<'a> TryFrom<&'a [u8]> for AccountId {
......@@ -288,7 +287,7 @@ impl Flush for AccountId {}
From,
Default,
)]
#[cfg_attr(feature = "ink-generate-abi", derive(Metadata))]
#[cfg_attr(feature = "std", derive(Metadata))]
pub struct Hash([u8; 32]);
impl<'a> TryFrom<&'a [u8]> for Hash {
......
......@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#[cfg(feature = "ink-generate-abi")]
#[cfg(feature = "std")]
use scale_info::Metadata;
use super::*;
......@@ -28,7 +28,7 @@ use ink_primitives::Key;
///
/// Users are recommended to use the [`DynAlloc`](struct.DynAlloc.html)
/// for dynamic storage allocation purposes instead.
#[cfg_attr(feature = "ink-generate-abi", derive(Metadata))]
#[cfg_attr(feature = "std", derive(Metadata))]
pub struct BumpAlloc {
/// The key offset used for all allocations.
offset_key: Key,
......
......@@ -22,7 +22,7 @@ use crate::storage::{
Allocator,
Flush,
};
#[cfg(feature = "ink-generate-abi")]
#[cfg(feature = "std")]
use ink_abi::{
HasLayout,
LayoutField,
......@@ -30,7 +30,7 @@ use ink_abi::{
StorageLayout,
};
use ink_primitives::Key;
#[cfg(feature = "ink-generate-abi")]
#[cfg(feature = "std")]
use scale_info::Metadata;
/// Allocator for dynamic contract storage.
......@@ -41,7 +41,7 @@ use scale_info::Metadata;
/// at the same time. This is subject to change in the future if
/// experiments show that this is a bottle neck.
#[derive(Debug)]
#[cfg_attr(feature = "ink-generate-abi", derive(Metadata))]
#[cfg_attr(feature = "std", derive(Metadata))]
pub struct DynAlloc {
/// Bitmap indicating free cell slots.
free_cells: storage::BitVec,
......@@ -53,7 +53,7 @@ pub struct DynAlloc {
chunks_origin: Key,
}
#[cfg(feature = "ink-generate-abi")]
#[cfg(feature = "std")]
impl HasLayout for DynAlloc {
fn layout(&self) -> StorageLayout {
LayoutStruct::new(
......
......@@ -22,7 +22,7 @@ use crate::storage::{
cell::TypedCell,
Flush,
};
#[cfg(feature = "ink-generate-abi")]
#[cfg(feature = "std")]
use ink_abi::{
HasLayout,
LayoutRange,
......@@ -30,7 +30,7 @@ use ink_abi::{
};
use ink_prelude::boxed::Box;
use ink_primitives::Key;
#[cfg(feature = "ink-generate-abi")]
#[cfg(feature = "std")]
use scale_info::{
build::Fields,
Metadata,
......@@ -57,7 +57,7 @@ pub struct SyncCell<T> {
cache: Cache<T>,
}
#[cfg(feature = "ink-generate-abi")]
#[cfg(feature = "std")]
impl<T> TypeInfo for SyncCell<T> {
fn type_info() -> Type {
Type::builder()
......@@ -306,7 +306,7 @@ impl<T> Cache<T> {
}
}
#[cfg(feature = "ink-generate-abi")]
#[cfg(feature = "std")]
impl<T> HasLayout for SyncCell<T>
where
T: Metadata,
......
......@@ -21,14 +21,14 @@ use crate::storage::{
chunk::TypedChunk,
Flush,
};
#[cfg(feature = "ink-generate-abi")]
#[cfg(feature = "std")]
use ink_abi::{
HasLayout,
LayoutRange,
StorageLayout,
};
use ink_primitives::Key;
#[cfg(feature = "ink-generate-abi")]
#[cfg(feature = "std")]
use scale_info::{
build::Fields,
Metadata,
......@@ -57,7 +57,7 @@ pub struct SyncChunk<T> {
cache: CacheGuard<T>,
}
#[cfg(feature = "ink-generate-abi")]
#[cfg(feature = "std")]
impl<T> TypeInfo for SyncChunk<T> {
fn type_info() -> Type {
Type::builder()
......@@ -102,7 +102,7 @@ impl<T> scale::Decode for SyncChunk<T> {
}
}
#[cfg(feature = "ink-generate-abi")]
#[cfg(feature = "std")]
impl<T> HasLayout for SyncChunk<T>
where
T: Metadata,
......
......@@ -31,7 +31,7 @@
//! The getters and setters exposed by this module take care of mapping
//! to the correct group index.
#[cfg(feature = "ink-generate-abi")]
#[cfg(feature = "std")]
use ink_abi::{
HasLayout,
LayoutField,
......@@ -43,7 +43,7 @@ use scale::{
Decode,
Encode,
};
#[cfg(feature = "ink-generate-abi")]
#[cfg(feature = "std")]
use scale_info::Metadata;
use crate::storage::{
......@@ -57,11 +57,11 @@ use crate::storage::{
const COUNT: u32 = 2;
#[derive(Debug, Encode, Decode)]
#[cfg_attr(feature = "ink-generate-abi", derive(Metadata))]
#[cfg_attr(feature = "std", derive(Metadata))]
pub struct Group<T>([Option<T>; COUNT as usize]);