diff --git a/lang2/macro/src/ir/into_hir.rs b/lang2/macro/src/ir/into_hir.rs index 26e7512902f4e617f80c660242cc9a4e5ab3dd85..62ad7bcf30935ab70d9fdb46090248721f897626 100644 --- a/lang2/macro/src/ir/into_hir.rs +++ b/lang2/macro/src/ir/into_hir.rs @@ -422,16 +422,17 @@ impl TryFrom for ir::Function { // Followed by some checks that are depending on the given function kind: match kind { ir::FunctionKind::Constructor(_) => { + let self_arg = sig.self_arg(); if !sig.is_mut() { - bail_span!( - sig.span(), - "constructors in ink! must always be `&mut self`", + bail!( + self_arg, + "#[ink(constructor)] functions must have a `&mut self` receiver", ) } if sig.output != syn::ReturnType::Default { bail!( sig.output, - "constructors in ink! must have no specified return type", + "#[ink(constructor)] functions must not have a return type", ) } } @@ -485,7 +486,7 @@ impl TryFrom for ir::Signature { } if sig.inputs.is_empty() { bail!( - sig.inputs, + sig, "`&self` or `&mut self` is mandatory for ink! functions", ) } diff --git a/lang2/macro/tests/compile_tests.rs b/lang2/macro/tests/compile_tests.rs index 7fbd7c2c193919179629338a30fc64d5f782b8bd..bee830864c072ca86182000514fe4c08d3c0e249 100644 --- a/lang2/macro/tests/compile_tests.rs +++ b/lang2/macro/tests/compile_tests.rs @@ -30,4 +30,11 @@ fn compile_tests() { t.compile_fail("tests/ui/fail/04-missing-message.rs"); t.compile_fail("tests/ui/fail/05-forbidden-idents.rs"); t.compile_fail("tests/ui/fail/06-access-generated-fields.rs"); + t.compile_fail("tests/ui/fail/07-constructor-missing-self.rs"); + t.compile_fail("tests/ui/fail/08-constructor-self-ref.rs"); + t.compile_fail("tests/ui/fail/09-constructor-self-val.rs"); + t.compile_fail("tests/ui/fail/10-async-constructor.rs"); + t.compile_fail("tests/ui/fail/11-unsafe-constructor.rs"); + t.compile_fail("tests/ui/fail/12-const-constructor.rs"); + t.compile_fail("tests/ui/fail/13-abi-constructor.rs"); } diff --git a/lang2/macro/tests/ui/fail/01-constructor-returns.rs b/lang2/macro/tests/ui/fail/01-constructor-returns.rs index 1f7d7003fd99cca1c93e204afa43c7fac16402e4..fa06a937e0bf3f849e7d5c58b2d429e249fa1292 100644 --- a/lang2/macro/tests/ui/fail/01-constructor-returns.rs +++ b/lang2/macro/tests/ui/fail/01-constructor-returns.rs @@ -2,17 +2,14 @@ use ink_lang2 as ink; -#[ink::contract( - env = DefaultSrmlTypes, - version = "0.1.0", -)] +#[ink::contract(version = "0.1.0")] mod noop { #[ink(storage)] struct Noop {} impl Noop { #[ink(constructor)] - fn new(&mut self) -> Self {} + fn invalid_return(&mut self) -> Self {} #[ink(message)] fn noop(&self) {} diff --git a/lang2/macro/tests/ui/fail/01-constructor-returns.stderr b/lang2/macro/tests/ui/fail/01-constructor-returns.stderr index 1f26bd1e7410925817191d86a6df26a887ce80eb..4a3c89b7ca77273bfee9d76af2a541ca901ce6dc 100644 --- a/lang2/macro/tests/ui/fail/01-constructor-returns.stderr +++ b/lang2/macro/tests/ui/fail/01-constructor-returns.stderr @@ -1,5 +1,5 @@ -error: constructors in ink! must have no specified return type - --> $DIR/01-constructor-returns.rs:15:27 +error: #[ink(constructor)] functions must not have a return type + --> $DIR/01-constructor-returns.rs:12:38 | -15 | fn new(&mut self) -> Self {} - | ^^^^^^^ +12 | fn invalid_return(&mut self) -> Self {} + | ^^^^^^^ diff --git a/lang2/macro/tests/ui/fail/02-missing-constructor.rs b/lang2/macro/tests/ui/fail/02-missing-constructor.rs index 6e99e678a0b2f96d28577bc15d2ee1d5fd7a32b6..ffda0d7a4fe9c04ff0756e9ee61bc5aa6070e1f0 100644 --- a/lang2/macro/tests/ui/fail/02-missing-constructor.rs +++ b/lang2/macro/tests/ui/fail/02-missing-constructor.rs @@ -2,10 +2,7 @@ use ink_lang2 as ink; -#[ink::contract( - env = DefaultSrmlTypes, - version = "0.1.0", -)] +#[ink::contract(version = "0.1.0")] mod noop { #[ink(storage)] struct Noop {} diff --git a/lang2/macro/tests/ui/fail/02-missing-constructor.stderr b/lang2/macro/tests/ui/fail/02-missing-constructor.stderr index 211dc8a95e60c945a4e7f8eff2c9acfc63f454ec..901089845c82bd444c209cdbca2fef89b9b521f9 100644 --- a/lang2/macro/tests/ui/fail/02-missing-constructor.stderr +++ b/lang2/macro/tests/ui/fail/02-missing-constructor.stderr @@ -1,11 +1,11 @@ error: ink! contracts require at least one `#[ink(constructor)]` - --> $DIR/02-missing-constructor.rs:9:1 + --> $DIR/02-missing-constructor.rs:6:1 | -9 | / mod noop { -10 | | #[ink(storage)] -11 | | struct Noop {} -12 | | +6 | / mod noop { +7 | | #[ink(storage)] +8 | | struct Noop {} +9 | | ... | -16 | | } -17 | | } +13 | | } +14 | | } | |_^ diff --git a/lang2/macro/tests/ui/fail/07-constructor-missing-self.rs b/lang2/macro/tests/ui/fail/07-constructor-missing-self.rs new file mode 100644 index 0000000000000000000000000000000000000000..e66a2b54324b263dbc8ebe67f09c3cbf77764954 --- /dev/null +++ b/lang2/macro/tests/ui/fail/07-constructor-missing-self.rs @@ -0,0 +1,19 @@ +#![feature(proc_macro_hygiene)] + +use ink_lang2 as ink; + +#[ink::contract(version = "0.1.0")] +mod noop { + #[ink(storage)] + struct Noop {} + + impl Noop { + #[ink(constructor)] + fn invalid_self_val() {} + + #[ink(message)] + fn noop(&self) {} + } +} + +fn main() {} diff --git a/lang2/macro/tests/ui/fail/07-constructor-missing-self.stderr b/lang2/macro/tests/ui/fail/07-constructor-missing-self.stderr new file mode 100644 index 0000000000000000000000000000000000000000..e070ad6288c8a442308987ba629d163d7cdd0558 --- /dev/null +++ b/lang2/macro/tests/ui/fail/07-constructor-missing-self.stderr @@ -0,0 +1,5 @@ +error: `&self` or `&mut self` is mandatory for ink! functions + --> $DIR/07-constructor-missing-self.rs:12:9 + | +12 | fn invalid_self_val() {} + | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/lang2/macro/tests/ui/fail/08-constructor-self-ref.rs b/lang2/macro/tests/ui/fail/08-constructor-self-ref.rs new file mode 100644 index 0000000000000000000000000000000000000000..e50847f26cde97161288407250b1b283f0e1a791 --- /dev/null +++ b/lang2/macro/tests/ui/fail/08-constructor-self-ref.rs @@ -0,0 +1,19 @@ +#![feature(proc_macro_hygiene)] + +use ink_lang2 as ink; + +#[ink::contract(version = "0.1.0")] +mod noop { + #[ink(storage)] + struct Noop {} + + impl Noop { + #[ink(constructor)] + fn invalid_self_ref(&self) {} + + #[ink(message)] + fn noop(&self) {} + } +} + +fn main() {} diff --git a/lang2/macro/tests/ui/fail/08-constructor-self-ref.stderr b/lang2/macro/tests/ui/fail/08-constructor-self-ref.stderr new file mode 100644 index 0000000000000000000000000000000000000000..bb4d27869b93f6c4075003fb9285bd071ad642dd --- /dev/null +++ b/lang2/macro/tests/ui/fail/08-constructor-self-ref.stderr @@ -0,0 +1,5 @@ +error: #[ink(constructor)] functions must have a `&mut self` receiver + --> $DIR/08-constructor-self-ref.rs:12:29 + | +12 | fn invalid_self_ref(&self) {} + | ^^^^^ diff --git a/lang2/macro/tests/ui/fail/09-constructor-self-val.rs b/lang2/macro/tests/ui/fail/09-constructor-self-val.rs new file mode 100644 index 0000000000000000000000000000000000000000..d35854ab683119ac30d3fbf98d3885148a8d39dd --- /dev/null +++ b/lang2/macro/tests/ui/fail/09-constructor-self-val.rs @@ -0,0 +1,19 @@ +#![feature(proc_macro_hygiene)] + +use ink_lang2 as ink; + +#[ink::contract(version = "0.1.0")] +mod noop { + #[ink(storage)] + struct Noop {} + + impl Noop { + #[ink(constructor)] + fn invalid_self_val(self) {} + + #[ink(message)] + fn noop(&self) {} + } +} + +fn main() {} diff --git a/lang2/macro/tests/ui/fail/09-constructor-self-val.stderr b/lang2/macro/tests/ui/fail/09-constructor-self-val.stderr new file mode 100644 index 0000000000000000000000000000000000000000..3863a31ce22ef47fd09f74d9eaa8375a3ad39abb --- /dev/null +++ b/lang2/macro/tests/ui/fail/09-constructor-self-val.stderr @@ -0,0 +1,5 @@ +error: #[ink(constructor)] functions must have a `&mut self` receiver + --> $DIR/09-constructor-self-val.rs:12:29 + | +12 | fn invalid_self_val(self) {} + | ^^^^ diff --git a/lang2/macro/tests/ui/fail/10-async-constructor.rs b/lang2/macro/tests/ui/fail/10-async-constructor.rs new file mode 100644 index 0000000000000000000000000000000000000000..e08de4695365fa132724451381540abddc5cb618 --- /dev/null +++ b/lang2/macro/tests/ui/fail/10-async-constructor.rs @@ -0,0 +1,19 @@ +#![feature(proc_macro_hygiene)] + +use ink_lang2 as ink; + +#[ink::contract(version = "0.1.0")] +mod noop { + #[ink(storage)] + struct Noop {} + + impl Noop { + #[ink(constructor)] + async fn invalid_return(&mut self) {} + + #[ink(message)] + fn noop(&self) {} + } +} + +fn main() {} diff --git a/lang2/macro/tests/ui/fail/10-async-constructor.stderr b/lang2/macro/tests/ui/fail/10-async-constructor.stderr new file mode 100644 index 0000000000000000000000000000000000000000..3fd615ac2ba727bb309ff1dedb154ce9de9847f2 --- /dev/null +++ b/lang2/macro/tests/ui/fail/10-async-constructor.stderr @@ -0,0 +1,5 @@ +error: `async fn` is not supported for ink! functions + --> $DIR/10-async-constructor.rs:12:9 + | +12 | async fn invalid_return(&mut self) {} + | ^^^^^ diff --git a/lang2/macro/tests/ui/fail/11-unsafe-constructor.rs b/lang2/macro/tests/ui/fail/11-unsafe-constructor.rs new file mode 100644 index 0000000000000000000000000000000000000000..8cdffa82a31f0ca2acbebb26fcf2852f56f6b89d --- /dev/null +++ b/lang2/macro/tests/ui/fail/11-unsafe-constructor.rs @@ -0,0 +1,19 @@ +#![feature(proc_macro_hygiene)] + +use ink_lang2 as ink; + +#[ink::contract(version = "0.1.0")] +mod noop { + #[ink(storage)] + struct Noop {} + + impl Noop { + #[ink(constructor)] + unsafe fn invalid_return(&mut self) {} + + #[ink(message)] + fn noop(&self) {} + } +} + +fn main() {} diff --git a/lang2/macro/tests/ui/fail/11-unsafe-constructor.stderr b/lang2/macro/tests/ui/fail/11-unsafe-constructor.stderr new file mode 100644 index 0000000000000000000000000000000000000000..777681372b7dc84cf0cca291af11a0397b4a9773 --- /dev/null +++ b/lang2/macro/tests/ui/fail/11-unsafe-constructor.stderr @@ -0,0 +1,5 @@ +error: `unsafe fn` is not supported for ink! functions + --> $DIR/11-unsafe-constructor.rs:12:9 + | +12 | unsafe fn invalid_return(&mut self) {} + | ^^^^^^ diff --git a/lang2/macro/tests/ui/fail/12-const-constructor.rs b/lang2/macro/tests/ui/fail/12-const-constructor.rs new file mode 100644 index 0000000000000000000000000000000000000000..b45992ed230c7a598c3657c8c5f50650a38db499 --- /dev/null +++ b/lang2/macro/tests/ui/fail/12-const-constructor.rs @@ -0,0 +1,19 @@ +#![feature(proc_macro_hygiene)] + +use ink_lang2 as ink; + +#[ink::contract(version = "0.1.0")] +mod noop { + #[ink(storage)] + struct Noop {} + + impl Noop { + #[ink(constructor)] + const fn invalid_return(&mut self) {} + + #[ink(message)] + fn noop(&self) {} + } +} + +fn main() {} diff --git a/lang2/macro/tests/ui/fail/12-const-constructor.stderr b/lang2/macro/tests/ui/fail/12-const-constructor.stderr new file mode 100644 index 0000000000000000000000000000000000000000..8332d031f7073c1e6cf3d9974712d6a966ac17ae --- /dev/null +++ b/lang2/macro/tests/ui/fail/12-const-constructor.stderr @@ -0,0 +1,5 @@ +error: `const fn` is not supported for ink! functions + --> $DIR/12-const-constructor.rs:12:9 + | +12 | const fn invalid_return(&mut self) {} + | ^^^^^ diff --git a/lang2/macro/tests/ui/fail/13-abi-constructor.rs b/lang2/macro/tests/ui/fail/13-abi-constructor.rs new file mode 100644 index 0000000000000000000000000000000000000000..29be38b981d147ff92766883eea8f9baad68a2b5 --- /dev/null +++ b/lang2/macro/tests/ui/fail/13-abi-constructor.rs @@ -0,0 +1,19 @@ +#![feature(proc_macro_hygiene)] + +use ink_lang2 as ink; + +#[ink::contract(version = "0.1.0")] +mod noop { + #[ink(storage)] + struct Noop {} + + impl Noop { + #[ink(constructor)] + extern "C" fn invalid_return(&mut self) {} + + #[ink(message)] + fn noop(&self) {} + } +} + +fn main() {} diff --git a/lang2/macro/tests/ui/fail/13-abi-constructor.stderr b/lang2/macro/tests/ui/fail/13-abi-constructor.stderr new file mode 100644 index 0000000000000000000000000000000000000000..0a06f766b5371a830abd6c5a6d0a67ba7fdda4b5 --- /dev/null +++ b/lang2/macro/tests/ui/fail/13-abi-constructor.stderr @@ -0,0 +1,5 @@ +error: specifying ABI is not allowed in ink! functions + --> $DIR/13-abi-constructor.rs:12:9 + | +12 | extern "C" fn invalid_return(&mut self) {} + | ^^^^^^^^^^