diff --git a/CHANGELOG.md b/CHANGELOG.md index 22ef08af222..aacbef652ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed +- Upgraded `syn` to version `2` - [#1731](https://github.com/paritytech/ink/pull/1731) + ## Version 4.1.0 ### Added diff --git a/crates/e2e/macro/Cargo.toml b/crates/e2e/macro/Cargo.toml index 5dbc5b17943..3b2a92dd08b 100644 --- a/crates/e2e/macro/Cargo.toml +++ b/crates/e2e/macro/Cargo.toml @@ -26,7 +26,7 @@ derive_more = "0.99.17" env_logger = "0.10.0" log = "0.4.17" serde_json = "1.0.89" -syn = "1" +syn = "2" proc-macro2 = "1" quote = "1" which = "4.4.0" diff --git a/crates/ink/codegen/Cargo.toml b/crates/ink/codegen/Cargo.toml index e42f3fa8025..45c0d5b98f7 100644 --- a/crates/ink/codegen/Cargo.toml +++ b/crates/ink/codegen/Cargo.toml @@ -21,7 +21,7 @@ name = "ink_codegen" ink_primitives = { version = "4.1.0", path = "../../primitives" } ir = { version = "4.1.0", package = "ink_ir", path = "../ir", default-features = false } quote = "1" -syn = { version = "1.0", features = ["parsing", "full", "extra-traits"] } +syn = { version = "2.0", features = ["parsing", "full", "extra-traits"] } proc-macro2 = "1.0" derive_more = { version = "0.99", default-features = false, features = ["from"] } itertools = "0.10" diff --git a/crates/ink/ir/Cargo.toml b/crates/ink/ir/Cargo.toml index 961c96f2b05..54333332e28 100644 --- a/crates/ink/ir/Cargo.toml +++ b/crates/ink/ir/Cargo.toml @@ -19,7 +19,7 @@ name = "ink_ir" [dependencies] quote = "1" -syn = { version = "1.0", features = ["parsing", "full", "visit", "extra-traits"] } +syn = { version = "2.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 } diff --git a/crates/ink/ir/src/ast/attr_args.rs b/crates/ink/ir/src/ast/attr_args.rs index cfc4adb38a7..40175302ef5 100644 --- a/crates/ink/ir/src/ast/attr_args.rs +++ b/crates/ink/ir/src/ast/attr_args.rs @@ -12,19 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use proc_macro2::{ - Ident, - TokenStream as TokenStream2, -}; -use quote::ToTokens; +use super::MetaNameValue; use syn::{ - ext::IdentExt as _, parse::{ Parse, ParseStream, }, punctuated::Punctuated, - spanned::Spanned, Token, }; @@ -37,24 +31,6 @@ pub struct AttributeArgs { args: Punctuated, } -/// A name-value pair within an attribute, like `feature = "nightly"`. -/// -/// The only difference from `syn::MetaNameValue` is that this additionally -/// allows the `value` to be a plain identifier or path. -#[derive(Debug, PartialEq, Eq)] -pub struct MetaNameValue { - pub name: syn::Path, - pub eq_token: syn::token::Eq, - pub value: PathOrLit, -} - -/// Either a path or a literal. -#[derive(Debug, PartialEq, Eq)] -pub enum PathOrLit { - Path(syn::Path), - Lit(syn::Lit), -} - impl IntoIterator for AttributeArgs { type Item = MetaNameValue; type IntoIter = syn::punctuated::IntoIter; @@ -72,94 +48,10 @@ impl Parse for AttributeArgs { } } -impl Parse for MetaNameValue { - fn parse(input: ParseStream) -> Result { - let path = input.call(Self::parse_meta_path)?; - Self::parse_meta_name_value_after_path(path, input) - } -} - -impl ToTokens for PathOrLit { - fn to_tokens(&self, tokens: &mut TokenStream2) { - match self { - Self::Lit(lit) => lit.to_tokens(tokens), - Self::Path(path) => path.to_tokens(tokens), - } - } -} - -impl ToTokens for MetaNameValue { - fn to_tokens(&self, tokens: &mut TokenStream2) { - self.name.to_tokens(tokens); - self.eq_token.to_tokens(tokens); - self.value.to_tokens(tokens); - } -} - -impl MetaNameValue { - /// Like [`syn::Path::parse_mod_style`] but accepts keywords in the path. - /// - /// # Note - /// - /// This code was taken from the `syn` implementation for a very similar - /// syntactical pattern. - fn parse_meta_path(input: ParseStream) -> Result { - Ok(syn::Path { - leading_colon: input.parse()?, - segments: { - let mut segments = Punctuated::new(); - while input.peek(Ident::peek_any) { - let ident = Ident::parse_any(input)?; - segments.push_value(syn::PathSegment::from(ident)); - if !input.peek(syn::Token![::]) { - break - } - let punct = input.parse()?; - segments.push_punct(punct); - } - if segments.is_empty() { - return Err(input.error("expected path")) - } else if segments.trailing_punct() { - return Err(input.error("expected path segment")) - } - segments - }, - }) - } - - fn parse_meta_name_value_after_path( - name: syn::Path, - input: ParseStream, - ) -> Result { - let span = name.span(); - Ok(MetaNameValue { - name, - eq_token: input.parse().map_err(|_error| { - format_err!( - span, - "ink! config options require an argument separated by '='", - ) - })?, - value: input.parse()?, - }) - } -} - -impl Parse for PathOrLit { - fn parse(input: ParseStream) -> Result { - if input.fork().peek(syn::Lit) { - return input.parse::().map(PathOrLit::Lit) - } - if input.fork().peek(Ident::peek_any) || input.fork().peek(Token![::]) { - return input.parse::().map(PathOrLit::Path) - } - Err(input.error("cannot parse into either literal or path")) - } -} - #[cfg(test)] mod tests { use super::*; + use crate::ast::PathOrLit; use quote::quote; impl AttributeArgs { diff --git a/crates/ink/ir/src/ast/meta.rs b/crates/ink/ir/src/ast/meta.rs new file mode 100644 index 00000000000..8aae8e4f4c4 --- /dev/null +++ b/crates/ink/ir/src/ast/meta.rs @@ -0,0 +1,211 @@ +// Copyright 2018-2022 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::{ + Ident, + TokenStream as TokenStream2, +}; +use quote::ToTokens; +use syn::{ + ext::IdentExt as _, + parse::{ + Parse, + ParseStream, + }, + punctuated::Punctuated, + spanned::Spanned, + LitInt, + Token, +}; + +/// Content of a compile-time structured attribute. +/// +/// This is a subset of `syn::Meta` that allows the `value` of a name-value pair +/// to be a plain identifier or path. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum Meta { + /// A path, like `message`. + Path(syn::Path), + /// A name-value pair, like `feature = "nightly"`. + NameValue(MetaNameValue), +} + +impl Parse for Meta { + fn parse(input: ParseStream) -> Result { + let path = input.call(parse_meta_path)?; + if input.peek(Token![=]) { + MetaNameValue::parse_meta_name_value_after_path(path, input) + .map(Meta::NameValue) + } else { + Ok(Meta::Path(path)) + } + } +} + +impl ToTokens for Meta { + fn to_tokens(&self, tokens: &mut TokenStream2) { + match self { + Self::Path(path) => path.to_tokens(tokens), + Self::NameValue(name_value) => name_value.to_tokens(tokens), + } + } +} + +/// A name-value pair within an attribute, like `feature = "nightly"`. +/// +/// The only difference from `syn::MetaNameValue` is that this additionally +/// allows the `value` to be a plain identifier or path. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct MetaNameValue { + pub name: syn::Path, + pub eq_token: syn::token::Eq, + pub value: PathOrLit, +} + +impl Parse for MetaNameValue { + fn parse(input: ParseStream) -> Result { + let path = input.call(parse_meta_path)?; + Self::parse_meta_name_value_after_path(path, input) + } +} + +impl ToTokens for MetaNameValue { + fn to_tokens(&self, tokens: &mut TokenStream2) { + self.name.to_tokens(tokens); + self.eq_token.to_tokens(tokens); + self.value.to_tokens(tokens); + } +} + +impl MetaNameValue { + fn parse_meta_name_value_after_path( + name: syn::Path, + input: ParseStream, + ) -> Result { + let span = name.span(); + Ok(MetaNameValue { + name, + eq_token: input.parse().map_err(|_error| { + format_err!( + span, + "ink! config options require an argument separated by '='", + ) + })?, + value: input.parse()?, + }) + } +} + +/// Either a path or a literal. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum PathOrLit { + Path(syn::Path), + Lit(syn::Lit), +} + +impl Parse for PathOrLit { + fn parse(input: ParseStream) -> Result { + if input.fork().peek(syn::Lit) { + return input.parse::().map(PathOrLit::Lit) + } + if input.fork().peek(Ident::peek_any) || input.fork().peek(Token![::]) { + return input.call(parse_meta_path).map(PathOrLit::Path) + } + Err(input.error("cannot parse into either literal or path")) + } +} + +impl ToTokens for PathOrLit { + fn to_tokens(&self, tokens: &mut TokenStream2) { + match self { + Self::Lit(lit) => lit.to_tokens(tokens), + Self::Path(path) => path.to_tokens(tokens), + } + } +} + +impl PathOrLit { + /// Returns the value of the literal if it is a boolean literal. + pub fn as_bool(&self) -> Option { + match self { + Self::Lit(syn::Lit::Bool(lit_bool)) => Some(lit_bool.value), + _ => None, + } + } + + /// Returns the value of the literal if it is a string literal. + pub fn as_string(&self) -> Option { + match self { + Self::Lit(syn::Lit::Str(lit_str)) => Some(lit_str.value()), + _ => None, + } + } + + /// Returns the 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, + } + } +} + +/// Like [`syn::Path::parse_mod_style`] but accepts keywords in the path. +/// +/// # Note +/// +/// This code was taken from the `syn` implementation for a very similar +/// syntactical pattern. +fn parse_meta_path(input: ParseStream) -> Result { + Ok(syn::Path { + leading_colon: input.parse()?, + segments: { + let mut segments = Punctuated::new(); + while input.peek(Ident::peek_any) { + let ident = Ident::parse_any(input)?; + segments.push_value(syn::PathSegment::from(ident)); + if !input.peek(syn::Token![::]) { + break + } + let punct = input.parse()?; + segments.push_punct(punct); + } + if segments.is_empty() { + return Err(input.error("expected path")) + } else if segments.trailing_punct() { + return Err(input.error("expected path segment")) + } + segments + }, + }) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::ast::PathOrLit; + use quote::quote; + + #[test] + fn underscore_token_works() { + assert_eq!( + syn::parse2::(quote! { selector = _ }).unwrap(), + Meta::NameValue(MetaNameValue { + name: syn::parse_quote! { selector }, + eq_token: syn::parse_quote! { = }, + value: PathOrLit::Path(syn::Path::from(quote::format_ident!("_"))), + }) + ) + } +} diff --git a/crates/ink/ir/src/ast/mod.rs b/crates/ink/ir/src/ast/mod.rs index 03111cedb23..aed8b679614 100644 --- a/crates/ink/ir/src/ast/mod.rs +++ b/crates/ink/ir/src/ast/mod.rs @@ -25,9 +25,13 @@ //! the `value` part. mod attr_args; +mod meta; -pub use self::attr_args::{ - AttributeArgs, - MetaNameValue, - PathOrLit, +pub use self::{ + attr_args::AttributeArgs, + meta::{ + Meta, + MetaNameValue, + PathOrLit, + }, }; diff --git a/crates/ink/ir/src/ir/attrs.rs b/crates/ink/ir/src/ir/attrs.rs index 77e790d9d07..6aab9d28215 100644 --- a/crates/ink/ir/src/ir/attrs.rs +++ b/crates/ink/ir/src/ir/attrs.rs @@ -12,7 +12,26 @@ // See the License for the specific language governing permissions and // limitations under the License. +use core::result::Result; +use std::collections::HashMap; + +use proc_macro2::{ + Span, + TokenStream as TokenStream2, +}; +use quote::ToTokens; +use syn::{ + parse::{ + Parse, + ParseStream, + }, + punctuated::Punctuated, + spanned::Spanned, + Token, +}; + use crate::{ + ast::{self,}, error::ExtError as _, ir, ir::{ @@ -20,16 +39,6 @@ use crate::{ Selector, }, }; -use core::result::Result; -use proc_macro2::{ - Group as Group2, - Ident, - Span, - TokenStream as TokenStream2, - TokenTree as TokenTree2, -}; -use std::collections::HashMap; -use syn::spanned::Spanned; /// An extension trait for [`syn::Attribute`] in order to query for documentation. pub trait IsDocAttribute { @@ -42,19 +51,22 @@ pub trait IsDocAttribute { impl IsDocAttribute for syn::Attribute { fn is_doc_attribute(&self) -> bool { - self.path.is_ident("doc") + self.path().is_ident("doc") } fn extract_docs(&self) -> Option { if !self.is_doc_attribute() { return None } - if let Ok(syn::Meta::NameValue(syn::MetaNameValue { - lit: syn::Lit::Str(lit_str), - .. - })) = self.parse_meta() - { - return Some(lit_str.value()) + match &self.meta { + syn::Meta::NameValue(nv) => { + if let syn::Expr::Lit(l) = &nv.value { + if let syn::Lit::Str(s) = &l.lit { + return Some(s.value()) + } + } + } + _ => return None, } None } @@ -82,7 +94,7 @@ impl Attrs for syn::ImplItem { fn attrs(&self) -> &[syn::Attribute] { match self { syn::ImplItem::Const(item) => &item.attrs, - syn::ImplItem::Method(item) => &item.attrs, + syn::ImplItem::Fn(item) => &item.attrs, syn::ImplItem::Type(item) => &item.attrs, syn::ImplItem::Macro(item) => &item.attrs, _ => &[], @@ -101,7 +113,6 @@ impl Attrs for syn::Item { | Item::ForeignMod(syn::ItemForeignMod { attrs, .. }) | Item::Impl(syn::ItemImpl { attrs, .. }) | Item::Macro(syn::ItemMacro { attrs, .. }) - | Item::Macro2(syn::ItemMacro2 { attrs, .. }) | Item::Mod(syn::ItemMod { attrs, .. }) | Item::Static(syn::ItemStatic { attrs, .. }) | Item::Struct(syn::ItemStruct { attrs, .. }) @@ -139,14 +150,11 @@ pub struct InkAttribute { args: Vec, } -impl Spanned for InkAttribute { - fn span(&self) -> Span { - self.args - .iter() - .map(|arg| arg.span()) - .fold(self.first().span(), |fst, snd| { - fst.join(snd).unwrap_or_else(|| self.first().span()) - }) +impl ToTokens for InkAttribute { + fn to_tokens(&self, tokens: &mut TokenStream2) { + for arg in &self.args { + arg.to_tokens(tokens) + } } } @@ -309,8 +317,8 @@ impl InkAttribute { /// An ink! specific attribute argument. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct AttributeFrag { - pub ast: syn::Meta, - pub arg: AttributeArg, + ast: ast::Meta, + arg: AttributeArg, } impl AttributeFrag { @@ -320,9 +328,9 @@ impl AttributeFrag { } } -impl Spanned for AttributeFrag { - fn span(&self) -> Span { - self.ast.span() +impl ToTokens for AttributeFrag { + fn to_tokens(&self, tokens: &mut TokenStream2) { + self.ast.to_tokens(tokens) } } @@ -519,6 +527,50 @@ impl SelectorOrWildcard { } } +impl TryFrom<&ast::PathOrLit> for SelectorOrWildcard { + type Error = syn::Error; + + fn try_from(value: &ast::PathOrLit) -> Result { + match value { + ast::PathOrLit::Lit(lit) => { + if let syn::Lit::Str(_) = lit { + return Err(format_err_spanned!( + lit, + "#[ink(selector = ..)] attributes with string inputs are deprecated. \ + use an integer instead, e.g. #[ink(selector = 1)] or #[ink(selector = 0xC0DECAFE)]." + )); + } + if let syn::Lit::Int(lit_int) = lit { + let selector_u32 = lit_int.base10_parse::() + .map_err(|error| { + format_err_spanned!( + lit_int, + "selector value out of range. selector must be a valid `u32` integer: {}", + error + ) + })?; + let selector = Selector::from(selector_u32.to_be_bytes()); + return Ok(SelectorOrWildcard::UserProvided(selector)) + } + Err(format_err_spanned!( + value, + "expected 4-digit hexcode for `selector` argument, e.g. #[ink(selector = 0xC0FEBABE]" + )) + } + ast::PathOrLit::Path(path) => { + if path.is_ident("_") { + Ok(SelectorOrWildcard::Wildcard) + } else { + Err(format_err_spanned!( + path, + "expected `selector` argument to be either a 4-digit hexcode or `_`" + )) + } + } + } + } +} + impl core::fmt::Display for SelectorOrWildcard { fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> { match self { @@ -535,6 +587,28 @@ pub struct Namespace { bytes: Vec, } +impl TryFrom<&ast::PathOrLit> for Namespace { + type Error = syn::Error; + + fn try_from(value: &ast::PathOrLit) -> Result { + if let ast::PathOrLit::Lit(syn::Lit::Str(lit_str)) = value { + let argument = lit_str.value(); + syn::parse_str::(&argument).map_err(|_error| { + format_err_spanned!( + lit_str, + "encountered invalid Rust identifier for namespace argument", + ) + })?; + Ok(Namespace::from(argument.into_bytes())) + } else { + Err(format_err_spanned!( + value, + "expected string type for `namespace` argument, e.g. #[ink(namespace = \"hello\")]", + )) + } + } +} + impl From> for Namespace { fn from(bytes: Vec) -> Self { Self { bytes } @@ -559,7 +633,7 @@ pub fn contains_ink_attributes<'a, I>(attrs: I) -> bool where I: IntoIterator, { - attrs.into_iter().any(|attr| attr.path.is_ident("ink")) + attrs.into_iter().any(|attr| attr.path().is_ident("ink")) } /// Returns the first valid ink! attribute, if any. @@ -575,7 +649,7 @@ pub fn first_ink_attribute<'a, I>( where I: IntoIterator, { - let first = attrs.into_iter().find(|attr| attr.path.is_ident("ink")); + let first = attrs.into_iter().find(|attr| attr.path().is_ident("ink")); match first { None => Ok(None), Some(ink_attr) => InkAttribute::try_from(ink_attr.clone()).map(Some), @@ -729,7 +803,7 @@ impl TryFrom for Attribute { type Error = syn::Error; fn try_from(attr: syn::Attribute) -> Result { - if attr.path.is_ident("ink") { + if attr.path().is_ident("ink") { return >::try_from(attr).map(Into::into) } Ok(Attribute::Other(attr)) @@ -742,86 +816,27 @@ impl From for Attribute { } } -/// This function replaces occurrences of a `TokenTree::Ident` of the sequence -/// `selector = _` with the sequence `selector = "_"`. -/// -/// This is done because `syn::Attribute::parse_meta` does not support parsing a -/// verbatim like `_`. For this we would need to switch to `syn::Attribute::parse_args`, -/// which requires a more in-depth rewrite of our IR parsing. -fn transform_wildcard_selector_to_string(group: Group2) -> TokenTree2 { - let mut found_selector = false; - let mut found_equal = false; - - let new_group: TokenStream2 = group - .stream() - .into_iter() - .map(|tt| { - match tt { - TokenTree2::Group(grp) => transform_wildcard_selector_to_string(grp), - TokenTree2::Ident(ident) - if found_selector && found_equal && ident == "_" => - { - let mut lit = proc_macro2::Literal::string("_"); - lit.set_span(ident.span()); - found_selector = false; - found_equal = false; - TokenTree2::Literal(lit) - } - TokenTree2::Ident(ident) if ident == "selector" => { - found_selector = true; - TokenTree2::Ident(ident) - } - TokenTree2::Punct(punct) if punct.as_char() == '=' => { - found_equal = true; - TokenTree2::Punct(punct) - } - _ => tt, - } - }) - .collect(); - TokenTree2::Group(Group2::new(group.delimiter(), new_group)) -} - impl TryFrom for InkAttribute { type Error = syn::Error; - fn try_from(mut attr: syn::Attribute) -> Result { - if !attr.path.is_ident("ink") { + fn try_from(attr: syn::Attribute) -> Result { + if !attr.path().is_ident("ink") { return Err(format_err_spanned!(attr, "unexpected non-ink! attribute")) } - let ts: TokenStream2 = attr - .tokens + let args: Vec<_> = attr + .parse_args_with(Punctuated::::parse_terminated)? .into_iter() - .map(|tt| { - match tt { - TokenTree2::Group(grp) => transform_wildcard_selector_to_string(grp), - _ => tt, - } - }) .collect(); - attr.tokens = ts; - - match attr.parse_meta().map_err(|_| { - format_err_spanned!(attr, "unexpected ink! attribute structure") - })? { - syn::Meta::List(meta_list) => { - let args = meta_list - .nested - .into_iter() - .map(>::try_from) - .collect::, syn::Error>>()?; - Self::ensure_no_duplicate_args(&args)?; - if args.is_empty() { - return Err(format_err_spanned!( - attr, - "encountered unsupported empty ink! attribute" - )) - } - Ok(InkAttribute { args }) - } - _ => Err(format_err_spanned!(attr, "unknown ink! attribute")), + + Self::ensure_no_duplicate_args(&args)?; + if args.is_empty() { + return Err(format_err_spanned!( + attr, + "encountered unsupported empty ink! attribute" + )) } + Ok(InkAttribute { args }) } } @@ -873,153 +888,110 @@ impl InkAttribute { } } -impl TryFrom for AttributeFrag { - type Error = syn::Error; +impl Parse for AttributeFrag { + fn parse(input: ParseStream) -> syn::Result { + let ast: ast::Meta = input.parse()?; - fn try_from(nested_meta: syn::NestedMeta) -> Result { - match nested_meta { - syn::NestedMeta::Meta(meta) => { - 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 argument = lit_str.value(); - // We've pre-processed the verbatim `_` to `"_"`. This was done - // because `syn::Attribute::parse_meta` does not support verbatim. - if argument != "_" { - 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 Ok(AttributeFrag { - ast: meta, - arg: AttributeArg::Selector(SelectorOrWildcard::Wildcard), - }) - } - - if let syn::Lit::Int(lit_int) = &name_value.lit { - let selector_u32 = lit_int.base10_parse::() - .map_err(|error| { - format_err_spanned!( - lit_int, - "selector value out of range. selector must be a valid `u32` integer: {}", - error - ) - })?; - let selector = Selector::from(selector_u32.to_be_bytes()); - return Ok(AttributeFrag { - ast: meta, - arg: AttributeArg::Selector(SelectorOrWildcard::UserProvided(selector)), - }) - } - return Err(format_err!(name_value, "expected 4-digit hexcode for `selector` argument, e.g. #[ink(selector = 0xC0FEBABE]")) - } - if name_value.path.is_ident("namespace") { - if let syn::Lit::Str(lit_str) = &name_value.lit { - let argument = lit_str.value(); - syn::parse_str::(&argument) - .map_err(|_error| format_err!( - lit_str, - "encountered invalid Rust identifier for namespace argument", - ))?; - return Ok(AttributeFrag { - ast: meta, - arg: AttributeArg::Namespace( - Namespace::from(argument.into_bytes()), - ), - }) - } - return Err(format_err!(name_value, "expected string type for `namespace` argument, e.g. #[ink(namespace = \"hello\")]")) - } - if name_value.path.is_ident("extension") { - if let syn::Lit::Int(lit_int) = &name_value.lit { - let id = lit_int.base10_parse::().map_err(|parse_err| { - format_err!( - name_value, - "could not parse `N` in `#[ink(extension = N)]` into a `u32` integer", - ).into_combine(parse_err) + let arg = match &ast { + ast::Meta::NameValue(name_value) => { + let ident = name_value.name.get_ident().ok_or_else(|| { + format_err_spanned!( + name_value.name, + "expected identifier for ink! attribute argument", + ) + })?; + match ident.to_string().as_str() { + "selector" => { + SelectorOrWildcard::try_from(&name_value.value) + .map(AttributeArg::Selector) + } + "namespace" => { + Namespace::try_from(&name_value.value) + .map(AttributeArg::Namespace) + } + "extension" => { + if let Some(lit_int) = name_value.value.as_lit_int() { + let id = lit_int.base10_parse::() + .map_err(|error| { + format_err_spanned!( + lit_int, + "could not parse `N` in `#[ink(extension = N)]` into a `u32` integer: {}", error) })?; - return Ok(AttributeFrag { - ast: meta, - arg: AttributeArg::Extension( - ExtensionId::from_u32(id), - ), - }) - } - return Err(format_err!(name_value, "expected `u32` integer type for `N` in #[ink(extension = N)]")) + Ok(AttributeArg::Extension(ExtensionId::from_u32(id))) + } else { + Err(format_err_spanned!( + name_value.value, + "expected `u32` integer type for `N` in #[ink(extension = N)]", + )) } - if name_value.path.is_ident("handle_status") { - if let syn::Lit::Bool(lit_bool) = &name_value.lit { - let value = lit_bool.value; - return Ok(AttributeFrag { - ast: meta, - arg: AttributeArg::HandleStatus(value), - }) - } - return Err(format_err!(name_value, "expected `bool` value type for `flag` in #[ink(handle_status = flag)]")) - } - Err(format_err_spanned!( - meta, - "unknown ink! attribute argument (name = value)", - )) } - syn::Meta::Path(path) => { - path - .get_ident() - .map(Ident::to_string) - .ok_or_else(|| format_err_spanned!(meta, "unknown ink! attribute (path)")) - .and_then(|ident| match ident.as_str() { - "storage" => Ok(AttributeArg::Storage), - "message" => Ok(AttributeArg::Message), - "constructor" => Ok(AttributeArg::Constructor), - "event" => Ok(AttributeArg::Event), - "anonymous" => Ok(AttributeArg::Anonymous), - "topic" => Ok(AttributeArg::Topic), - "payable" => Ok(AttributeArg::Payable), - "impl" => Ok(AttributeArg::Implementation), - "selector" => Err(format_err!( - meta, - "encountered #[ink(selector)] that is missing its u32 parameter. \ - Did you mean #[ink(selector = value: u32)] ?" - )), - "namespace" => Err(format_err!( - meta, - "encountered #[ink(namespace)] that is missing its string parameter. \ - Did you mean #[ink(namespace = name: str)] ?" - )), - "extension" => Err(format_err!( - meta, - "encountered #[ink(extension)] that is missing its `id` parameter. \ - Did you mean #[ink(extension = id: u32)] ?" - )), - "handle_status" => Err(format_err!( - meta, - "encountered #[ink(handle_status)] that is missing its `flag: bool` parameter. \ - Did you mean #[ink(handle_status = flag: bool)] ?" - )), - _ => Err(format_err_spanned!( - meta, "unknown ink! attribute (path)" - )) - }) - .map(|kind| AttributeFrag { ast: meta, arg: kind, }) + "handle_status" => { + if let Some(value) = name_value.value.as_bool() { + Ok(AttributeArg::HandleStatus(value)) + } else { + Err(format_err_spanned!( + name_value.value, + "expected `bool` value type for `flag` in #[ink(handle_status = flag)]", + )) + } } - syn::Meta::List(_) => { + _ => { Err(format_err_spanned!( - meta, - "unknown ink! attribute argument (list)" + ident, + "encountered unknown ink! attribute argument: {}", + ident )) } } } - syn::NestedMeta::Lit(_) => { - Err(format_err_spanned!( - nested_meta, - "unknown ink! attribute argument (literal)" - )) + ast::Meta::Path(path) => { + let ident = path.get_ident().ok_or_else(|| { + format_err_spanned!( + path, + "expected identifier for ink! attribute argument", + ) + })?; + match ident.to_string().as_str() { + "storage" => Ok(AttributeArg::Storage), + "message" => Ok(AttributeArg::Message), + "constructor" => Ok(AttributeArg::Constructor), + "event" => Ok(AttributeArg::Event), + "anonymous" => Ok(AttributeArg::Anonymous), + "topic" => Ok(AttributeArg::Topic), + "payable" => Ok(AttributeArg::Payable), + "impl" => Ok(AttributeArg::Implementation), + _ => match ident.to_string().as_str() { + "extension" => Err(format_err_spanned!( + path, + "encountered #[ink(extension)] that is missing its `id` parameter. \ + Did you mean #[ink(extension = id: u32)] ?" + )), + "handle_status" => Err(format_err_spanned!( + path, + "encountered #[ink(handle_status)] that is missing its `flag: bool` parameter. \ + Did you mean #[ink(handle_status = flag: bool)] ?" + )), + "namespace" => Err(format_err_spanned!( + path, + "encountered #[ink(namespace)] that is missing its string parameter. \ + Did you mean #[ink(namespace = name: str)] ?" + )), + "selector" => Err(format_err_spanned!( + path, + "encountered #[ink(selector)] that is missing its u32 parameter. \ + Did you mean #[ink(selector = value: u32)] ?" + )), + _ => Err(format_err_spanned!( + path, + "encountered unknown ink! attribute argument: {}", + ident + )), + }, + } } - } + }?; + + Ok(Self { ast, arg }) } } @@ -1074,7 +1046,7 @@ mod tests { ); assert_first_ink_attribute( &[syn::parse_quote! { #[ink(invalid)] }], - Err("unknown ink! attribute (path)"), + Err("encountered unknown ink! attribute argument: invalid"), ); } @@ -1197,6 +1169,18 @@ mod tests { ); } + #[test] + fn wildcard_selector_works() { + assert_attribute_try_from( + syn::parse_quote! { + #[ink(selector = _)] + }, + Ok(test::Attribute::Ink(vec![AttributeArg::Selector( + SelectorOrWildcard::Wildcard, + )])), + ); + } + #[test] fn selector_negative_number() { assert_attribute_try_from( @@ -1306,7 +1290,7 @@ mod tests { syn::parse_quote! { #[ink(extension = -1)] }, - Err("could not parse `N` in `#[ink(extension = N)]` into a `u32` integer"), + Err("could not parse `N` in `#[ink(extension = N)]` into a `u32` integer: invalid digit found in string") ); } @@ -1317,7 +1301,7 @@ mod tests { syn::parse_quote! { #[ink(extension = #max_u32_plus_1)] }, - Err("could not parse `N` in `#[ink(extension = N)]` into a `u32` integer"), + Err("could not parse `N` in `#[ink(extension = N)]` into a `u32` integer: number too large to fit in target type"), ); } @@ -1433,7 +1417,7 @@ mod tests { syn::parse_quote! { #[ink] }, - Err("unknown ink! attribute"), + Err("expected attribute arguments in parentheses: #[ink(...)]"), ); assert_attribute_try_from( syn::parse_quote! { diff --git a/crates/ink/ir/src/ir/chain_extension.rs b/crates/ink/ir/src/ir/chain_extension.rs index cf4d46984eb..f9645bfe175 100644 --- a/crates/ink/ir/src/ir/chain_extension.rs +++ b/crates/ink/ir/src/ir/chain_extension.rs @@ -70,7 +70,7 @@ impl ChainExtension { #[derive(Debug, PartialEq, Eq)] pub struct ChainExtensionMethod { /// The underlying validated AST of the chain extension method. - item: syn::TraitItemMethod, + item: syn::TraitItemFn, /// The unique identifier of the chain extension method. id: ExtensionId, /// If `false` the `u32` status code of the chain extension method call is going to @@ -357,8 +357,8 @@ impl ChainExtension { "encountered unsupported item in ink! chain extensions" )) } - syn::TraitItem::Method(method_trait_item) => { - let method = Self::analyse_methods(method_trait_item)?; + syn::TraitItem::Fn(fn_trait_item) => { + let method = Self::analyse_methods(fn_trait_item)?; let method_id = method.id(); if let Some(previous) = seen_ids.get(&method_id) { return Err(format_err!( @@ -401,7 +401,7 @@ impl ChainExtension { /// - If the method declared as `unsafe`, `const` or `async`. /// - If the method has some explicit API. /// - If the method is variadic or has generic parameters. - fn analyse_methods(method: &syn::TraitItemMethod) -> Result { + fn analyse_methods(method: &syn::TraitItemFn) -> Result { if let Some(default_impl) = &method.default { return Err(format_err_spanned!( default_impl, @@ -470,7 +470,7 @@ impl ChainExtension { /// /// - If the chain extension method has a `self` receiver as first argument. fn analyse_chain_extension_method( - item_method: &syn::TraitItemMethod, + item_method: &syn::TraitItemFn, extension: ExtensionId, ) -> Result { let (ink_attrs, _) = ir::sanitize_attributes( @@ -740,7 +740,7 @@ mod tests { } ); assert_ink_chain_extension_eq_err!( - error: "unknown ink! attribute (path)", + error: "encountered unknown ink! attribute argument: unknown", pub trait MyChainExtension { #[ink(unknown)] fn unknown_ink_attribute(&self); @@ -751,7 +751,8 @@ mod tests { #[test] fn chain_extension_containing_method_with_invalid_marker() { assert_ink_chain_extension_eq_err!( - error: "could not parse `N` in `#[ink(extension = N)]` into a `u32` integer", + error: "could not parse `N` in `#[ink(extension = N)]` into a `u32` integer: \ + invalid digit found in string", pub trait MyChainExtension { #[ink(extension = -1)] fn has_self_receiver(); @@ -759,7 +760,8 @@ mod tests { ); let too_large = (u32::MAX as u64) + 1; assert_ink_chain_extension_eq_err!( - error: "could not parse `N` in `#[ink(extension = N)]` into a `u32` integer", + error: "could not parse `N` in `#[ink(extension = N)]` into a `u32` integer: \ + number too large to fit in target type", pub trait MyChainExtension { #[ink(extension = #too_large)] fn has_self_receiver(); diff --git a/crates/ink/ir/src/ir/item/event.rs b/crates/ink/ir/src/ir/item/event.rs index 8512693db50..476c6d40b70 100644 --- a/crates/ink/ir/src/ir/item/event.rs +++ b/crates/ink/ir/src/ir/item/event.rs @@ -108,7 +108,7 @@ impl TryFrom for Event { let some_cfg_attrs = field .attrs .iter() - .find(|attr| attr.path.is_ident(CFG_IDENT)); + .find(|attr| attr.path().is_ident(CFG_IDENT)); if some_cfg_attrs.is_some() { return Err(format_err!( field_span, diff --git a/crates/ink/ir/src/ir/item_impl/callable.rs b/crates/ink/ir/src/ir/item_impl/callable.rs index 6a5b7a76d41..e9ce9129268 100644 --- a/crates/ink/ir/src/ir/item_impl/callable.rs +++ b/crates/ink/ir/src/ir/item_impl/callable.rs @@ -365,13 +365,12 @@ where /// - Furthermore this is `true` if the externally callable is defined for a non default /// ABI (e.g. `extern "C"`) or does not have valid visibility. pub(super) fn ensure_callable_invariants( - method_item: &syn::ImplItemMethod, + method_item: &syn::ImplItemFn, kind: CallableKind, ) -> Result<(), syn::Error> { let bad_visibility = match &method_item.vis { syn::Visibility::Inherited => None, syn::Visibility::Restricted(vis_restricted) => Some(vis_restricted.span()), - syn::Visibility::Crate(vis_crate) => Some(vis_crate.span()), syn::Visibility::Public(_) => None, }; if let Some(bad_visibility) = bad_visibility { @@ -442,7 +441,7 @@ pub(super) fn ensure_callable_invariants( /// The visibility of an ink! message or constructor. #[derive(Debug, Clone)] pub enum Visibility { - Public(syn::VisPublic), + Public(syn::Token![pub]), Inherited, } @@ -567,17 +566,17 @@ mod tests { /// message result in the same composed selector as the expected bytes. fn assert_compose_selector( item_impl: syn::ItemImpl, - item_method: syn::ImplItemMethod, + item_method: syn::ImplItemFn, expected_selector: S, ) where - C: Callable + TryFrom, - >::Error: Debug, + C: Callable + TryFrom, + >::Error: Debug, S: Into, { assert_eq!( compose_selector( &>::try_from(item_impl).unwrap(), - &>::try_from(item_method).unwrap(), + &>::try_from(item_method).unwrap(), ), expected_selector.into().expected_selector(), ) diff --git a/crates/ink/ir/src/ir/item_impl/constructor.rs b/crates/ink/ir/src/ir/item_impl/constructor.rs index ae681fa21a3..bce50923a6c 100644 --- a/crates/ink/ir/src/ir/item_impl/constructor.rs +++ b/crates/ink/ir/src/ir/item_impl/constructor.rs @@ -67,7 +67,7 @@ use syn::spanned::Spanned as _; #[derive(Debug, PartialEq, Eq)] pub struct Constructor { /// The underlying Rust method item. - pub(super) item: syn::ImplItemMethod, + pub(super) item: syn::ImplItemFn, /// If the ink! constructor can receive funds. is_payable: bool, /// An optional user provided selector. @@ -94,7 +94,7 @@ impl Constructor { /// # Errors /// /// If the ink! constructor is missing a return type. - fn ensure_return(method_item: &syn::ImplItemMethod) -> Result<(), syn::Error> { + fn ensure_return(method_item: &syn::ImplItemFn) -> Result<(), syn::Error> { if let syn::ReturnType::Default = &method_item.sig.output { return Err(format_err_spanned!( &method_item.sig, @@ -112,9 +112,7 @@ impl Constructor { /// /// If the ink! constructor has a `&self`, `&mut self`, `self` or any other /// kind of a `self` receiver as first argument. - fn ensure_no_self_receiver( - method_item: &syn::ImplItemMethod, - ) -> Result<(), syn::Error> { + fn ensure_no_self_receiver(method_item: &syn::ImplItemFn) -> Result<(), syn::Error> { match method_item.sig.inputs.iter().next() { None | Some(syn::FnArg::Typed(_)) => (), Some(syn::FnArg::Receiver(receiver)) => { @@ -131,7 +129,7 @@ impl Constructor { /// /// Returns a tuple of ink! attributes and non-ink! attributes. fn sanitize_attributes( - method_item: &syn::ImplItemMethod, + method_item: &syn::ImplItemFn, ) -> Result<(ir::InkAttribute, Vec), syn::Error> { ir::sanitize_attributes( method_item.span(), @@ -149,10 +147,10 @@ impl Constructor { } } -impl TryFrom for Constructor { +impl TryFrom for Constructor { type Error = syn::Error; - fn try_from(method_item: syn::ImplItemMethod) -> Result { + fn try_from(method_item: syn::ImplItemFn) -> Result { ensure_callable_invariants(&method_item, CallableKind::Constructor)?; Self::ensure_return(&method_item)?; Self::ensure_no_self_receiver(&method_item)?; @@ -162,7 +160,7 @@ impl TryFrom for Constructor { Ok(Constructor { selector, is_payable, - item: syn::ImplItemMethod { + item: syn::ImplItemFn { attrs: other_attrs, ..method_item }, @@ -199,7 +197,7 @@ impl Callable for Constructor { fn visibility(&self) -> Visibility { match &self.item.vis { - syn::Visibility::Public(vis_public) => Visibility::Public(vis_public.clone()), + syn::Visibility::Public(vis_public) => Visibility::Public(*vis_public), syn::Visibility::Inherited => Visibility::Inherited, _ => unreachable!("encountered invalid visibility for ink! constructor"), } @@ -255,7 +253,7 @@ mod tests { ] }}; } - let test_inputs: Vec<(Vec, syn::ImplItemMethod)> = vec![ + let test_inputs: Vec<(Vec, syn::ImplItemFn)> = vec![ ( // No inputs: expected_inputs!(), @@ -294,7 +292,7 @@ mod tests { #[test] fn is_payable_works() { - let test_inputs: Vec<(bool, syn::ImplItemMethod)> = vec![ + let test_inputs: Vec<(bool, syn::ImplItemFn)> = vec![ // Not payable. ( false, @@ -340,7 +338,7 @@ mod tests { #[test] fn visibility_works() { - let test_inputs: Vec<(bool, syn::ImplItemMethod)> = vec![ + let test_inputs: Vec<(bool, syn::ImplItemFn)> = vec![ // inherited ( false, @@ -369,7 +367,7 @@ mod tests { #[test] fn try_from_works() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ // simple + inherited visibility syn::parse_quote! { #[ink(constructor)] @@ -396,7 +394,7 @@ mod tests { } } - fn assert_try_from_fails(item_method: syn::ImplItemMethod, expected_err: &str) { + fn assert_try_from_fails(item_method: syn::ImplItemFn, expected_err: &str) { assert_eq!( >::try_from(item_method) .map_err(|err| err.to_string()), @@ -406,7 +404,7 @@ mod tests { #[test] fn try_from_missing_return_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ syn::parse_quote! { #[ink(constructor)] fn my_constructor() {} @@ -423,7 +421,7 @@ mod tests { #[test] fn try_from_invalid_self_receiver_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ syn::parse_quote! { #[ink(constructor)] fn my_constructor(&self) -> Self {} @@ -451,7 +449,7 @@ mod tests { #[test] fn try_from_generics_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ syn::parse_quote! { #[ink(constructor)] fn my_constructor() -> Self {} @@ -468,7 +466,7 @@ mod tests { #[test] fn try_from_const_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ syn::parse_quote! { #[ink(constructor)] const fn my_constructor() -> Self {} @@ -485,7 +483,7 @@ mod tests { #[test] fn try_from_async_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ syn::parse_quote! { #[ink(constructor)] async fn my_constructor() -> Self {} @@ -502,7 +500,7 @@ mod tests { #[test] fn try_from_unsafe_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ syn::parse_quote! { #[ink(constructor)] unsafe fn my_constructor() -> Self {} @@ -519,7 +517,7 @@ mod tests { #[test] fn try_from_explicit_abi_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ syn::parse_quote! { #[ink(constructor)] extern "C" fn my_constructor() -> Self {} @@ -539,7 +537,7 @@ mod tests { #[test] fn try_from_variadic_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ syn::parse_quote! { #[ink(constructor)] fn my_constructor(...) -> Self {} @@ -556,10 +554,10 @@ mod tests { #[test] fn try_from_visibility_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ syn::parse_quote! { #[ink(constructor)] - crate fn my_constructor() -> Self {} + pub(crate) fn my_constructor() -> Self {} }, syn::parse_quote! { #[ink(constructor)] @@ -576,7 +574,7 @@ mod tests { #[test] fn conflicting_attributes_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ // storage syn::parse_quote! { #[ink(constructor, storage)] @@ -604,7 +602,7 @@ mod tests { #[test] fn try_from_wildcard_constructor_works() { - let item: syn::ImplItemMethod = syn::parse_quote! { + let item: syn::ImplItemFn = syn::parse_quote! { #[ink(constructor, selector = _)] pub fn my_constructor() -> Self {} }; diff --git a/crates/ink/ir/src/ir/item_impl/impl_item.rs b/crates/ink/ir/src/ir/item_impl/impl_item.rs index c04f9945f8b..38555c194bc 100644 --- a/crates/ink/ir/src/ir/item_impl/impl_item.rs +++ b/crates/ink/ir/src/ir/item_impl/impl_item.rs @@ -61,25 +61,25 @@ impl TryFrom for ImplItem { fn try_from(impl_item: syn::ImplItem) -> Result { match impl_item { - syn::ImplItem::Method(method_item) => { - if !ir::contains_ink_attributes(&method_item.attrs) { - return Ok(Self::Other(method_item.into())) + syn::ImplItem::Fn(fn_item) => { + if !ir::contains_ink_attributes(&fn_item.attrs) { + return Ok(Self::Other(fn_item.into())) } - let attr = ir::first_ink_attribute(&method_item.attrs)? + let attr = ir::first_ink_attribute(&fn_item.attrs)? .expect("missing expected ink! attribute for struct"); match attr.first().kind() { ir::AttributeArg::Message => { - >::try_from(method_item) + >::try_from(fn_item) .map(Into::into) .map(Self::Message) } ir::AttributeArg::Constructor => { - >::try_from(method_item) + >::try_from(fn_item) .map(Into::into) .map(Self::Constructor) } _ => Err(format_err_spanned!( - method_item, + fn_item, "encountered invalid ink! attribute at this point, expected either \ #[ink(message)] or #[ink(constructor) attributes" )), diff --git a/crates/ink/ir/src/ir/item_impl/message.rs b/crates/ink/ir/src/ir/item_impl/message.rs index 4f3bf80a343..3ee6c3efc7a 100644 --- a/crates/ink/ir/src/ir/item_impl/message.rs +++ b/crates/ink/ir/src/ir/item_impl/message.rs @@ -97,7 +97,7 @@ impl Receiver { #[derive(Debug, PartialEq, Eq)] pub struct Message { /// The underlying Rust method item. - pub(super) item: syn::ImplItemMethod, + pub(super) item: syn::ImplItemFn, /// If the ink! message can receive funds. is_payable: bool, /// An optional user provided selector. @@ -128,7 +128,7 @@ impl Message { /// - If the method inputs yields no elements. /// - If the first method input is not `&self` or `&mut self`. fn ensure_receiver_is_self_ref( - method_item: &syn::ImplItemMethod, + method_item: &syn::ImplItemFn, ) -> Result<(), syn::Error> { let mut fn_args = method_item.sig.inputs.iter(); fn bail(span: Span) -> syn::Error { @@ -154,9 +154,7 @@ impl Message { /// # Errors /// /// If the given Rust method has a `Self` return type. - fn ensure_not_return_self( - method_item: &syn::ImplItemMethod, - ) -> Result<(), syn::Error> { + fn ensure_not_return_self(method_item: &syn::ImplItemFn) -> Result<(), syn::Error> { match &method_item.sig.output { syn::ReturnType::Default => (), syn::ReturnType::Type(_arrow, ret_type) => { @@ -177,7 +175,7 @@ impl Message { /// /// Returns a tuple of ink! attributes and non-ink! attributes. fn sanitize_attributes( - method_item: &syn::ImplItemMethod, + method_item: &syn::ImplItemFn, ) -> Result<(ir::InkAttribute, Vec), syn::Error> { ir::sanitize_attributes( method_item.span(), @@ -195,10 +193,10 @@ impl Message { } } -impl TryFrom for Message { +impl TryFrom for Message { type Error = syn::Error; - fn try_from(method_item: syn::ImplItemMethod) -> Result { + fn try_from(method_item: syn::ImplItemFn) -> Result { ensure_callable_invariants(&method_item, CallableKind::Message)?; Self::ensure_receiver_is_self_ref(&method_item)?; Self::ensure_not_return_self(&method_item)?; @@ -208,7 +206,7 @@ impl TryFrom for Message { Ok(Self { is_payable, selector, - item: syn::ImplItemMethod { + item: syn::ImplItemFn { attrs: other_attrs, ..method_item }, @@ -245,7 +243,7 @@ impl Callable for Message { fn visibility(&self) -> Visibility { match &self.item.vis { - syn::Visibility::Public(vis_public) => Visibility::Public(vis_public.clone()), + syn::Visibility::Public(vis_public) => Visibility::Public(*vis_public), syn::Visibility::Inherited => Visibility::Inherited, _ => unreachable!("encountered invalid visibility for ink! message"), } @@ -337,7 +335,7 @@ mod tests { #[test] fn output_works() { - let test_inputs: Vec<(Option, syn::ImplItemMethod)> = vec![ + let test_inputs: Vec<(Option, syn::ImplItemFn)> = vec![ ( // No output: None, @@ -385,7 +383,7 @@ mod tests { ] }}; } - let test_inputs: Vec<(Vec, syn::ImplItemMethod)> = vec![ + let test_inputs: Vec<(Vec, syn::ImplItemFn)> = vec![ ( // No inputs: expected_inputs!(), @@ -424,7 +422,7 @@ mod tests { #[test] fn is_payable_works() { - let test_inputs: Vec<(bool, syn::ImplItemMethod)> = vec![ + let test_inputs: Vec<(bool, syn::ImplItemFn)> = vec![ // Not payable. ( false, @@ -470,7 +468,7 @@ mod tests { #[test] fn receiver_works() { - let test_inputs: Vec<(Receiver, syn::ImplItemMethod)> = vec![ + let test_inputs: Vec<(Receiver, syn::ImplItemFn)> = vec![ ( Receiver::Ref, syn::parse_quote! { @@ -496,7 +494,7 @@ mod tests { #[test] fn visibility_works() { - let test_inputs: Vec<(bool, syn::ImplItemMethod)> = vec![ + let test_inputs: Vec<(bool, syn::ImplItemFn)> = vec![ // &self ( false, @@ -541,7 +539,7 @@ mod tests { #[test] fn try_from_works() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ // &self syn::parse_quote! { #[ink(message)] @@ -588,7 +586,7 @@ mod tests { } } - fn assert_try_from_fails(item_method: syn::ImplItemMethod, expected_err: &str) { + fn assert_try_from_fails(item_method: syn::ImplItemFn, expected_err: &str) { assert_eq!( >::try_from(item_method) .map_err(|err| err.to_string()), @@ -598,7 +596,7 @@ mod tests { #[test] fn try_from_generics_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ syn::parse_quote! { #[ink(message)] fn my_message(&self) {} @@ -623,7 +621,7 @@ mod tests { #[test] fn try_from_receiver_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ syn::parse_quote! { #[ink(message)] fn my_message() {} @@ -655,7 +653,7 @@ mod tests { #[test] fn try_from_const_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ // &self syn::parse_quote! { #[ink(message)] @@ -674,7 +672,7 @@ mod tests { #[test] fn try_from_async_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ // &self syn::parse_quote! { #[ink(message)] @@ -693,7 +691,7 @@ mod tests { #[test] fn try_from_unsafe_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ // &self syn::parse_quote! { #[ink(message)] @@ -712,7 +710,7 @@ mod tests { #[test] fn try_from_explicit_abi_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ // &self syn::parse_quote! { #[ink(message)] @@ -731,7 +729,7 @@ mod tests { #[test] fn try_from_variadic_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ // &self syn::parse_quote! { #[ink(message)] @@ -750,16 +748,16 @@ mod tests { #[test] fn try_from_visibility_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ // &self + crate visibility syn::parse_quote! { #[ink(message)] - crate fn my_message(&self) {} + pub(crate) fn my_message(&self) {} }, // &mut self + crate visibility syn::parse_quote! { #[ink(message)] - crate fn my_message(&mut self) {} + pub(crate) fn my_message(&mut self) {} }, // &self + pub restricted visibility syn::parse_quote! { @@ -782,7 +780,7 @@ mod tests { #[test] fn conflicting_attributes_fails() { - let item_methods: Vec = vec![ + let item_methods: Vec = vec![ // storage syn::parse_quote! { #[ink(message, storage)] diff --git a/crates/ink/ir/src/ir/item_impl/mod.rs b/crates/ink/ir/src/ir/item_impl/mod.rs index a767c07f563..90bc9388180 100644 --- a/crates/ink/ir/src/ir/item_impl/mod.rs +++ b/crates/ink/ir/src/ir/item_impl/mod.rs @@ -74,7 +74,7 @@ pub struct ItemImpl { unsafety: Option, impl_token: syn::token::Impl, generics: syn::Generics, - trait_: Option<(Option, syn::Path, syn::token::For)>, + trait_: Option<(Option, syn::Path, syn::token::For)>, self_ty: Box, brace_token: syn::token::Brace, items: Vec, @@ -190,11 +190,11 @@ impl ItemImpl { // an ink! constructor or an ink! message: 'repeat: for item in &item_impl.items { match item { - syn::ImplItem::Method(method_item) => { - if !ir::contains_ink_attributes(&method_item.attrs) { + syn::ImplItem::Fn(fn_item) => { + if !ir::contains_ink_attributes(&fn_item.attrs) { continue 'repeat } - let attr = ir::first_ink_attribute(&method_item.attrs)? + let attr = ir::first_ink_attribute(&fn_item.attrs)? .expect("missing expected ink! attribute for struct"); match attr.first().kind() { ir::AttributeArg::Constructor | ir::AttributeArg::Message => { diff --git a/crates/ink/ir/src/ir/item_impl/tests.rs b/crates/ink/ir/src/ir/item_impl/tests.rs index d8774827554..bd10d4444f1 100644 --- a/crates/ink/ir/src/ir/item_impl/tests.rs +++ b/crates/ink/ir/src/ir/item_impl/tests.rs @@ -111,14 +111,14 @@ fn is_ink_impl_block_fails() { #[ink(invalid)] impl MyStorage {} }, - "unknown ink! attribute (path)", + "encountered unknown ink! attribute argument: invalid", ); assert_is_ink_impl_block_fails( &syn::parse_quote! { #[ink(invalid)] impl MyTrait for MyStorage {} }, - "unknown ink! attribute (path)", + "encountered unknown ink! attribute argument: invalid", ); assert_is_ink_impl_block_fails( &syn::parse_quote! { @@ -143,7 +143,7 @@ fn is_ink_impl_block_fails() { fn invalid_fn_attr(&self) {} } }, - "unknown ink! attribute (path)", + "encountered unknown ink! attribute argument: invalid", ); assert_is_ink_impl_block_fails( &syn::parse_quote! { @@ -152,7 +152,7 @@ fn is_ink_impl_block_fails() { fn invalid_fn_attr(&self) {} } }, - "unknown ink! attribute (path)", + "encountered unknown ink! attribute argument: invalid", ); } diff --git a/crates/ink/ir/src/ir/storage_item/mod.rs b/crates/ink/ir/src/ir/storage_item/mod.rs index 361a59acb04..40771c82dfb 100644 --- a/crates/ink/ir/src/ir/storage_item/mod.rs +++ b/crates/ink/ir/src/ir/storage_item/mod.rs @@ -38,7 +38,7 @@ impl StorageItem { for attr in &ast.attrs { if attr - .path + .path() .to_token_stream() .to_string() .contains("storage_item") diff --git a/crates/ink/ir/src/ir/trait_def/item/iter.rs b/crates/ink/ir/src/ir/trait_def/item/iter.rs index 0a588698dfb..dfafb5cd5aa 100644 --- a/crates/ink/ir/src/ir/trait_def/item/iter.rs +++ b/crates/ink/ir/src/ir/trait_def/item/iter.rs @@ -43,8 +43,8 @@ impl<'a> Iterator for IterInkTraitItemsRaw<'a> { 'outer: loop { match self.iter.next() { None => return None, - Some(syn::TraitItem::Method(method)) => { - let first_attr = ir::first_ink_attribute(&method.attrs) + Some(syn::TraitItem::Fn(function)) => { + let first_attr = ir::first_ink_attribute(&function.attrs) .ok() .flatten() .expect("unexpected missing ink! attribute for trait method") @@ -54,7 +54,7 @@ impl<'a> Iterator for IterInkTraitItemsRaw<'a> { match first_attr { ir::AttributeArg::Message => { return Some(InkTraitItem::Message(InkTraitMessage::new( - method, + function, ))) } _ => continue 'outer, diff --git a/crates/ink/ir/src/ir/trait_def/item/mod.rs b/crates/ink/ir/src/ir/trait_def/item/mod.rs index 3f46496e362..69b8f95b266 100644 --- a/crates/ink/ir/src/ir/trait_def/item/mod.rs +++ b/crates/ink/ir/src/ir/trait_def/item/mod.rs @@ -193,8 +193,8 @@ impl InkItemTrait { "encountered unsupported item in ink! trait definition" )) } - syn::TraitItem::Method(method_trait_item) => { - Self::analyse_trait_method(method_trait_item)?; + syn::TraitItem::Fn(fn_trait_item) => { + Self::analyse_trait_fn(fn_trait_item)?; } unknown => { return Err(format_err_spanned!( @@ -216,7 +216,7 @@ impl InkItemTrait { /// - If the method is variadic or has generic parameters. /// - If the method does not respect the properties of either an ink! message or ink! /// constructor. - fn analyse_trait_method(method: &syn::TraitItemMethod) -> Result<()> { + fn analyse_trait_fn(method: &syn::TraitItemFn) -> Result<()> { if let Some(default_impl) = &method.default { return Err(format_err_spanned!( default_impl, @@ -288,7 +288,7 @@ impl InkItemTrait { } /// Constructors are generally not allowed in ink! trait definitions. - fn analyse_trait_constructor(constructor: &syn::TraitItemMethod) -> Result<()> { + fn analyse_trait_constructor(constructor: &syn::TraitItemFn) -> Result<()> { Err(format_err!( constructor.span(), "ink! trait definitions must not have constructors", @@ -300,16 +300,16 @@ impl InkItemTrait { /// # Errors /// /// - If the message has no `&self` or `&mut self` receiver. - fn analyse_trait_message(message: &syn::TraitItemMethod) -> Result<()> { + fn analyse_trait_message(message: &syn::TraitItemFn) -> Result<()> { InkTraitMessage::extract_attributes(message.span(), &message.attrs)?; match message.sig.receiver() { - None | Some(syn::FnArg::Typed(_)) => { + None => { return Err(format_err_spanned!( - message.sig, - "missing or malformed `&self` or `&mut self` receiver for ink! message", - )) + message.sig, + "missing `&self` or `&mut self` receiver for ink! message", + )) } - Some(syn::FnArg::Receiver(receiver)) => { + Some(receiver) => { if receiver.reference.is_none() { return Err(format_err_spanned!( receiver, diff --git a/crates/ink/ir/src/ir/trait_def/item/trait_item.rs b/crates/ink/ir/src/ir/trait_def/item/trait_item.rs index e26fa295545..3740b8d4fc6 100644 --- a/crates/ink/ir/src/ir/trait_def/item/trait_item.rs +++ b/crates/ink/ir/src/ir/trait_def/item/trait_item.rs @@ -64,7 +64,7 @@ impl<'a> InkTraitItem<'a> { /// A checked ink! message of an ink! trait definition. #[derive(Debug, Clone)] pub struct InkTraitMessage<'a> { - item: &'a syn::TraitItemMethod, + item: &'a syn::TraitItemFn, } impl<'a> InkTraitMessage<'a> { @@ -73,7 +73,7 @@ impl<'a> InkTraitMessage<'a> { "encountered invalid attributes for ink! trait message"; /// Creates a new ink! trait definition message. - pub(super) fn new(item: &'a syn::TraitItemMethod) -> Self { + pub(super) fn new(item: &'a syn::TraitItemFn) -> Self { Self { item } } @@ -179,16 +179,7 @@ impl<'a> InkTraitMessage<'a> { pub fn mutates(&self) -> bool { self.sig() .receiver() - .map(|fn_arg| match fn_arg { - syn::FnArg::Receiver(receiver) if receiver.mutability.is_some() => true, - syn::FnArg::Typed(pat_type) => { - matches!( - &*pat_type.ty, - syn::Type::Reference(reference) if reference.mutability.is_some() - ) - } - _ => false, - }) + .map(|receiver| receiver.mutability.is_some()) .expect("encountered missing receiver for ink! message") } } diff --git a/crates/ink/ir/src/ir/trait_def/tests.rs b/crates/ink/ir/src/ir/trait_def/tests.rs index 47a003e31d8..8080416aa98 100644 --- a/crates/ink/ir/src/ir/trait_def/tests.rs +++ b/crates/ink/ir/src/ir/trait_def/tests.rs @@ -261,7 +261,7 @@ fn trait_def_containing_method_with_unsupported_ink_attribute_is_denied() { } ); assert_ink_trait_eq_err!( - error: "unknown ink! attribute (path)", + error: "encountered unknown ink! attribute argument: unknown", pub trait MyTrait { #[ink(unknown)] fn unknown_ink_attribute(&self); @@ -272,14 +272,14 @@ fn trait_def_containing_method_with_unsupported_ink_attribute_is_denied() { #[test] fn trait_def_containing_invalid_message_is_denied() { assert_ink_trait_eq_err!( - error: "missing or malformed `&self` or `&mut self` receiver for ink! message", + error: "missing `&self` or `&mut self` receiver for ink! message", pub trait MyTrait { #[ink(message)] fn does_not_return_self(); } ); assert_ink_trait_eq_err!( - error: "missing or malformed `&self` or `&mut self` receiver for ink! message", + error: "self receiver of ink! message must be `&self` or `&mut self`", pub trait MyTrait { #[ink(message)] fn does_not_return_self(self: &Self); diff --git a/crates/ink/ir/src/ir/utils.rs b/crates/ink/ir/src/ir/utils.rs index 30a3cad19a6..e38f5f89b8e 100644 --- a/crates/ink/ir/src/ir/utils.rs +++ b/crates/ink/ir/src/ir/utils.rs @@ -37,7 +37,6 @@ pub fn ensure_pub_visibility( let bad_visibility = match vis { syn::Visibility::Inherited => Some(parent_span), syn::Visibility::Restricted(vis_restricted) => Some(vis_restricted.span()), - syn::Visibility::Crate(vis_crate) => Some(vis_crate.span()), syn::Visibility::Public(_) => None, }; if let Some(bad_visibility) = bad_visibility { @@ -112,7 +111,7 @@ impl WhitelistedAttributes { attrs .into_iter() .filter(|attr| { - if let Some(ident) = attr.path.get_ident() { + if let Some(ident) = attr.path().get_ident() { self.0.contains_key(&ident.to_string()) } else { false @@ -174,13 +173,7 @@ pub fn extract_cfg_attributes( ) -> Vec { attrs .iter() - .filter(|a| a.path.is_ident(super::CFG_IDENT)) - .map(|a| { - a.tokens - .clone() - .into_iter() - .map(|token| quote::quote_spanned!(span=> #[cfg #token])) - .collect() - }) + .filter(|a| a.path().is_ident(super::CFG_IDENT)) + .map(|a| quote::quote_spanned!(span=> #a )) .collect() } diff --git a/crates/ink/macro/Cargo.toml b/crates/ink/macro/Cargo.toml index 42c7a3801bd..957853742d8 100644 --- a/crates/ink/macro/Cargo.toml +++ b/crates/ink/macro/Cargo.toml @@ -20,8 +20,8 @@ ink_codegen = { version = "4.1.0", path = "../codegen", default-features = false ink_primitives = { version = "4.1.0", path = "../../primitives/", default-features = false } scale = { package = "parity-scale-codec", version = "3.4", default-features = false, features = ["derive"] } -syn = "1" -synstructure = "0.12.6" +syn = "2" +synstructure = "0.13.0" proc-macro2 = "1" quote = "1" diff --git a/crates/ink/tests/ui/blake2b/fail/invalid_parameter_type_01.stderr b/crates/ink/tests/ui/blake2b/fail/invalid_parameter_type_01.stderr index d0faadef29c..9d57f51a8c2 100644 --- a/crates/ink/tests/ui/blake2b/fail/invalid_parameter_type_01.stderr +++ b/crates/ink/tests/ui/blake2b/fail/invalid_parameter_type_01.stderr @@ -1,4 +1,4 @@ -error: expected string or byte string literal as input. found Bool(LitBool { value: true }) +error: expected string or byte string literal as input. found Lit::Bool { value: true } --> tests/ui/blake2b/fail/invalid_parameter_type_01.rs:1:38 | 1 | const _: [u8; 32] = ink::blake2x256!(true); diff --git a/crates/ink/tests/ui/blake2b/fail/invalid_parameter_type_02.stderr b/crates/ink/tests/ui/blake2b/fail/invalid_parameter_type_02.stderr index c2345d0053c..7f6c1089f7a 100644 --- a/crates/ink/tests/ui/blake2b/fail/invalid_parameter_type_02.stderr +++ b/crates/ink/tests/ui/blake2b/fail/invalid_parameter_type_02.stderr @@ -1,4 +1,4 @@ -error: expected string or byte string literal as input. found Int(LitInt { token: 42 }) +error: expected string or byte string literal as input. found Lit::Int { token: 42 } --> tests/ui/blake2b/fail/invalid_parameter_type_02.rs:1:38 | 1 | const _: [u8; 32] = ink::blake2x256!(42); diff --git a/crates/ink/tests/ui/contract/fail/constructor-payable-invalid-1.stderr b/crates/ink/tests/ui/contract/fail/constructor-payable-invalid-1.stderr index 622e3c02164..dbd62bb61fa 100644 --- a/crates/ink/tests/ui/contract/fail/constructor-payable-invalid-1.stderr +++ b/crates/ink/tests/ui/contract/fail/constructor-payable-invalid-1.stderr @@ -1,5 +1,5 @@ -error: unknown ink! attribute argument (name = value) +error: encountered unknown ink! attribute argument: payable --> tests/ui/contract/fail/constructor-payable-invalid-1.rs:7:28 | 7 | #[ink(constructor, payable = true)] - | ^^^^^^^^^^^^^^ + | ^^^^^^^ diff --git a/crates/ink/tests/ui/contract/fail/constructor-payable-invalid-2.stderr b/crates/ink/tests/ui/contract/fail/constructor-payable-invalid-2.stderr index b86f7ddca81..130ef245956 100644 --- a/crates/ink/tests/ui/contract/fail/constructor-payable-invalid-2.stderr +++ b/crates/ink/tests/ui/contract/fail/constructor-payable-invalid-2.stderr @@ -1,5 +1,5 @@ -error: unknown ink! attribute argument (name = value) +error: encountered unknown ink! attribute argument: payable --> tests/ui/contract/fail/constructor-payable-invalid-2.rs:7:28 | 7 | #[ink(constructor, payable = false)] - | ^^^^^^^^^^^^^^^ + | ^^^^^^^ diff --git a/crates/ink/tests/ui/contract/fail/impl-block-namespace-invalid-type.stderr b/crates/ink/tests/ui/contract/fail/impl-block-namespace-invalid-type.stderr index 712bc1a1c92..423af44a13e 100644 --- a/crates/ink/tests/ui/contract/fail/impl-block-namespace-invalid-type.stderr +++ b/crates/ink/tests/ui/contract/fail/impl-block-namespace-invalid-type.stderr @@ -1,5 +1,5 @@ error: expected string type for `namespace` argument, e.g. #[ink(namespace = "hello")] - --> tests/ui/contract/fail/impl-block-namespace-invalid-type.rs:6:11 + --> tests/ui/contract/fail/impl-block-namespace-invalid-type.rs:6:23 | 6 | #[ink(namespace = true)] - | ^^^^^^^^^ + | ^^^^ diff --git a/crates/ink/tests/ui/contract/fail/message-selector-invalid-type-01.stderr b/crates/ink/tests/ui/contract/fail/message-selector-invalid-type-01.stderr index 967256cb73f..0e47feb6e77 100644 --- a/crates/ink/tests/ui/contract/fail/message-selector-invalid-type-01.stderr +++ b/crates/ink/tests/ui/contract/fail/message-selector-invalid-type-01.stderr @@ -1,5 +1,5 @@ error: #[ink(selector = ..)] attributes with string inputs are deprecated. use an integer instead, e.g. #[ink(selector = 1)] or #[ink(selector = 0xC0DECAFE)]. - --> tests/ui/contract/fail/message-selector-invalid-type-01.rs:12:24 + --> tests/ui/contract/fail/message-selector-invalid-type-01.rs:12:35 | 12 | #[ink(message, selector = "0xC0DECAFE")] - | ^^^^^^^^ + | ^^^^^^^^^^^^ diff --git a/crates/ink/tests/ui/contract/fail/message-selector-invalid-type-02.stderr b/crates/ink/tests/ui/contract/fail/message-selector-invalid-type-02.stderr index 9a3d99c5679..ecd9623eed0 100644 --- a/crates/ink/tests/ui/contract/fail/message-selector-invalid-type-02.stderr +++ b/crates/ink/tests/ui/contract/fail/message-selector-invalid-type-02.stderr @@ -1,5 +1,5 @@ error: expected 4-digit hexcode for `selector` argument, e.g. #[ink(selector = 0xC0FEBABE] - --> tests/ui/contract/fail/message-selector-invalid-type-02.rs:12:24 + --> tests/ui/contract/fail/message-selector-invalid-type-02.rs:12:35 | 12 | #[ink(message, selector = true)] - | ^^^^^^^^ + | ^^^^ diff --git a/crates/ink/tests/ui/contract/fail/message-unknown-property.stderr b/crates/ink/tests/ui/contract/fail/message-unknown-property.stderr index b265c0f3d16..143ef03a4b7 100644 --- a/crates/ink/tests/ui/contract/fail/message-unknown-property.stderr +++ b/crates/ink/tests/ui/contract/fail/message-unknown-property.stderr @@ -1,4 +1,4 @@ -error: unknown ink! attribute (path) +error: encountered unknown ink! attribute argument: unknown_marker --> tests/ui/contract/fail/message-unknown-property.rs:13:15 | 13 | #[ink(unknown_marker)] diff --git a/crates/ink/tests/ui/contract/fail/storage-unknown-marker.stderr b/crates/ink/tests/ui/contract/fail/storage-unknown-marker.stderr index 0741f764fd8..b3c9cbbd14d 100644 --- a/crates/ink/tests/ui/contract/fail/storage-unknown-marker.stderr +++ b/crates/ink/tests/ui/contract/fail/storage-unknown-marker.stderr @@ -1,4 +1,4 @@ -error: unknown ink! attribute (path) +error: encountered unknown ink! attribute argument: unknown_or_unsupported --> tests/ui/contract/fail/storage-unknown-marker.rs:4:11 | 4 | #[ink(unknown_or_unsupported)] diff --git a/crates/ink/tests/ui/selector_bytes/fail/invalid_parameter_type_01.stderr b/crates/ink/tests/ui/selector_bytes/fail/invalid_parameter_type_01.stderr index aa13dc96b9f..fe0da271bf0 100644 --- a/crates/ink/tests/ui/selector_bytes/fail/invalid_parameter_type_01.stderr +++ b/crates/ink/tests/ui/selector_bytes/fail/invalid_parameter_type_01.stderr @@ -1,4 +1,4 @@ -error: expected string or byte string literal as input. found Bool(LitBool { value: true }) +error: expected string or byte string literal as input. found Lit::Bool { value: true } --> tests/ui/selector_bytes/fail/invalid_parameter_type_01.rs:1:37 | 1 | const _: u32 = ink::selector_bytes!(true); diff --git a/crates/ink/tests/ui/selector_bytes/fail/invalid_parameter_type_02.stderr b/crates/ink/tests/ui/selector_bytes/fail/invalid_parameter_type_02.stderr index 5856bc7bdcd..8e9e8e70e0a 100644 --- a/crates/ink/tests/ui/selector_bytes/fail/invalid_parameter_type_02.stderr +++ b/crates/ink/tests/ui/selector_bytes/fail/invalid_parameter_type_02.stderr @@ -1,4 +1,4 @@ -error: expected string or byte string literal as input. found Int(LitInt { token: 42 }) +error: expected string or byte string literal as input. found Lit::Int { token: 42 } --> tests/ui/selector_bytes/fail/invalid_parameter_type_02.rs:1:37 | 1 | const _: u32 = ink::selector_bytes!(42); diff --git a/crates/ink/tests/ui/selector_id/fail/invalid_parameter_type_01.stderr b/crates/ink/tests/ui/selector_id/fail/invalid_parameter_type_01.stderr index de3f1b3bf24..3aece1acd61 100644 --- a/crates/ink/tests/ui/selector_id/fail/invalid_parameter_type_01.stderr +++ b/crates/ink/tests/ui/selector_id/fail/invalid_parameter_type_01.stderr @@ -1,4 +1,4 @@ -error: expected string or byte string literal as input. found Bool(LitBool { value: true }) +error: expected string or byte string literal as input. found Lit::Bool { value: true } --> tests/ui/selector_id/fail/invalid_parameter_type_01.rs:1:34 | 1 | const _: u32 = ink::selector_id!(true); diff --git a/crates/ink/tests/ui/selector_id/fail/invalid_parameter_type_02.stderr b/crates/ink/tests/ui/selector_id/fail/invalid_parameter_type_02.stderr index 0f69fbcabeb..f329a678671 100644 --- a/crates/ink/tests/ui/selector_id/fail/invalid_parameter_type_02.stderr +++ b/crates/ink/tests/ui/selector_id/fail/invalid_parameter_type_02.stderr @@ -1,4 +1,4 @@ -error: expected string or byte string literal as input. found Int(LitInt { token: 42 }) +error: expected string or byte string literal as input. found Lit::Int { token: 42 } --> tests/ui/selector_id/fail/invalid_parameter_type_02.rs:1:34 | 1 | const _: u32 = ink::selector_id!(42); diff --git a/crates/ink/tests/ui/trait_def/fail/message_payable_invalid_1.stderr b/crates/ink/tests/ui/trait_def/fail/message_payable_invalid_1.stderr index 4e073342fb0..086f7f80f3a 100644 --- a/crates/ink/tests/ui/trait_def/fail/message_payable_invalid_1.stderr +++ b/crates/ink/tests/ui/trait_def/fail/message_payable_invalid_1.stderr @@ -1,5 +1,5 @@ -error: unknown ink! attribute argument (name = value) +error: encountered unknown ink! attribute argument: payable --> tests/ui/trait_def/fail/message_payable_invalid_1.rs:3:20 | 3 | #[ink(message, payable = false)] - | ^^^^^^^^^^^^^^^ + | ^^^^^^^ diff --git a/crates/ink/tests/ui/trait_def/fail/message_payable_invalid_2.stderr b/crates/ink/tests/ui/trait_def/fail/message_payable_invalid_2.stderr index f27d313b995..1e03d584162 100644 --- a/crates/ink/tests/ui/trait_def/fail/message_payable_invalid_2.stderr +++ b/crates/ink/tests/ui/trait_def/fail/message_payable_invalid_2.stderr @@ -1,5 +1,5 @@ -error: unknown ink! attribute argument (name = value) +error: encountered unknown ink! attribute argument: payable --> tests/ui/trait_def/fail/message_payable_invalid_2.rs:3:20 | 3 | #[ink(message, payable = true)] - | ^^^^^^^^^^^^^^ + | ^^^^^^^ diff --git a/crates/ink/tests/ui/trait_def/fail/message_receiver_invalid_1.stderr b/crates/ink/tests/ui/trait_def/fail/message_receiver_invalid_1.stderr index 0fa4e3bcb25..ea0b8cec9d1 100644 --- a/crates/ink/tests/ui/trait_def/fail/message_receiver_invalid_1.stderr +++ b/crates/ink/tests/ui/trait_def/fail/message_receiver_invalid_1.stderr @@ -1,4 +1,4 @@ -error: missing or malformed `&self` or `&mut self` receiver for ink! message +error: missing `&self` or `&mut self` receiver for ink! message --> tests/ui/trait_def/fail/message_receiver_invalid_1.rs:4:5 | 4 | fn message(); diff --git a/crates/ink/tests/ui/trait_def/fail/message_receiver_invalid_2.stderr b/crates/ink/tests/ui/trait_def/fail/message_receiver_invalid_2.stderr index 94fe205b698..a09418dbd32 100644 --- a/crates/ink/tests/ui/trait_def/fail/message_receiver_invalid_2.stderr +++ b/crates/ink/tests/ui/trait_def/fail/message_receiver_invalid_2.stderr @@ -1,4 +1,4 @@ -error: missing or malformed `&self` or `&mut self` receiver for ink! message +error: missing `&self` or `&mut self` receiver for ink! message --> tests/ui/trait_def/fail/message_receiver_invalid_2.rs:4:5 | 4 | fn message(this: Self); diff --git a/crates/ink/tests/ui/trait_def/fail/message_receiver_invalid_3.stderr b/crates/ink/tests/ui/trait_def/fail/message_receiver_invalid_3.stderr index d007fb6832d..e59639c3ab8 100644 --- a/crates/ink/tests/ui/trait_def/fail/message_receiver_invalid_3.stderr +++ b/crates/ink/tests/ui/trait_def/fail/message_receiver_invalid_3.stderr @@ -1,4 +1,4 @@ -error: missing or malformed `&self` or `&mut self` receiver for ink! message +error: missing `&self` or `&mut self` receiver for ink! message --> tests/ui/trait_def/fail/message_receiver_invalid_3.rs:4:5 | 4 | fn message(this: &Self); diff --git a/crates/ink/tests/ui/trait_def/fail/message_receiver_missing.stderr b/crates/ink/tests/ui/trait_def/fail/message_receiver_missing.stderr index cfb56ed9cd0..13d3c56c3b7 100644 --- a/crates/ink/tests/ui/trait_def/fail/message_receiver_missing.stderr +++ b/crates/ink/tests/ui/trait_def/fail/message_receiver_missing.stderr @@ -1,4 +1,4 @@ -error: missing or malformed `&self` or `&mut self` receiver for ink! message +error: missing `&self` or `&mut self` receiver for ink! message --> tests/ui/trait_def/fail/message_receiver_missing.rs:4:5 | 4 | fn message(); diff --git a/crates/ink/tests/ui/trait_def/fail/message_selector_invalid_1.stderr b/crates/ink/tests/ui/trait_def/fail/message_selector_invalid_1.stderr index a50cbd6b793..0cea27e51ae 100644 --- a/crates/ink/tests/ui/trait_def/fail/message_selector_invalid_1.stderr +++ b/crates/ink/tests/ui/trait_def/fail/message_selector_invalid_1.stderr @@ -1,5 +1,5 @@ error: expected 4-digit hexcode for `selector` argument, e.g. #[ink(selector = 0xC0FEBABE] - --> tests/ui/trait_def/fail/message_selector_invalid_1.rs:3:20 + --> tests/ui/trait_def/fail/message_selector_invalid_1.rs:3:31 | 3 | #[ink(message, selector = true)] - | ^^^^^^^^ + | ^^^^ diff --git a/integration-tests/conditional-compilation/lib.rs b/integration-tests/conditional-compilation/lib.rs index 9b00af86db6..f23de5f26a6 100755 --- a/integration-tests/conditional-compilation/lib.rs +++ b/integration-tests/conditional-compilation/lib.rs @@ -55,21 +55,21 @@ pub mod conditional_compilation { } } - /// Constructor that included when `foo` is enabled + /// Constructor that is included when `foo` is enabled #[cfg(feature = "foo")] #[ink(constructor)] pub fn new_foo(value: bool) -> Self { Self { value } } - /// Constructor that included when `bar` is enabled + /// Constructor that is included when `bar` is enabled #[cfg(feature = "bar")] #[ink(constructor)] pub fn new_bar(value: bool) -> Self { Self { value } } - /// Constructor that included with either `foo` or `bar` features enabled + /// Constructor that is included with either `foo` or `bar` features enabled #[cfg(feature = "foo")] #[cfg(feature = "bar")] #[ink(constructor)]