Repository: paritytech/ink
Pull request #926 (2021-09-19 08:22:56)

Improve SpreadLayout and StorageLayout derive macro hygiene
PR and side-work resulting from my work on https://github.com/paritytech/ink/pull/665/commits.

codecov-commenter: # [Codecov](https://codecov.io/gh/paritytech/ink/pull/926?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech) Report
> Merging [#926](https://codecov.io/gh/paritytech/ink/pull/926?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech) (2672dd2) into [master](https://codecov.io/gh/paritytech/ink/commit/4155ebe28a29674299a687ed1bab660727ac738b?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech) (4155ebe) will **increase** coverage by `0.24%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/paritytech/ink/pull/926/graphs/tree.svg?width=650&height=150&src=pr&token=tYyVaCZb7o&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech)](https://codecov.io/gh/paritytech/ink/pull/926?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech)

```diff
@@            Coverage Diff             @@
##           master     #926      +/-   ##
==========================================
+ Coverage   84.24%   84.49%   +0.24%     
==========================================
  Files         172      158      -14     
  Lines        7945     6551    -1394     
==========================================
- Hits         6693     5535    -1158     
+ Misses       1252     1016     -236     
```


| [Impacted Files](https://codecov.io/gh/paritytech/ink/pull/926?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech) | Coverage Δ | |
|---|---|---|
| [crates/storage/derive/src/spread\_layout.rs](https://codecov.io/gh/paritytech/ink/pull/926/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech#diff-Y3JhdGVzL3N0b3JhZ2UvZGVyaXZlL3NyYy9zcHJlYWRfbGF5b3V0LnJz) | `98.48% <ø> (ø)` | |
| [crates/storage/derive/src/storage\_layout.rs](https://codecov.io/gh/paritytech/ink/pull/926/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech#diff-Y3JhdGVzL3N0b3JhZ2UvZGVyaXZlL3NyYy9zdG9yYWdlX2xheW91dC5ycw==) | `94.11% <100.00%> (ø)` | |
| [crates/lang/ir/src/ir/item\_impl/mod.rs](https://codecov.io/gh/paritytech/ink/pull/926/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech#diff-Y3JhdGVzL2xhbmcvaXIvc3JjL2lyL2l0ZW1faW1wbC9tb2QucnM=) | `73.58% <0.00%> (-17.80%)` | :arrow_down: |
| [crates/lang/codegen/src/generator/metadata.rs](https://codecov.io/gh/paritytech/ink/pull/926/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech#diff-Y3JhdGVzL2xhbmcvY29kZWdlbi9zcmMvZ2VuZXJhdG9yL21ldGFkYXRhLnJz) | `90.90% <0.00%> (-6.70%)` | :arrow_down: |
| [crates/lang/ir/src/ir/item\_impl/impl\_item.rs](https://codecov.io/gh/paritytech/ink/pull/926/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech#diff-Y3JhdGVzL2xhbmcvaXIvc3JjL2lyL2l0ZW1faW1wbC9pbXBsX2l0ZW0ucnM=) | `51.35% <0.00%> (-6.10%)` | :arrow_down: |
| [crates/lang/ir/src/ir/idents\_lint.rs](https://codecov.io/gh/paritytech/ink/pull/926/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech#diff-Y3JhdGVzL2xhbmcvaXIvc3JjL2lyL2lkZW50c19saW50LnJz) | `68.42% <0.00%> (-3.01%)` | :arrow_down: |
| [crates/lang/ir/src/ir/config.rs](https://codecov.io/gh/paritytech/ink/pull/926/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech#diff-Y3JhdGVzL2xhbmcvaXIvc3JjL2lyL2NvbmZpZy5ycw==) | `88.88% <0.00%> (-2.61%)` | :arrow_down: |
| [crates/lang/ir/src/ir/trait\_def.rs](https://codecov.io/gh/paritytech/ink/pull/926/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech#diff-Y3JhdGVzL2xhbmcvaXIvc3JjL2lyL3RyYWl0X2RlZi5ycw==) | `92.89% <0.00%> (-0.21%)` | :arrow_down: |
| [crates/metadata/src/lib.rs](https://codecov.io/gh/paritytech/ink/pull/926/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech#diff-Y3JhdGVzL21ldGFkYXRhL3NyYy9saWIucnM=) | `0.00% <0.00%> (ø)` | |
| [crates/primitives/src/key\_ptr.rs](https://codecov.io/gh/paritytech/ink/pull/926/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech#diff-Y3JhdGVzL3ByaW1pdGl2ZXMvc3JjL2tleV9wdHIucnM=) | `100.00% <0.00%> (ø)` | |
| ... and [34 more](https://codecov.io/gh/paritytech/ink/pull/926/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/paritytech/ink/pull/926?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/paritytech/ink/pull/926?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech). Last update [4155ebe...2672dd2](https://codecov.io/gh/paritytech/ink/pull/926?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=paritytech).


Patch:
diff --git a/.config/cargo_spellcheck.dic b/.config/cargo_spellcheck.dic
index 63a06223f3..8ad567d41e 100644
--- a/.config/cargo_spellcheck.dic
+++ b/.config/cargo_spellcheck.dic
@@ -1,4 +1,4 @@
-90
+100
 
 ABI
 AST
@@ -91,3 +91,4 @@ runtime/S
 struct/S
 vec/S
 vector/S
+wildcard/S
diff --git a/README.md b/README.md
index d1bb0b6cad..d48f1a8b29 100644
--- a/README.md
+++ b/README.md
@@ -220,8 +220,8 @@ In a module annotated with `#[ink::contract]` these attributes are available:
 | `#[ink(message)]` | Applicable to methods. | Flags a method for the ink! storage struct as message making it available to the API for calling the contract. |
 | `#[ink(constructor)]` | Applicable to method. | Flags a method for the ink! storage struct as constructor making it available to the API for instantiating the contract. |
 | `#[ink(payable)]` | Applicable to ink! messages. | Allows receiving value as part of the call of the ink! message. ink! constructors are implicitly payable. |
-| `#[ink(selector = "..")]` | Applicable to ink! messages and ink! constructors. | Specifies a concrete dispatch selector for the flagged entity. This allows a contract author to precisely control the selectors of their APIs making it possible to rename their API without breakage. |
-| `#[ink(namespace = "..")]` | Applicable to ink! trait implementation blocks. | Changes the resulting selectors of all the ink! messages and ink! constructors within the trait implementation. Allows to disambiguate between trait implementations with overlapping message or constructor names. Use only with great care and consideration! |
+| `#[ink(selector = S:u32)]` | Applicable to ink! messages and ink! constructors. | Specifies a concrete dispatch selector for the flagged entity. This allows a contract author to precisely control the selectors of their APIs making it possible to rename their API without breakage. |
+| `#[ink(namespace = N:string)]` | Applicable to ink! trait implementation blocks. | Changes the resulting selectors of all the ink! messages and ink! constructors within the trait implementation. Allows to disambiguate between trait implementations with overlapping message or constructor names. Use only with great care and consideration! |
 | `#[ink(impl)]` | Applicable to ink! implementation blocks. | Tells the ink! codegen that some implementation block shall be granted access to ink! internals even without it containing any ink! messages or ink! constructors. |
 
 See [here](https://paritytech.github.io/ink/ink_lang/attr.contract.html) for a more detailed description of those and also for details on the `#[ink::contract]` macro.
diff --git a/RELEASES.md b/RELEASES.md
index af27e82182..bbfe067239 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,15 @@
+# Version 3.0-rc6 (UNRELEASED)
+
+This is the 6th release candidate for ink! 3.0.
+
+## Changed
+
+- Message and constructor selectors no longer take their inputs as string but as `u32` decodable integer. For example:
+
+    - It is no longer possible to specify a selector as `#[ink(selector = "0xC0DECAFE")]`.
+    - The newly allowed formats are `#[ink(selector = 0xC0DECAFE)]` and `#[ink(selector = 42)]`.
+    - Smart contract authors are required to update their smart contracts for this change.
+
 # Version 3.0-rc5 (2021-09-08)
 
 This is the 5th release candidate for ink! 3.0.
diff --git a/crates/lang/codegen/Cargo.toml b/crates/lang/codegen/Cargo.toml
index c0fea9e7c8..e0f06a1ab7 100644
--- a/crates/lang/codegen/Cargo.toml
+++ b/crates/lang/codegen/Cargo.toml
@@ -25,7 +25,6 @@ proc-macro2 = "1.0"
 derive_more = { version = "0.99", default-features = false, features = ["from"] }
 itertools = "0.10"
 either = { version = "1.5", default-features = false }
-regex = "1.3"
 blake2 = "0.9"
 heck = "0.3.1"
 scale = { package = "parity-scale-codec", version = "2.1", default-features = false, features = ["derive", "full"] }
diff --git a/crates/lang/ir/Cargo.toml b/crates/lang/ir/Cargo.toml
index 79757578e4..99c4a0de68 100644
--- a/crates/lang/ir/Cargo.toml
+++ b/crates/lang/ir/Cargo.toml
@@ -23,7 +23,6 @@ syn = { version = "1.0", features = ["parsing", "full", "visit", "extra-traits"]
 proc-macro2 = "1.0"
 itertools = { version = "0.10", default-features = false }
 either = { version = "1.5", default-features = false }
-regex = "1.3"
 blake2 = "0.9"
 
 [features]
diff --git a/crates/lang/ir/src/ir/attrs.rs b/crates/lang/ir/src/ir/attrs.rs
index 7f384c8eaf..6f50373d8f 100644
--- a/crates/lang/ir/src/ir/attrs.rs
+++ b/crates/lang/ir/src/ir/attrs.rs
@@ -28,7 +28,6 @@ use proc_macro2::{
     Ident,
     Span,
 };
-use regex::Regex;
 use std::collections::HashMap;
 use syn::spanned::Spanned;
 
@@ -98,12 +97,12 @@ impl Attrs for syn::Item {
 ///
 /// An attribute with a parameterized flag:
 /// ```no_compile
-/// #[ink(selector = "0xDEADBEEF")]
+/// #[ink(selector = 0xDEADBEEF)]
 /// ```
 ///
 /// An attribute with multiple flags:
 /// ```no_compile
-/// #[ink(message, payable, selector = "0xDEADBEEF")]
+/// #[ink(message, payable, selector = 0xDEADBEEF)]
 /// ```
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct InkAttribute {
@@ -314,7 +313,7 @@ pub enum AttributeArgKind {
     Constructor,
     /// `#[ink(payable)]`
     Payable,
-    /// `#[ink(selector = "0xDEADBEEF")]`
+    /// `#[ink(selector = 0xDEADBEEF)]`
     Selector,
     /// `#[ink(extension = N: u32)]`
     Extension,
@@ -367,7 +366,7 @@ pub enum AttributeArg {
     /// Applied on ink! constructors or messages in order to specify that they
     /// can receive funds from callers.
     Payable,
-    /// `#[ink(selector = "0xDEADBEEF")]`
+    /// `#[ink(selector = 0xDEADBEEF)]`
     ///
     /// Applied on ink! constructors or messages to manually control their
     /// selectors.
@@ -732,19 +731,6 @@ impl InkAttribute {
     }
 }
 
-/// Returns an error to notify about non-hex digits at a position.
-fn err_non_hex(meta: &syn::Meta, pos: usize) -> syn::Error {
-    format_err_spanned!(meta, "encountered non-hex digit at position {}", pos)
-}
-
-/// Returns an error to notify about an invalid ink! selector.
-fn invalid_selector_err_regex(meta: &syn::Meta) -> syn::Error {
-    format_err_spanned!(
-        meta,
-        "invalid selector - a selector must consist of four bytes in hex (e.g. `selector = \"0xCAFEBABE\"`)"
-    )
-}
-
 impl TryFrom<syn::NestedMeta> for AttributeFrag {
     type Error = syn::Error;
 
@@ -754,46 +740,28 @@ impl TryFrom<syn::NestedMeta> for AttributeFrag {
                 match &meta {
                     syn::Meta::NameValue(name_value) => {
                         if name_value.path.is_ident("selector") {
-                            if let syn::Lit::Str(lit_str) = &name_value.lit {
-                                let regex = Regex::new(r"0x([\da-fA-F]{2})([\da-fA-F]{2})([\da-fA-F]{2})([\da-fA-F]{2})")
-                                    .map_err(|_| {
-                                    invalid_selector_err_regex(&meta)
-                                })?;
-                                let str = lit_str.value();
-                                let cap =
-                                    regex.captures(&str).ok_or_else(|| {
-                                        invalid_selector_err_regex(&meta)
+                            if let syn::Lit::Int(lit_int) = &name_value.lit {
+                                let selector_u32 = lit_int.base10_parse::<u32>()
+                                    .map_err(|error| {
+                                        format_err_spanned!(
+                                            lit_int,
+                                            "selector value out of range. selector must be a valid `u32` integer: {}",
+                                            error
+                                        )
                                     })?;
-                                if !regex.is_match(&str) {
-                                    return Err(invalid_selector_err_regex(
-                                        &meta,
-                                    ))
-                                }
-                                let len_digits = (str.as_bytes().len() - 2) / 2;
-                                if len_digits != 4 {
-                                    return Err(format_err!(
-                                            name_value,
-                                            "expected 4-digit hexcode for `selector` argument, found {} digits",
-                                            len_digits,
-                                        ))
-                                }
-                                let selector_bytes = [
-                                    u8::from_str_radix(&cap[1], 16)
-                                        .map_err(|_| err_non_hex(&meta, 0))?,
-                                    u8::from_str_radix(&cap[2], 16)
-                                        .map_err(|_| err_non_hex(&meta, 1))?,
-                                    u8::from_str_radix(&cap[3], 16)
-                                        .map_err(|_| err_non_hex(&meta, 2))?,
-                                    u8::from_str_radix(&cap[4], 16)
-                                        .map_err(|_| err_non_hex(&meta, 3))?,
-                                ];
+                                let selector = Selector::from_bytes(selector_u32.to_be_bytes());
                                 return Ok(AttributeFrag {
                                     ast: meta,
-                                    arg: AttributeArg::Selector(Selector::from_bytes(
-                                        selector_bytes,
-                                    )),
+                                    arg: AttributeArg::Selector(selector),
                                 })
                             }
+                            if let syn::Lit::Str(_) = &name_value.lit {
+                                return Err(format_err!(
+                                    name_value,
+                                    "#[ink(selector = ..)] attributes with string inputs are deprecated. \
+                                    use an integer instead, e.g. #[ink(selector = 1)] or #[ink(selector = 0xC0DECAFE)]."
+                                ))
+                            }
                             return Err(format_err!(name_value, "expecteded 4-digit hexcode for `selector` argument, e.g. #[ink(selector = 0xC0FEBABE]"))
                         }
                         if name_value.path.is_ident("namespace") {
@@ -1066,7 +1034,7 @@ mod tests {
     fn selector_works() {
         assert_attribute_try_from(
             syn::parse_quote! {
-                #[ink(selector = "0xDEADBEEF")]
+                #[ink(selector = 0xDEADBEEF)]
             },
             Ok(test::Attribute::Ink(vec![AttributeArg::Selector(
                 Selector::from_bytes([0xDE, 0xAD, 0xBE, 0xEF]),
@@ -1075,22 +1043,28 @@ mod tests {
     }
 
     #[test]
-    fn selector_non_hexcode() {
+    fn selector_negative_number() {
         assert_attribute_try_from(
             syn::parse_quote! {
-                #[ink(selector = "0xhelloworld")]
+                #[ink(selector = -1)]
             },
-            Err("invalid selector - a selector must consist of four bytes in hex (e.g. `selector = \"0xCAFEBABE\"`)"),
+            Err(
+                "selector value out of range. selector must be a valid `u32` integer: \
+                invalid digit found in string",
+            ),
         );
     }
 
     #[test]
-    fn selector_too_long() {
+    fn selector_out_of_range() {
         assert_attribute_try_from(
             syn::parse_quote! {
-                #[ink(selector = "0xDEADBEEFC0FEBABE")]
+                #[ink(selector = 0xFFFF_FFFF_FFFF_FFFF)]
             },
-            Err("expected 4-digit hexcode for `selector` argument, found 8 digits"),
+            Err(
+                "selector value out of range. \
+                selector must be a valid `u32` integer: number too large to fit in target type"
+            ),
         );
     }
 
@@ -1098,7 +1072,7 @@ mod tests {
     fn selector_invalid_type() {
         assert_attribute_try_from(
             syn::parse_quote! {
-                #[ink(selector = 42)]
+                #[ink(selector = true)]
             },
             Err("expecteded 4-digit hexcode for `selector` argument, e.g. #[ink(selector = 0xC0FEBABE]"),
         );
diff --git a/crates/lang/ir/src/ir/item_impl/callable.rs b/crates/lang/ir/src/ir/item_impl/callable.rs
index 88fee67b7b..1c48f900cb 100644
--- a/crates/lang/ir/src/ir/item_impl/callable.rs
+++ b/crates/lang/ir/src/ir/item_impl/callable.rs
@@ -208,7 +208,7 @@ pub trait Callable {
 ///
 /// ```no_compile
 /// impl MyStorage {
-///     #[ink(message, selector = "0xDEADBEEF")]
+///     #[ink(message, selector = 0xDEADBEEF)]
 ///     fn my_message(&self) {}
 /// }
 /// ```
@@ -611,7 +611,7 @@ mod tests {
                 impl MyTrait for MyStorage {}
             },
             syn::parse_quote! {
-                #[ink(message, selector = "0xDEADBEEF")]
+                #[ink(message, selector = 0xDEADBEEF)]
                 fn my_message(&self) {}
             },
             [0xDE, 0xAD, 0xBE, 0xEF],
diff --git a/crates/lang/ir/src/ir/item_impl/message.rs b/crates/lang/ir/src/ir/item_impl/message.rs
index 63eda9971f..90b44e9941 100644
--- a/crates/lang/ir/src/ir/item_impl/message.rs
+++ b/crates/lang/ir/src/ir/item_impl/message.rs
@@ -405,7 +405,7 @@ mod tests {
                 true,
                 syn::parse_quote! {
                     #[ink(message)]
-                    #[ink(selector = "0xDEADBEEF", payable)]
+                    #[ink(selector = 0xDEADBEEF, payable)]
                     pub fn my_message(&self) {}
                 },
             ),
diff --git a/crates/lang/ir/src/ir/item_mod.rs b/crates/lang/ir/src/ir/item_mod.rs
index e3effcd8a0..d6c1b31034 100644
--- a/crates/lang/ir/src/ir/item_mod.rs
+++ b/crates/lang/ir/src/ir/item_mod.rs
@@ -192,8 +192,8 @@ impl ItemMod {
                 format_err!(
                     second_span,
                     "encountered ink! {}s with overlapping selectors (= {:02X?})\n\
-                     hint: use #[ink(selector = \"0x...\")] on the callable or \
-                     #[ink(namespace = \"...\")] on the implementation block to \
+                     hint: use #[ink(selector = S:u32)] on the callable or \
+                     #[ink(namespace = N:string)] on the implementation block to \
                      disambiguate overlapping selectors.",
                     kind,
                     selector.as_bytes(),
@@ -713,20 +713,19 @@ mod tests {
                         #[ink(constructor)]
                         pub fn my_constructor() -> Self {}
 
-                        #[ink(message, selector = "0xDEADBEEF")]
+                        #[ink(message, selector = 0xDEADBEEF)]
                         pub fn my_message_1(&self) {}
                     }
 
                     impl MyStorage {
-                        #[ink(message, selector = "0xDEADBEEF")]
+                        #[ink(message, selector = 0xDEADBEEF)]
                         pub fn my_message_2(&self) {}
                     }
                 }
             },
             "encountered ink! messages with overlapping selectors (= [DE, AD, BE, EF])\n\
-                hint: use #[ink(selector = \"0x...\")] on the callable or \
-                #[ink(namespace = \"...\")] on the implementation block to \
-                disambiguate overlapping selectors.",
+            hint: use #[ink(selector = S:u32)] on the callable or #[ink(namespace = N:string)] \
+            on the implementation block to disambiguate overlapping selectors.",
         );
     }
 
@@ -739,7 +738,7 @@ mod tests {
                     pub struct MyStorage {}
 
                     impl MyStorage {
-                        #[ink(constructor, selector = "0xDEADBEEF")]
+                        #[ink(constructor, selector = 0xDEADBEEF)]
                         pub fn my_constructor_1() -> Self {}
 
                         #[ink(message)]
@@ -747,15 +746,14 @@ mod tests {
                     }
 
                     impl MyStorage {
-                        #[ink(constructor, selector = "0xDEADBEEF")]
+                        #[ink(constructor, selector = 0xDEADBEEF)]
                         pub fn my_constructor_2() -> Self {}
                     }
                 }
             },
             "encountered ink! constructors with overlapping selectors (= [DE, AD, BE, EF])\n\
-                hint: use #[ink(selector = \"0x...\")] on the callable or \
-                #[ink(namespace = \"...\")] on the implementation block to \
-                disambiguate overlapping selectors.",
+            hint: use #[ink(selector = S:u32)] on the callable or #[ink(namespace = N:string)] \
+            on the implementation block to disambiguate overlapping selectors.",
         );
     }
 
@@ -782,9 +780,8 @@ mod tests {
                 }
             },
             "encountered ink! messages with overlapping selectors (= [04, C4, 94, 46])\n\
-                hint: use #[ink(selector = \"0x...\")] on the callable or \
-                #[ink(namespace = \"...\")] on the implementation block to \
-                disambiguate overlapping selectors.",
+            hint: use #[ink(selector = S:u32)] on the callable or #[ink(namespace = N:string)] \
+            on the implementation block to disambiguate overlapping selectors.",
         );
     }
 
@@ -824,10 +821,10 @@ mod tests {
                     pub struct MyStorage {}
 
                     impl MyStorage {
-                        #[ink(constructor, selector = "0xDEADBEEF")]
+                        #[ink(constructor, selector = 0xDEADBEEF)]
                         pub fn my_constructor() -> Self {}
 
-                        #[ink(message, selector = "0xDEADBEEF")]
+                        #[ink(message, selector = 0xDEADBEEF)]
                         pub fn my_message(&self) {}
                     }
                 }
diff --git a/crates/lang/macro/src/lib.rs b/crates/lang/macro/src/lib.rs
index 9455616d7a..5633659ba5 100644
--- a/crates/lang/macro/src/lib.rs
+++ b/crates/lang/macro/src/lib.rs
@@ -356,20 +356,20 @@ use proc_macro::TokenStream;
 ///         # }
 ///     impl Flipper {
 ///         #[ink(constructor)]
-///         #[ink(selector = "0xDEADBEEF")] // Works on constructors as well.
+///         #[ink(selector = 0xDEADBEEF)] // Works on constructors as well.
 ///         pub fn new(initial_value: bool) -> Self {
 ///             Flipper { value: false }
 ///         }
 ///
 ///         # /// Flips the current value.
 ///         # #[ink(message)]
-///         # #[ink(selector = "0xCAFEBABE")] // You can either specify selector out-of-line.
+///         # #[ink(selector = 0xCAFEBABE)] // You can either specify selector out-of-line.
 ///         # pub fn flip(&mut self) {
 ///         #     self.value = !self.value;
 ///         # }
 ///         #
 ///         /// Returns the current value.
-///         #[ink(message, selector = "0xFEEDBEEF")] // ... or specify selector inline.
+///         #[ink(message, selector = 0xFEEDBEEF)] // ... or specify selector inline.
 ///         pub fn get(&self) -> bool {
 ///             self.value
 ///         }
diff --git a/crates/storage/derive/src/spread_layout.rs b/crates/storage/derive/src/spread_layout.rs
index d2796c78b5..b20f3e5b28 100644
--- a/crates/storage/derive/src/spread_layout.rs
+++ b/crates/storage/derive/src/spread_layout.rs
@@ -31,7 +31,7 @@ fn max_n(args: &[TokenStream2]) -> TokenStream2 {
         Some((head, rest)) => {
             let rest = max_n(rest);
             quote! {
-                [#head, #rest][(#head < #rest) as usize]
+                [#head, #rest][(#head < #rest) as ::core::primitive::usize]
             }
         }
         None => quote! { 0u64 },
@@ -103,8 +103,8 @@ fn spread_layout_struct_derive(s: &synstructure::Structure) -> TokenStream2 {
     s.gen_impl(quote! {
         gen impl ::ink_storage::traits::SpreadLayout for @Self {
             #[allow(unused_comparisons)]
-            const FOOTPRINT: u64 = #footprint_body;
-            const REQUIRES_DEEP_CLEAN_UP: bool = #requires_deep_clean_up_body;
+            const FOOTPRINT: ::core::primitive::u64 = #footprint_body;
+            const REQUIRES_DEEP_CLEAN_UP: ::core::primitive::bool = #requires_deep_clean_up_body;
 
             fn pull_spread(__key_ptr: &mut ::ink_storage::traits::KeyPtr) -> Self {
                 #pull_body
@@ -154,7 +154,7 @@ fn spread_layout_enum_derive(s: &synstructure::Structure) -> TokenStream2 {
         });
         quote! {
             #pat => {
-                { <u8 as ::ink_storage::traits::SpreadLayout>::push_spread(&#index, __key_ptr); }
+                { <::core::primitive::u8 as ::ink_storage::traits::SpreadLayout>::push_spread(&#index, __key_ptr); }
                 #(
                     { #fields }
                 )*
@@ -169,12 +169,12 @@ fn spread_layout_enum_derive(s: &synstructure::Structure) -> TokenStream2 {
     s.gen_impl(quote! {
         gen impl ::ink_storage::traits::SpreadLayout for @Self {
             #[allow(unused_comparisons)]
-            const FOOTPRINT: u64 = 1 + #footprint_body;
+            const FOOTPRINT: ::core::primitive::u64 = 1 + #footprint_body;
 
-            const REQUIRES_DEEP_CLEAN_UP: bool = #requires_deep_clean_up_body;
+            const REQUIRES_DEEP_CLEAN_UP: ::core::primitive::bool = #requires_deep_clean_up_body;
 
             fn pull_spread(__key_ptr: &mut ::ink_storage::traits::KeyPtr) -> Self {
-                match <u8 as ::ink_storage::traits::SpreadLayout>::pull_spread(__key_ptr) {
+                match <::core::primitive::u8 as ::ink_storage::traits::SpreadLayout>::pull_spread(__key_ptr) {
                     #pull_body
                     _ => unreachable!("encountered invalid enum discriminant"),
                 }
diff --git a/crates/storage/derive/src/storage_layout.rs b/crates/storage/derive/src/storage_layout.rs
index 13ee9f3c02..c215121855 100644
--- a/crates/storage/derive/src/storage_layout.rs
+++ b/crates/storage/derive/src/storage_layout.rs
@@ -22,9 +22,9 @@ fn field_layout<'a>(
         let ident = match field.ident.as_ref() {
             Some(ident) => {
                 let ident_str = ident.to_string();
-                quote! { Some(#ident_str) }
+                quote! { ::core::option::Option::Some(#ident_str) }
             }
-            None => quote! { None },
+            None => quote! { ::core::option::Option::None },
         };
         let ty = &field.ty;
         quote! {
diff --git a/examples/contract-transfer/lib.rs b/examples/contract-transfer/lib.rs
index f42e55a54a..5c9279ad32 100644
--- a/examples/contract-transfer/lib.rs
+++ b/examples/contract-transfer/lib.rs
@@ -69,7 +69,7 @@ pub mod give_me {
         ///
         /// The method needs to be annotated with `payable`; only then it is
         /// allowed to receive value as part of the call.
-        #[ink(message, payable, selector = "0xCAFEBABE")]
+        #[ink(message, payable, selector = 0xCAFEBABE)]
         pub fn was_it_ten(&self) {
             ink_env::debug_println!(
                 "received payment: {}",
diff --git a/examples/erc1155/lib.rs b/examples/erc1155/lib.rs
index 67ac9d2d55..d730346242 100644
--- a/examples/erc1155/lib.rs
+++ b/examples/erc1155/lib.rs
@@ -562,7 +562,7 @@ mod erc1155 {
     }
 
     impl super::Erc1155TokenReceiver for Contract {
-        #[ink(message, selector = "0xF23A6E61")]
+        #[ink(message, selector = 0xF23A6E61)]
         fn on_received(
             &mut self,
             _operator: AccountId,
@@ -582,7 +582,7 @@ mod erc1155 {
             unimplemented!("This smart contract does not accept token transfer.")
         }
 
-        #[ink(message, selector = "0xBC197C81")]
+        #[ink(message, selector = 0xBC197C81)]
         fn on_batch_received(
             &mut self,
             _operator: AccountId,


Test patch:
diff --git a/crates/lang/macro/tests/compile_tests.rs b/crates/lang/macro/tests/compile_tests.rs
index 93548b31a6..65b51b6cf4 100644
--- a/crates/lang/macro/tests/compile_tests.rs
+++ b/crates/lang/macro/tests/compile_tests.rs
@@ -50,6 +50,7 @@ fn compile_tests() {
     t.compile_fail("tests/ui/fail/M-03-message-returns-self.rs");
     t.compile_fail("tests/ui/fail/M-04-message-returns-non-codec.rs");
     t.compile_fail("tests/ui/fail/M-05-message-invalid-selector.rs");
+    t.compile_fail("tests/ui/fail/M-06-message-invalid-selector-type.rs");
     t.compile_fail("tests/ui/fail/M-10-method-unknown-ink-marker.rs");
 
     t.compile_fail("tests/ui/fail/S-01-missing-storage-struct.rs");
diff --git a/crates/lang/macro/tests/ui/fail/M-05-message-invalid-selector.rs b/crates/lang/macro/tests/ui/fail/M-05-message-invalid-selector.rs
index bb5b7b9075..ef0c35fefe 100644
--- a/crates/lang/macro/tests/ui/fail/M-05-message-invalid-selector.rs
+++ b/crates/lang/macro/tests/ui/fail/M-05-message-invalid-selector.rs
@@ -11,7 +11,7 @@ mod message_invalid_selector {
             Self {}
         }
 
-        #[ink(message, selector = "0x00")]
+        #[ink(message, selector = "0xC0DECAFE")]
         pub fn invalid_selector(&self) {}
     }
 }
diff --git a/crates/lang/macro/tests/ui/fail/M-05-message-invalid-selector.stderr b/crates/lang/macro/tests/ui/fail/M-05-message-invalid-selector.stderr
index ac4ea433bc..ef29bddacc 100644
--- a/crates/lang/macro/tests/ui/fail/M-05-message-invalid-selector.stderr
+++ b/crates/lang/macro/tests/ui/fail/M-05-message-invalid-selector.stderr
@@ -1,5 +1,5 @@
-error: invalid selector - a selector must consist of four bytes in hex (e.g. `selector = "0xCAFEBABE"`)
+error: #[ink(selector = ..)] attributes with string inputs are deprecated. use an integer instead, e.g. #[ink(selector = 1)] or #[ink(selector = 0xC0DECAFE)].
   --> $DIR/M-05-message-invalid-selector.rs:14:24
    |
-14 |         #[ink(message, selector = "0x00")]
-   |                        ^^^^^^^^^^^^^^^^^
+14 |         #[ink(message, selector = "0xC0DECAFE")]
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/crates/lang/macro/tests/ui/fail/M-06-message-invalid-selector-type.rs b/crates/lang/macro/tests/ui/fail/M-06-message-invalid-selector-type.rs
new file mode 100644
index 0000000000..88348aa471
--- /dev/null
+++ b/crates/lang/macro/tests/ui/fail/M-06-message-invalid-selector-type.rs
@@ -0,0 +1,19 @@
+use ink_lang as ink;
+
+#[ink::contract]
+mod message_invalid_selector {
+    #[ink(storage)]
+    pub struct MessageInvalidSelector {}
+
+    impl MessageInvalidSelector {
+        #[ink(constructor)]
+        pub fn constructor() -> Self {
+            Self {}
+        }
+
+        #[ink(message, selector = true)]
+        pub fn invalid_selector(&self) {}
+    }
+}
+
+fn main() {}
diff --git a/crates/lang/macro/tests/ui/fail/M-06-message-invalid-selector-type.stderr b/crates/lang/macro/tests/ui/fail/M-06-message-invalid-selector-type.stderr
new file mode 100644
index 0000000000..45844a68a6
--- /dev/null
+++ b/crates/lang/macro/tests/ui/fail/M-06-message-invalid-selector-type.stderr
@@ -0,0 +1,5 @@
+error: expecteded 4-digit hexcode for `selector` argument, e.g. #[ink(selector = 0xC0FEBABE]
+  --> $DIR/M-06-message-invalid-selector-type.rs:14:24
+   |
+14 |         #[ink(message, selector = true)]
+   |                        ^^^^^^^^^^^^^^^
diff --git a/crates/storage/derive/src/tests/spread_layout.rs b/crates/storage/derive/src/tests/spread_layout.rs
index 0cb9d2729b..286a509e64 100644
--- a/crates/storage/derive/src/tests/spread_layout.rs
+++ b/crates/storage/derive/src/tests/spread_layout.rs
@@ -32,9 +32,9 @@ fn unit_struct_works() {
             const _: () = {
                 impl ::ink_storage::traits::SpreadLayout for UnitStruct {
                     #[allow(unused_comparisons)]
-                    const FOOTPRINT: u64 = [0u64, 0u64][(0u64 < 0u64) as usize];
+                    const FOOTPRINT: ::core::primitive::u64 = [0u64, 0u64][(0u64 < 0u64) as ::core::primitive::usize];
 
-                    const REQUIRES_DEEP_CLEAN_UP : bool = (false || false );
+                    const REQUIRES_DEEP_CLEAN_UP : ::core::primitive::bool = (false || false );
 
                     fn pull_spread(__key_ptr: &mut ::ink_storage::traits::KeyPtr) -> Self {
                         UnitStruct
@@ -71,7 +71,7 @@ fn struct_works() {
             const _: () = {
                 impl ::ink_storage::traits::SpreadLayout for NamedFields {
                     #[allow(unused_comparisons)]
-                    const FOOTPRINT: u64 = [
+                    const FOOTPRINT: ::core::primitive::u64 = [
                         (((0u64 + <i32 as ::ink_storage::traits::SpreadLayout>::FOOTPRINT)
                             + <[u8; 32] as ::ink_storage::traits::SpreadLayout>::FOOTPRINT)
                             + <Box<i32> as ::ink_storage::traits::SpreadLayout>::FOOTPRINT),
@@ -80,10 +80,10 @@ fn struct_works() {
                         + <i32 as ::ink_storage::traits::SpreadLayout>::FOOTPRINT)
                         + <[u8; 32] as ::ink_storage::traits::SpreadLayout>::FOOTPRINT)
                         + <Box<i32> as ::ink_storage::traits::SpreadLayout>::FOOTPRINT)
-                        < 0u64) as usize
+                        < 0u64) as ::core::primitive::usize
                     ];
 
-                    const REQUIRES_DEEP_CLEAN_UP : bool = (
+                    const REQUIRES_DEEP_CLEAN_UP : ::core::primitive::bool = (
                         false || (
                             (
                                 (
@@ -181,7 +181,7 @@ fn enum_works() {
             const _: () = {
                 impl ::ink_storage::traits::SpreadLayout for MixedEnum {
                     #[allow(unused_comparisons)]
-                    const FOOTPRINT : u64 = 1 + [
+                    const FOOTPRINT : ::core::primitive::u64 = 1 + [
                         0u64 ,
                         [
                             (
@@ -211,7 +211,7 @@ fn enum_works() {
                                         + <(bool, i32) as ::ink_storage::traits::SpreadLayout>::FOOTPRINT
                                     )
                                     < 0u64
-                                ) as usize
+                                ) as ::core::primitive::usize
                             ]
                         ][
                             (
@@ -241,9 +241,9 @@ fn enum_works() {
                                             + <(bool, i32) as ::ink_storage::traits::SpreadLayout>::FOOTPRINT
                                         )
                                         < 0u64
-                                    ) as usize
+                                    ) as ::core::primitive::usize
                                 ]
-                            ) as usize
+                            ) as ::core::primitive::usize
                         ]
                     ][
                         (
@@ -274,7 +274,7 @@ fn enum_works() {
                                             + <(bool, i32) as ::ink_storage::traits::SpreadLayout>::FOOTPRINT
                                         )
                                         < 0u64
-                                    ) as usize
+                                    ) as ::core::primitive::usize
                                 ]
                             ][
                                 (
@@ -304,14 +304,14 @@ fn enum_works() {
                                                 + <(bool, i32) as ::ink_storage::traits::SpreadLayout>::FOOTPRINT
                                             )
                                             < 0u64
-                                        ) as usize
+                                        ) as ::core::primitive::usize
                                     ]
-                                ) as usize
+                                ) as ::core::primitive::usize
                             ]
-                        ) as usize
+                        ) as ::core::primitive::usize
                     ];
 
-                    const REQUIRES_DEEP_CLEAN_UP : bool = (
+                    const REQUIRES_DEEP_CLEAN_UP : ::core::primitive::bool = (
                         (
                             (false || false)
                             || (
@@ -332,7 +332,7 @@ fn enum_works() {
                     );
 
                     fn pull_spread(__key_ptr: &mut ::ink_storage::traits::KeyPtr) -> Self {
-                        match <u8 as ::ink_storage::traits::SpreadLayout>::pull_spread(__key_ptr)
+                        match <::core::primitive::u8 as ::ink_storage::traits::SpreadLayout>::pull_spread(__key_ptr)
                         {
                             0u8 => MixedEnum::A,
                             1u8 => MixedEnum::B(
@@ -350,7 +350,7 @@ fn enum_works() {
                         match self {
                             MixedEnum::A => {
                                 {
-                                    <u8 as ::ink_storage::traits::SpreadLayout>::push_spread(
+                                    <::core::primitive::u8 as ::ink_storage::traits::SpreadLayout>::push_spread(
                                         &0u8,
                                         __key_ptr
                                     );
@@ -358,7 +358,7 @@ fn enum_works() {
                             }
                             MixedEnum::B(__binding_0, __binding_1,) => {
                                 {
-                                    <u8 as ::ink_storage::traits::SpreadLayout>::push_spread(
+                                    <::core::primitive::u8 as ::ink_storage::traits::SpreadLayout>::push_spread(
                                         &1u8,
                                         __key_ptr
                                     );
@@ -381,7 +381,7 @@ fn enum_works() {
                                 b: __binding_1,
                             } => {
                                 {
-                                    <u8 as ::ink_storage::traits::SpreadLayout>::push_spread(
+                                    <::core::primitive::u8 as ::ink_storage::traits::SpreadLayout>::push_spread(
                                         &2u8, __key_ptr
                                     );
                                 }
@@ -459,16 +459,16 @@ fn generic_struct_works() {
                     T2: ::ink_storage::traits::SpreadLayout
                 {
                     #[allow(unused_comparisons)]
-                    const FOOTPRINT: u64 = [
+                    const FOOTPRINT: ::core::primitive::u64 = [
                         ((0u64 + <T1 as ::ink_storage::traits::SpreadLayout>::FOOTPRINT)
                             + <(T1, T2) as ::ink_storage::traits::SpreadLayout>::FOOTPRINT),
                         0u64
                     ][(((0u64 + <T1 as ::ink_storage::traits::SpreadLayout>::FOOTPRINT)
                         + <(T1, T2) as ::ink_storage::traits::SpreadLayout>::FOOTPRINT)
-                        < 0u64) as usize
+                        < 0u64) as ::core::primitive::usize
                     ];
 
-                    const REQUIRES_DEEP_CLEAN_UP : bool = (
+                    const REQUIRES_DEEP_CLEAN_UP : ::core::primitive::bool = (
                         false || (
                             (
                                 false
@@ -555,7 +555,7 @@ fn generic_enum_works() {
                     T2: ::ink_storage::traits::SpreadLayout
                 {
                     #[allow(unused_comparisons)]
-                    const FOOTPRINT: u64 = 1 + [
+                    const FOOTPRINT: ::core::primitive::u64 = 1 + [
                         ((0u64 + <T1 as ::ink_storage::traits::SpreadLayout>::FOOTPRINT)
                             + <T2 as ::ink_storage::traits::SpreadLayout>::FOOTPRINT),
                         [
@@ -565,7 +565,7 @@ fn generic_enum_works() {
                         ][(((0u64
                             + <T1 as ::ink_storage::traits::SpreadLayout>::FOOTPRINT)
                             + <T2 as ::ink_storage::traits::SpreadLayout>::FOOTPRINT)
-                            < 0u64) as usize]
+                            < 0u64) as ::core::primitive::usize]
                     ][(((0u64 + <T1 as ::ink_storage::traits::SpreadLayout>::FOOTPRINT)
                         + <T2 as ::ink_storage::traits::SpreadLayout>::FOOTPRINT)
                         < [
@@ -575,10 +575,10 @@ fn generic_enum_works() {
                         ][(((0u64
                             + <T1 as ::ink_storage::traits::SpreadLayout>::FOOTPRINT)
                             + <T2 as ::ink_storage::traits::SpreadLayout>::FOOTPRINT)
-                            < 0u64) as usize]) as usize
+                            < 0u64) as ::core::primitive::usize]) as ::core::primitive::usize
                     ];
 
-                    const REQUIRES_DEEP_CLEAN_UP : bool = (
+                    const REQUIRES_DEEP_CLEAN_UP : ::core::primitive::bool = (
                         (
                             false || (
                                 (
@@ -598,7 +598,7 @@ fn generic_enum_works() {
                     );
 
                     fn pull_spread(__key_ptr: &mut ::ink_storage::traits::KeyPtr) -> Self {
-                        match <u8 as ::ink_storage::traits::SpreadLayout>::pull_spread(__key_ptr)
+                        match <::core::primitive::u8 as ::ink_storage::traits::SpreadLayout>::pull_spread(__key_ptr)
                         {
                             0u8 => GenericEnum::Tuple(
                                 <T1 as ::ink_storage::traits::SpreadLayout>::pull_spread(__key_ptr),
@@ -616,7 +616,7 @@ fn generic_enum_works() {
                         match self {
                             GenericEnum::Tuple(__binding_0, __binding_1,) => {
                                 {
-                                    <u8 as ::ink_storage::traits::SpreadLayout>::push_spread(&0u8, __key_ptr);
+                                    <::core::primitive::u8 as ::ink_storage::traits::SpreadLayout>::push_spread(&0u8, __key_ptr);
                                 }
                                 {
                                     ::ink_storage::traits::SpreadLayout::push_spread(
@@ -636,7 +636,7 @@ fn generic_enum_works() {
                                 b: __binding_1,
                             } => {
                                 {
-                                    <u8 as ::ink_storage::traits::SpreadLayout>::push_spread(&1u8, __key_ptr);
+                                    <::core::primitive::u8 as ::ink_storage::traits::SpreadLayout>::push_spread(&1u8, __key_ptr);
                                 }
                                 {
                                     ::ink_storage::traits::SpreadLayout::push_spread(
diff --git a/crates/storage/derive/src/tests/storage_layout.rs b/crates/storage/derive/src/tests/storage_layout.rs
index d52e4905ec..2a71f50482 100644
--- a/crates/storage/derive/src/tests/storage_layout.rs
+++ b/crates/storage/derive/src/tests/storage_layout.rs
@@ -47,15 +47,15 @@ fn tuple_struct_works() {
                         ::ink_metadata::layout::Layout::Struct(
                             ::ink_metadata::layout::StructLayout::new(vec![
                                 ::ink_metadata::layout::FieldLayout::new(
-                                    None,
+                                    ::core::option::Option::None,
                                     <bool as ::ink_storage::traits::StorageLayout>::layout(__key_ptr),
                                 ),
                                 ::ink_metadata::layout::FieldLayout::new(
-                                    None,
+                                    ::core::option::Option::None,
                                     <u32 as ::ink_storage::traits::StorageLayout>::layout(__key_ptr),
                                 ),
                                 ::ink_metadata::layout::FieldLayout::new(
-                                    None,
+                                    ::core::option::Option::None,
                                     <i64 as ::ink_storage::traits::StorageLayout>::layout(__key_ptr),
                                 ),
                             ])
@@ -84,15 +84,15 @@ fn named_fields_struct_works() {
                         ::ink_metadata::layout::Layout::Struct(
                             ::ink_metadata::layout::StructLayout::new(vec![
                                 ::ink_metadata::layout::FieldLayout::new(
-                                    Some("a"),
+                                    ::core::option::Option::Some("a"),
                                     <bool as ::ink_storage::traits::StorageLayout>::layout(__key_ptr),
                                 ),
                                 ::ink_metadata::layout::FieldLayout::new(
-                                    Some("b"),
+                                    ::core::option::Option::Some("b"),
                                     <u32 as ::ink_storage::traits::StorageLayout>::layout(__key_ptr),
                                 ),
                                 ::ink_metadata::layout::FieldLayout::new(
-                                    Some("c"),
+                                    ::core::option::Option::Some("c"),
                                     <i64 as ::ink_storage::traits::StorageLayout>::layout(__key_ptr),
                                 ),
                             ])
@@ -191,15 +191,15 @@ fn mixed_enum_works() {
                                             ::ink_metadata::layout::Discriminant::from(1usize),
                                             ::ink_metadata::layout::StructLayout::new(vec![
                                                 ::ink_metadata::layout::FieldLayout::new(
-                                                    None,
+                                                    ::core::option::Option::None,
                                                     <bool as ::ink_storage::traits::StorageLayout>::layout(__key_ptr),
                                                 ),
                                                 ::ink_metadata::layout::FieldLayout::new(
-                                                    None,
+                                                    ::core::option::Option::None,
                                                     <u32 as ::ink_storage::traits::StorageLayout>::layout(__key_ptr),
                                                 ),
                                                 ::ink_metadata::layout::FieldLayout::new(
-                                                    None,
+                                                    ::core::option::Option::None,
                                                     <i64 as ::ink_storage::traits::StorageLayout>::layout(__key_ptr),
                                                 ),
                                             ]),
@@ -212,15 +212,15 @@ fn mixed_enum_works() {
                                             ::ink_metadata::layout::Discriminant::from(2usize),
                                             ::ink_metadata::layout::StructLayout::new(vec![
                                                 ::ink_metadata::layout::FieldLayout::new(
-                                                    Some("a"),
+                                                    ::core::option::Option::Some("a"),
                                                     <bool as ::ink_storage::traits::StorageLayout>::layout(__key_ptr),
                                                 ),
                                                 ::ink_metadata::layout::FieldLayout::new(
-                                                    Some("b"),
+                                                    ::core::option::Option::Some("b"),
                                                     <u32 as ::ink_storage::traits::StorageLayout>::layout(__key_ptr),
                                                 ),
                                                 ::ink_metadata::layout::FieldLayout::new(
-                                                    Some("c"),
+                                                    ::core::option::Option::Some("c"),
                                                     <i64 as ::ink_storage::traits::StorageLayout>::layout(__key_ptr),
                                                 ),
                                             ]),