From 0f2b2c6f40bedb8c1f23406603cdce9a8644e340 Mon Sep 17 00:00:00 2001 From: David Semakula Date: Fri, 8 Mar 2024 14:10:57 +0300 Subject: [PATCH] Use name-only syntax for `anonymous` ink! event item configuration argument (#2140) * Use name-only syntax for `anonymous` ink! event item configuration argument Required updating `ink_ir::ast::AttributeArgs` to support name-only meta items e.g. `#[ink::event(anonymous)]` * Add changelog entry --- CHANGELOG.md | 1 + crates/ink/ir/src/ast/attr_args.rs | 69 +++++++++++-------- crates/ink/ir/src/ast/meta.rs | 66 +++++++++++++++++- crates/ink/ir/src/error.rs | 15 ++++ crates/ink/ir/src/ir/chain_extension.rs | 18 ++--- crates/ink/ir/src/ir/config.rs | 46 ++++++++++--- crates/ink/ir/src/ir/event/config.rs | 29 +++++--- crates/ink/ir/src/ir/event/signature_topic.rs | 5 +- crates/ink/ir/src/ir/storage_item/config.rs | 9 +-- crates/ink/ir/src/ir/trait_def/config.rs | 24 +++++-- crates/ink/macro/src/lib.rs | 6 +- .../fail/config-keep-attr-missing-arg.stderr | 2 +- .../ui/event/fail/anonymous_invalid_value.rs | 8 +++ .../event/fail/anonymous_invalid_value.stderr | 5 ++ .../ui/event/fail/signature_missing_value.rs | 6 ++ .../event/fail/signature_missing_value.stderr | 5 ++ .../ui/event/pass/anonymous_flag_works.rs | 4 +- .../fail/argument_derive_invalid_type.stderr | 2 +- .../fail/argument_derive_missing_arg.stderr | 2 +- .../fail/config_keep_attr_missing_arg.stderr | 2 +- .../fail/config_namespace_invalid_2.stderr | 2 +- .../fail/config_namespace_invalid_4.stderr | 2 +- integration-tests/events/lib.rs | 2 +- 23 files changed, 246 insertions(+), 84 deletions(-) create mode 100644 crates/ink/tests/ui/event/fail/anonymous_invalid_value.rs create mode 100644 crates/ink/tests/ui/event/fail/anonymous_invalid_value.stderr create mode 100644 crates/ink/tests/ui/event/fail/signature_missing_value.rs create mode 100644 crates/ink/tests/ui/event/fail/signature_missing_value.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 7380a84942a..69f847e66e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Changed +- Use name-only syntax for `anonymous` ink! event item configuration argument - [#2140](https://github.com/paritytech/ink/pull/2140) - Restrict syntax for setting default ink! e2e test runtime-only emulator - [#2143](https://github.com/paritytech/ink/pull/2143) ## Version 5.0.0-rc.2 diff --git a/crates/ink/ir/src/ast/attr_args.rs b/crates/ink/ir/src/ast/attr_args.rs index ba8d598b2c2..6ed96c2571a 100644 --- a/crates/ink/ir/src/ast/attr_args.rs +++ b/crates/ink/ir/src/ast/attr_args.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use super::MetaNameValue; +use super::Meta; use syn::{ parse::{ Parse, @@ -28,7 +28,7 @@ use syn::{ /// in `#[ink::contract(env = ::my::env::Environment)]`. #[derive(Clone, Debug, PartialEq, Eq)] pub struct AttributeArgs { - args: Punctuated, + args: Punctuated, } impl quote::ToTokens for AttributeArgs { @@ -38,8 +38,8 @@ impl quote::ToTokens for AttributeArgs { } impl IntoIterator for AttributeArgs { - type Item = MetaNameValue; - type IntoIter = syn::punctuated::IntoIter; + type Item = Meta; + type IntoIter = syn::punctuated::IntoIter; fn into_iter(self) -> Self::IntoIter { self.args.into_iter() @@ -57,14 +57,17 @@ impl Parse for AttributeArgs { #[cfg(test)] mod tests { use super::*; - use crate::ast::MetaValue; + use crate::ast::{ + MetaNameValue, + MetaValue, + }; use quote::quote; impl AttributeArgs { /// Creates a new attribute argument list from the given arguments. pub fn new(args: I) -> Self where - I: IntoIterator, + I: IntoIterator, { Self { args: args.into_iter().collect(), @@ -80,15 +83,23 @@ mod tests { ) } + #[test] + fn flag_works() { + assert_eq!( + syn::parse2::(quote! { flag }).unwrap(), + AttributeArgs::new(vec![Meta::Path(syn::parse_quote! { flag })]) + ) + } + #[test] fn literal_bool_value_works() { assert_eq!( syn::parse2::(quote! { name = true }).unwrap(), - AttributeArgs::new(vec![MetaNameValue { + AttributeArgs::new(vec![Meta::NameValue(MetaNameValue { name: syn::parse_quote! { name }, eq_token: syn::parse_quote! { = }, value: MetaValue::Lit(syn::parse_quote! { true }), - }]) + })]) ) } @@ -96,11 +107,11 @@ mod tests { fn literal_str_value_works() { assert_eq!( syn::parse2::(quote! { name = "string literal" }).unwrap(), - AttributeArgs::new(vec![MetaNameValue { + AttributeArgs::new(vec![Meta::NameValue(MetaNameValue { name: syn::parse_quote! { name }, eq_token: syn::parse_quote! { = }, value: MetaValue::Lit(syn::parse_quote! { "string literal" }), - }]) + })]) ) } @@ -108,11 +119,11 @@ mod tests { fn ident_value_works() { assert_eq!( syn::parse2::(quote! { name = MyIdentifier }).unwrap(), - AttributeArgs::new(vec![MetaNameValue { + AttributeArgs::new(vec![Meta::NameValue(MetaNameValue { name: syn::parse_quote! { name }, eq_token: syn::parse_quote! { = }, value: MetaValue::Path(syn::parse_quote! { MyIdentifier }), - }]) + })]) ) } @@ -120,11 +131,11 @@ mod tests { fn root_path_value_works() { assert_eq!( syn::parse2::(quote! { name = ::this::is::my::Path }).unwrap(), - AttributeArgs::new(vec![MetaNameValue { + AttributeArgs::new(vec![Meta::NameValue(MetaNameValue { name: syn::parse_quote! { name }, eq_token: syn::parse_quote! { = }, value: MetaValue::Path(syn::parse_quote! { ::this::is::my::Path }), - }]) + })]) ) } @@ -133,24 +144,24 @@ mod tests { assert_eq!( syn::parse2::(quote! { name = this::is::my::relative::Path }) .unwrap(), - AttributeArgs::new(vec![MetaNameValue { + AttributeArgs::new(vec![Meta::NameValue(MetaNameValue { name: syn::parse_quote! { name }, eq_token: syn::parse_quote! { = }, value: MetaValue::Path( syn::parse_quote! { this::is::my::relative::Path } ), - }]) + })]) ) } #[test] fn trailing_comma_works() { let mut expected_args = Punctuated::new(); - expected_args.push_value(MetaNameValue { + expected_args.push_value(Meta::NameValue(MetaNameValue { name: syn::parse_quote! { name }, eq_token: syn::parse_quote! { = }, value: MetaValue::Path(syn::parse_quote! { value }), - }); + })); expected_args.push_punct(::default()); assert_eq!( syn::parse2::(quote! { name = value, }).unwrap(), @@ -164,6 +175,7 @@ mod tests { fn many_mixed_works() { assert_eq!( syn::parse2::(quote! { + flag, name1 = ::root::Path, name2 = false, name3 = "string literal", @@ -172,31 +184,32 @@ mod tests { }) .unwrap(), AttributeArgs::new(vec![ - MetaNameValue { + Meta::Path(syn::parse_quote! { flag }), + Meta::NameValue(MetaNameValue { name: syn::parse_quote! { name1 }, eq_token: syn::parse_quote! { = }, value: MetaValue::Path(syn::parse_quote! { ::root::Path }), - }, - MetaNameValue { + }), + Meta::NameValue(MetaNameValue { name: syn::parse_quote! { name2 }, eq_token: syn::parse_quote! { = }, value: MetaValue::Lit(syn::parse_quote! { false }), - }, - MetaNameValue { + }), + Meta::NameValue(MetaNameValue { name: syn::parse_quote! { name3 }, eq_token: syn::parse_quote! { = }, value: MetaValue::Lit(syn::parse_quote! { "string literal" }), - }, - MetaNameValue { + }), + Meta::NameValue(MetaNameValue { name: syn::parse_quote! { name4 }, eq_token: syn::parse_quote! { = }, value: MetaValue::Lit(syn::parse_quote! { 42 }), - }, - MetaNameValue { + }), + Meta::NameValue(MetaNameValue { name: syn::parse_quote! { name5 }, eq_token: syn::parse_quote! { = }, value: MetaValue::Lit(syn::parse_quote! { 7.7 }), - }, + }), ]) ) } diff --git a/crates/ink/ir/src/ast/meta.rs b/crates/ink/ir/src/ast/meta.rs index df1703afa9d..831b00e954f 100644 --- a/crates/ink/ir/src/ast/meta.rs +++ b/crates/ink/ir/src/ast/meta.rs @@ -25,7 +25,9 @@ use syn::{ }, punctuated::Punctuated, spanned::Spanned, + LitBool, LitInt, + LitStr, Token, }; @@ -62,6 +64,32 @@ impl ToTokens for Meta { } } +impl Meta { + /// Returns the meta-item name. + pub fn name(&self) -> &syn::Path { + match self { + Meta::Path(path) => path, + Meta::NameValue(name_value) => &name_value.name, + } + } + + /// Returns the meta-item value (if any). + pub fn value(&self) -> Option<&MetaValue> { + match self { + Meta::Path(_) => None, + Meta::NameValue(name_value) => Some(&name_value.value), + } + } + + /// Returns the `NameValue` variant (if any). + pub fn name_value(&self) -> Option<&MetaNameValue> { + match self { + Meta::NameValue(name_value) => Some(name_value), + Meta::Path(_) => None, + } + } +} + /// A name-value pair within an attribute, like `feature = "nightly"`. /// /// The only difference from `syn::MetaNameValue` is that this additionally @@ -157,13 +185,37 @@ impl MetaValue { } } - /// Returns the the literal if it is an integer literal. + /// Returns the literal if it is an integer literal. pub fn as_lit_int(&self) -> Option<&LitInt> { match self { Self::Lit(syn::Lit::Int(lit_int)) => Some(lit_int), _ => None, } } + + /// Returns the literal if it is a boolean literal. + pub fn as_lit_bool(&self) -> Option<&LitBool> { + match self { + Self::Lit(syn::Lit::Bool(lit_bool)) => Some(lit_bool), + _ => None, + } + } + + /// Returns the literal if it is a string literal. + pub fn as_lit_string(&self) -> Option<&LitStr> { + match self { + Self::Lit(syn::Lit::Str(lit_str)) => Some(lit_str), + _ => None, + } + } + + /// Returns the path (if the value is a path). + pub fn as_path(&self) -> Option<&syn::Path> { + match self { + Self::Path(path) => Some(path), + _ => None, + } + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -243,4 +295,16 @@ mod tests { }) ) } + + #[test] + fn at_token_works() { + assert_eq!( + syn::parse2::(quote! { selector = @ }).unwrap(), + Meta::NameValue(MetaNameValue { + name: syn::parse_quote! { selector }, + eq_token: syn::parse_quote! { = }, + value: MetaValue::Symbol(Symbol::AtSign(syn::parse_quote! { @ })), + }) + ) + } } diff --git a/crates/ink/ir/src/error.rs b/crates/ink/ir/src/error.rs index a955dc2e101..55fd1ef5f77 100644 --- a/crates/ink/ir/src/error.rs +++ b/crates/ink/ir/src/error.rs @@ -53,6 +53,21 @@ macro_rules! format_err_spanned { } } +/// Creates a [`syn::Error`] with the format message and infers the +/// [`Span`](`proc_macro2::Span`) using the [`ToTokens`](`quote::ToTokens`) implementation +/// for the [`MetaValue`][crate::ast::MetaValue] (if possible). +/// +/// See [`format_err_spanned`] for more details. +macro_rules! format_err_spanned_value { + ($arg:expr, $($msg:tt)*) => { + if let Some(value) = $arg.value() { + format_err_spanned!(value, $($msg)*) + } else { + format_err_spanned!($arg, $($msg)*) + } + }; +} + /// Creates a [`syn::Error`] with the format message and infers the /// [`Span`](`proc_macro2::Span`) using [`Spanned`](`syn::spanned::Spanned`). /// diff --git a/crates/ink/ir/src/ir/chain_extension.rs b/crates/ink/ir/src/ir/chain_extension.rs index 30e5b768ec9..f4e22727096 100644 --- a/crates/ink/ir/src/ir/chain_extension.rs +++ b/crates/ink/ir/src/ir/chain_extension.rs @@ -81,15 +81,15 @@ impl TryFrom for Config { let mut ext_id: Option = None; for arg in args.clone().into_iter() { - if arg.name.is_ident("extension") { + if arg.name().is_ident("extension") { if ext_id.is_some() { - return Err(format_err_spanned!( - arg.value, + return Err(format_err_spanned_value!( + arg, "encountered duplicate ink! contract `extension` configuration argument", - )) + )); } - if let Some(lit_int) = arg.value.as_lit_int() { + if let Some(lit_int) = arg.value().and_then(ast::MetaValue::as_lit_int) { let id = lit_int.base10_parse::() .map_err(|error| { format_err_spanned!( @@ -98,16 +98,16 @@ impl TryFrom for Config { })?; ext_id = Some(ExtensionId::from_u16(id)); } else { - return Err(format_err_spanned!( - arg.value, + return Err(format_err_spanned_value!( + arg, "expected `u16` integer type for `N` in `extension = N`", - )) + )); } } else { return Err(format_err_spanned!( arg, "encountered unknown or unsupported chain extension configuration argument", - )) + )); } } diff --git a/crates/ink/ir/src/ir/config.rs b/crates/ink/ir/src/ir/config.rs index 2e5d7a7340e..dbb63bf2323 100644 --- a/crates/ink/ir/src/ir/config.rs +++ b/crates/ink/ir/src/ir/config.rs @@ -41,25 +41,35 @@ impl TryFrom for Config { let mut whitelisted_attributes = WhitelistedAttributes::default(); for arg in args.into_iter() { - if arg.name.is_ident("env") { + if arg.name().is_ident("env") { if let Some((_, ast)) = env { - return Err(duplicate_config_err(ast, arg, "env", "contract")) + return Err(duplicate_config_err(ast, arg, "env", "contract")); } - if let ast::MetaValue::Path(path) = &arg.value { - env = Some((Environment { path: path.clone() }, arg)) + let env_info = arg + .name_value() + .zip(arg.value().and_then(ast::MetaValue::as_path)); + if let Some((name_value, path)) = env_info { + env = Some((Environment { path: path.clone() }, name_value.clone())) } else { return Err(format_err_spanned!( arg, - "expected a path for `env` ink! configuration argument", - )) + "expected a path value for `env` ink! configuration argument", + )); + } + } else if arg.name().is_ident("keep_attr") { + if let Some(name_value) = arg.name_value() { + whitelisted_attributes.parse_arg_value(name_value)?; + } else { + return Err(format_err_spanned!( + arg, + "expected a string literal value for `keep_attr` ink! configuration argument", + )); } - } else if arg.name.is_ident("keep_attr") { - whitelisted_attributes.parse_arg_value(&arg)?; } else { return Err(format_err_spanned!( arg, "encountered unknown or unsupported ink! configuration argument", - )) + )); } } Ok(Config { @@ -143,7 +153,15 @@ mod tests { fn env_invalid_value_fails() { assert_try_from( syn::parse_quote! { env = "invalid" }, - Err("expected a path for `env` ink! configuration argument"), + Err("expected a path value for `env` ink! configuration argument"), + ); + } + + #[test] + fn env_missing_value_fails() { + assert_try_from( + syn::parse_quote! { env }, + Err("expected a path value for `env` ink! configuration argument"), ); } @@ -189,4 +207,12 @@ mod tests { Err("expected a string with attributes separated by `,`"), ); } + + #[test] + fn keep_attr_missing_value_fails() { + assert_try_from( + syn::parse_quote! { keep_attr }, + Err("expected a string literal value for `keep_attr` ink! configuration argument"), + ); + } } diff --git a/crates/ink/ir/src/ir/event/config.rs b/crates/ink/ir/src/ir/event/config.rs index 71313c36530..1020bd8657d 100644 --- a/crates/ink/ir/src/ir/event/config.rs +++ b/crates/ink/ir/src/ir/event/config.rs @@ -33,22 +33,23 @@ impl TryFrom for EventConfig { type Error = syn::Error; fn try_from(args: ast::AttributeArgs) -> Result { - let mut anonymous: Option = None; + let mut anonymous: Option = None; let mut signature_topic: Option = None; for arg in args.into_iter() { - if arg.name.is_ident("anonymous") { + if arg.name().is_ident("anonymous") { if let Some(lit_bool) = anonymous { return Err(duplicate_config_err(lit_bool, arg, "anonymous", "event")); } - if let ast::MetaValue::Lit(syn::Lit::Bool(lit_bool)) = &arg.value { - anonymous = Some(lit_bool.clone()) + if let ast::Meta::Path(path) = arg { + anonymous = Some(path) } else { return Err(format_err_spanned!( arg, - "expected a bool literal for `anonymous` ink! event item configuration argument", + "encountered an unexpected value for `anonymous` ink! event item configuration argument. \ + Did you mean #[ink::event(anonymous)] ?", )); } - } else if arg.name.is_ident("signature_topic") { + } else if arg.name().is_ident("signature_topic") { if anonymous.is_some() { return Err(format_err_spanned!( arg, @@ -57,14 +58,20 @@ impl TryFrom for EventConfig { } if let Some(lit_str) = signature_topic { - return Err(duplicate_config_err(lit_str, arg, "anonymous", "event")); + return Err(duplicate_config_err( + lit_str, + arg, + "signature_topic", + "event", + )); } - if let ast::MetaValue::Lit(syn::Lit::Str(lis_str)) = &arg.value { - signature_topic = Some(lis_str.clone()) + if let Some(lit_str) = arg.value().and_then(ast::MetaValue::as_lit_string) + { + signature_topic = Some(lit_str.clone()) } else { return Err(format_err_spanned!( arg, - "expected a bool literal for `anonymous` ink! event item configuration argument", + "expected a string literal value for `signature_topic` ink! event item configuration argument", )); } } else { @@ -76,7 +83,7 @@ impl TryFrom for EventConfig { } Ok(EventConfig::new( - anonymous.map(|lit_bool| lit_bool.value).unwrap_or(false), + anonymous.is_some(), signature_topic.map(|lit_str| lit_str.value()), )) } diff --git a/crates/ink/ir/src/ir/event/signature_topic.rs b/crates/ink/ir/src/ir/event/signature_topic.rs index 4e4aa4d46f9..49ed14fdd20 100644 --- a/crates/ink/ir/src/ir/event/signature_topic.rs +++ b/crates/ink/ir/src/ir/event/signature_topic.rs @@ -89,14 +89,15 @@ impl TryFrom for Option { fn try_from(args: ast::AttributeArgs) -> Result { let mut signature_topic: Option = None; for arg in args.into_iter() { - if arg.name.is_ident("hash") { + if arg.name().is_ident("hash") { if signature_topic.is_some() { return Err(format_err!( arg.span(), "encountered duplicate ink! event configuration argument" )); } - signature_topic = Some(SignatureTopicArg::try_from(&arg.value)?); + signature_topic = + arg.value().map(SignatureTopicArg::try_from).transpose()?; } else { return Err(format_err_spanned!( arg, diff --git a/crates/ink/ir/src/ir/storage_item/config.rs b/crates/ink/ir/src/ir/storage_item/config.rs index 213a5e77a1f..d35c984c45d 100644 --- a/crates/ink/ir/src/ir/storage_item/config.rs +++ b/crates/ink/ir/src/ir/storage_item/config.rs @@ -33,21 +33,22 @@ impl TryFrom for StorageItemConfig { fn try_from(args: ast::AttributeArgs) -> Result { let mut derive: Option = None; for arg in args.into_iter() { - if arg.name.is_ident("derive") { + if arg.name().is_ident("derive") { if let Some(lit_bool) = derive { return Err(duplicate_config_err( lit_bool, arg, "derive", "storage item", - )) + )); } - if let ast::MetaValue::Lit(syn::Lit::Bool(lit_bool)) = &arg.value { + if let Some(lit_bool) = arg.value().and_then(ast::MetaValue::as_lit_bool) + { derive = Some(lit_bool.clone()) } else { return Err(format_err_spanned!( arg, - "expected a bool literal for `derive` ink! storage item configuration argument", + "expected a bool literal value for `derive` ink! storage item configuration argument", )); } } else { diff --git a/crates/ink/ir/src/ir/trait_def/config.rs b/crates/ink/ir/src/ir/trait_def/config.rs index 1e6ae16274d..4b4737179f2 100644 --- a/crates/ink/ir/src/ir/trait_def/config.rs +++ b/crates/ink/ir/src/ir/trait_def/config.rs @@ -57,31 +57,41 @@ impl TryFrom for TraitDefinitionConfig { let mut namespace: Option<(syn::LitStr, ast::MetaNameValue)> = None; let mut whitelisted_attributes = WhitelistedAttributes::default(); for arg in args.into_iter() { - if arg.name.is_ident("namespace") { + if arg.name().is_ident("namespace") { if let Some((_, meta_name_value)) = namespace { return Err(duplicate_config_err( meta_name_value, arg, "namespace", "trait definition", - )) + )); } - if let ast::MetaValue::Lit(syn::Lit::Str(lit_str)) = &arg.value { + let namespace_info = arg + .name_value() + .zip(arg.value().and_then(ast::MetaValue::as_lit_string)); + if let Some((name_value, lit_str)) = namespace_info { if syn::parse_str::(&lit_str.value()).is_err() { return Err(format_err_spanned!( lit_str, "encountered invalid Rust identifier for the ink! namespace configuration parameter" )); } - namespace = Some((lit_str.clone(), arg)) + namespace = Some((lit_str.clone(), name_value.clone())) + } else { + return Err(format_err_spanned!( + arg, + "expected a string literal value for `namespace` ink! trait definition configuration argument", + )); + } + } else if arg.name().is_ident("keep_attr") { + if let Some(name_value) = arg.name_value() { + whitelisted_attributes.parse_arg_value(name_value)?; } else { return Err(format_err_spanned!( arg, - "expected a string literal for `namespace` ink! trait definition configuration argument", + "expected a string literal value for `keep_attr` ink! configuration argument", )); } - } else if arg.name.is_ident("keep_attr") { - whitelisted_attributes.parse_arg_value(&arg)?; } else { return Err(format_err_spanned!( arg, diff --git a/crates/ink/macro/src/lib.rs b/crates/ink/macro/src/lib.rs index 6476b0ef921..b81473af2c0 100644 --- a/crates/ink/macro/src/lib.rs +++ b/crates/ink/macro/src/lib.rs @@ -657,7 +657,7 @@ pub fn trait_definition(attr: TokenStream, item: TokenStream) -> TokenStream { /// contract. /// /// By default, a signature topic will be generated for the event. This allows consumers -/// to filter and identify events of this type. Marking an event with `anonymous = true` +/// to filter and identify events of this type. Marking an event with `anonymous` /// means no signature topic will be generated or emitted. /// Custom signature topic can be specified with `signature_topic = <32 byte hex string>`. /// @@ -673,8 +673,8 @@ pub fn trait_definition(attr: TokenStream, item: TokenStream) -> TokenStream { /// pub topic: [u8; 32], /// } /// -/// // Setting `anonymous = true` means no signature topic will be emitted for the event. -/// #[ink::event(anonymous = true)] +/// // Setting `anonymous` means no signature topic will be emitted for the event. +/// #[ink::event(anonymous)] /// pub struct MyAnonEvent { /// pub field: u32, /// #[ink(topic)] diff --git a/crates/ink/tests/ui/contract/fail/config-keep-attr-missing-arg.stderr b/crates/ink/tests/ui/contract/fail/config-keep-attr-missing-arg.stderr index ec0956fac84..33054b2fcb1 100644 --- a/crates/ink/tests/ui/contract/fail/config-keep-attr-missing-arg.stderr +++ b/crates/ink/tests/ui/contract/fail/config-keep-attr-missing-arg.stderr @@ -1,4 +1,4 @@ -error: ink! config options require an argument separated by '=' +error: expected a string literal value for `keep_attr` ink! configuration argument --> tests/ui/contract/fail/config-keep-attr-missing-arg.rs:1:17 | 1 | #[ink::contract(keep_attr)] diff --git a/crates/ink/tests/ui/event/fail/anonymous_invalid_value.rs b/crates/ink/tests/ui/event/fail/anonymous_invalid_value.rs new file mode 100644 index 00000000000..a1dcb8abbcd --- /dev/null +++ b/crates/ink/tests/ui/event/fail/anonymous_invalid_value.rs @@ -0,0 +1,8 @@ +#[ink::event(anonymous = true)] +pub struct Event { + #[ink(topic)] + pub topic: [u8; 32], + pub field_1: u32, +} + +fn main() {} diff --git a/crates/ink/tests/ui/event/fail/anonymous_invalid_value.stderr b/crates/ink/tests/ui/event/fail/anonymous_invalid_value.stderr new file mode 100644 index 00000000000..6547f3ac271 --- /dev/null +++ b/crates/ink/tests/ui/event/fail/anonymous_invalid_value.stderr @@ -0,0 +1,5 @@ +error: encountered an unexpected value for `anonymous` ink! event item configuration argument. Did you mean #[ink::event(anonymous)] ? + --> tests/ui/event/fail/anonymous_invalid_value.rs:1:14 + | +1 | #[ink::event(anonymous = true)] + | ^^^^^^^^^^^^^^^^ diff --git a/crates/ink/tests/ui/event/fail/signature_missing_value.rs b/crates/ink/tests/ui/event/fail/signature_missing_value.rs new file mode 100644 index 00000000000..293e2d50d61 --- /dev/null +++ b/crates/ink/tests/ui/event/fail/signature_missing_value.rs @@ -0,0 +1,6 @@ +#[ink::event(signature_topic)] +pub struct Event { + pub topic: [u8; 32], +} + +fn main() {} diff --git a/crates/ink/tests/ui/event/fail/signature_missing_value.stderr b/crates/ink/tests/ui/event/fail/signature_missing_value.stderr new file mode 100644 index 00000000000..a81245df5d6 --- /dev/null +++ b/crates/ink/tests/ui/event/fail/signature_missing_value.stderr @@ -0,0 +1,5 @@ +error: expected a string literal value for `signature_topic` ink! event item configuration argument + --> tests/ui/event/fail/signature_missing_value.rs:1:14 + | +1 | #[ink::event(signature_topic)] + | ^^^^^^^^^^^^^^^ diff --git a/crates/ink/tests/ui/event/pass/anonymous_flag_works.rs b/crates/ink/tests/ui/event/pass/anonymous_flag_works.rs index 34a6e705d2e..edf81c79b9d 100644 --- a/crates/ink/tests/ui/event/pass/anonymous_flag_works.rs +++ b/crates/ink/tests/ui/event/pass/anonymous_flag_works.rs @@ -1,8 +1,8 @@ -#[ink::event(anonymous = true)] +#[ink::event(anonymous)] pub struct Event { #[ink(topic)] pub topic: [u8; 32], pub field_1: u32, } -fn main() {} \ No newline at end of file +fn main() {} diff --git a/crates/ink/tests/ui/storage_item/fail/argument_derive_invalid_type.stderr b/crates/ink/tests/ui/storage_item/fail/argument_derive_invalid_type.stderr index 40fd498c21b..cb8a6edcb9d 100644 --- a/crates/ink/tests/ui/storage_item/fail/argument_derive_invalid_type.stderr +++ b/crates/ink/tests/ui/storage_item/fail/argument_derive_invalid_type.stderr @@ -1,4 +1,4 @@ -error: expected a bool literal for `derive` ink! storage item configuration argument +error: expected a bool literal value for `derive` ink! storage item configuration argument --> tests/ui/storage_item/fail/argument_derive_invalid_type.rs:1:21 | 1 | #[ink::storage_item(derive = "false")] diff --git a/crates/ink/tests/ui/storage_item/fail/argument_derive_missing_arg.stderr b/crates/ink/tests/ui/storage_item/fail/argument_derive_missing_arg.stderr index 1915baf6c6f..3c5f9c41530 100644 --- a/crates/ink/tests/ui/storage_item/fail/argument_derive_missing_arg.stderr +++ b/crates/ink/tests/ui/storage_item/fail/argument_derive_missing_arg.stderr @@ -1,4 +1,4 @@ -error: ink! config options require an argument separated by '=' +error: expected a bool literal value for `derive` ink! storage item configuration argument --> tests/ui/storage_item/fail/argument_derive_missing_arg.rs:1:21 | 1 | #[ink::storage_item(derive)] diff --git a/crates/ink/tests/ui/trait_def/fail/config_keep_attr_missing_arg.stderr b/crates/ink/tests/ui/trait_def/fail/config_keep_attr_missing_arg.stderr index 6b9d883a1b1..0aea620055f 100644 --- a/crates/ink/tests/ui/trait_def/fail/config_keep_attr_missing_arg.stderr +++ b/crates/ink/tests/ui/trait_def/fail/config_keep_attr_missing_arg.stderr @@ -1,4 +1,4 @@ -error: ink! config options require an argument separated by '=' +error: expected a string literal value for `keep_attr` ink! configuration argument --> tests/ui/trait_def/fail/config_keep_attr_missing_arg.rs:1:25 | 1 | #[ink::trait_definition(keep_attr)] diff --git a/crates/ink/tests/ui/trait_def/fail/config_namespace_invalid_2.stderr b/crates/ink/tests/ui/trait_def/fail/config_namespace_invalid_2.stderr index d0db5ea758c..1a125cc2309 100644 --- a/crates/ink/tests/ui/trait_def/fail/config_namespace_invalid_2.stderr +++ b/crates/ink/tests/ui/trait_def/fail/config_namespace_invalid_2.stderr @@ -1,4 +1,4 @@ -error: ink! config options require an argument separated by '=' +error: expected a string literal value for `namespace` ink! trait definition configuration argument --> tests/ui/trait_def/fail/config_namespace_invalid_2.rs:1:25 | 1 | #[ink::trait_definition(namespace)] diff --git a/crates/ink/tests/ui/trait_def/fail/config_namespace_invalid_4.stderr b/crates/ink/tests/ui/trait_def/fail/config_namespace_invalid_4.stderr index a609223a57f..196a49e75d8 100644 --- a/crates/ink/tests/ui/trait_def/fail/config_namespace_invalid_4.stderr +++ b/crates/ink/tests/ui/trait_def/fail/config_namespace_invalid_4.stderr @@ -1,4 +1,4 @@ -error: expected a string literal for `namespace` ink! trait definition configuration argument +error: expected a string literal value for `namespace` ink! trait definition configuration argument --> tests/ui/trait_def/fail/config_namespace_invalid_4.rs:1:25 | 1 | #[ink::trait_definition(namespace = true)] diff --git a/integration-tests/events/lib.rs b/integration-tests/events/lib.rs index 8fcaace02a7..211b55b33ae 100644 --- a/integration-tests/events/lib.rs +++ b/integration-tests/events/lib.rs @@ -1,6 +1,6 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] -#[ink::event(anonymous = true)] +#[ink::event(anonymous)] pub struct AnonymousEvent { #[ink(topic)] pub topic: [u8; 32],