diff --git a/crates/lang/ir/src/ir/attrs.rs b/crates/lang/ir/src/ir/attrs.rs index 6f50373d8f..64fa45efbb 100644 --- a/crates/lang/ir/src/ir/attrs.rs +++ b/crates/lang/ir/src/ir/attrs.rs @@ -766,11 +766,16 @@ impl TryFrom for AttributeFrag { } if name_value.path.is_ident("namespace") { if let syn::Lit::Str(lit_str) = &name_value.lit { - let bytes = lit_str.value().into_bytes(); + 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(bytes), + Namespace::from(argument.into_bytes()), ), }) } @@ -1090,6 +1095,16 @@ mod tests { ); } + #[test] + fn namespace_invalid_identifier() { + assert_attribute_try_from( + syn::parse_quote! { + #[ink(namespace = "::invalid_identifier")] + }, + Err("encountered invalid Rust identifier for namespace argument"), + ); + } + #[test] fn namespace_invalid_type() { assert_attribute_try_from( diff --git a/crates/lang/macro/tests/compile_tests.rs b/crates/lang/macro/tests/compile_tests.rs index 65b51b6cf4..fc0ea55aeb 100644 --- a/crates/lang/macro/tests/compile_tests.rs +++ b/crates/lang/macro/tests/compile_tests.rs @@ -60,5 +60,9 @@ fn compile_tests() { t.compile_fail("tests/ui/fail/S-05-storage-as-event.rs"); t.compile_fail("tests/ui/fail/S-06-event-as-storage.rs"); + t.compile_fail("tests/ui/fail/N-01-namespace-invalid-identifier.rs"); + t.compile_fail("tests/ui/fail/N-02-namespace-invalid-type.rs"); + t.compile_fail("tests/ui/fail/N-03-namespace-missing-argument.rs"); + t.pass("tests/ui/chain_extension/E-01-simple.rs"); } diff --git a/crates/lang/macro/tests/ui/fail/N-01-namespace-invalid-identifier.rs b/crates/lang/macro/tests/ui/fail/N-01-namespace-invalid-identifier.rs new file mode 100644 index 0000000000..21d08c2d3d --- /dev/null +++ b/crates/lang/macro/tests/ui/fail/N-01-namespace-invalid-identifier.rs @@ -0,0 +1,20 @@ +use ink_lang as ink; + +#[ink::contract] +mod invalid_namespace_identifier { + #[ink(storage)] + pub struct MyStorage {} + + #[ink(namespace = "::invalid_identifier")] + impl MyStorage { + #[ink(constructor)] + pub fn constructor() -> Self { + Self {} + } + + #[ink(message)] + pub fn message(&self) {} + } +} + +fn main() {} diff --git a/crates/lang/macro/tests/ui/fail/N-01-namespace-invalid-identifier.stderr b/crates/lang/macro/tests/ui/fail/N-01-namespace-invalid-identifier.stderr new file mode 100644 index 0000000000..8e3bacd08e --- /dev/null +++ b/crates/lang/macro/tests/ui/fail/N-01-namespace-invalid-identifier.stderr @@ -0,0 +1,5 @@ +error: encountered invalid Rust identifier for namespace argument + --> $DIR/N-01-namespace-invalid-identifier.rs:8:23 + | +8 | #[ink(namespace = "::invalid_identifier")] + | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/crates/lang/macro/tests/ui/fail/N-02-namespace-invalid-type.rs b/crates/lang/macro/tests/ui/fail/N-02-namespace-invalid-type.rs new file mode 100644 index 0000000000..60871df1e5 --- /dev/null +++ b/crates/lang/macro/tests/ui/fail/N-02-namespace-invalid-type.rs @@ -0,0 +1,20 @@ +use ink_lang as ink; + +#[ink::contract] +mod invalid_namespace_identifier { + #[ink(storage)] + pub struct MyStorage {} + + #[ink(namespace = true)] + impl MyStorage { + #[ink(constructor)] + pub fn constructor() -> Self { + Self {} + } + + #[ink(message)] + pub fn message(&self) {} + } +} + +fn main() {} diff --git a/crates/lang/macro/tests/ui/fail/N-02-namespace-invalid-type.stderr b/crates/lang/macro/tests/ui/fail/N-02-namespace-invalid-type.stderr new file mode 100644 index 0000000000..aed0beed38 --- /dev/null +++ b/crates/lang/macro/tests/ui/fail/N-02-namespace-invalid-type.stderr @@ -0,0 +1,5 @@ +error: expecteded string type for `namespace` argument, e.g. #[ink(namespace = "hello")] + --> $DIR/N-02-namespace-invalid-type.rs:8:11 + | +8 | #[ink(namespace = true)] + | ^^^^^^^^^^^^^^^^ diff --git a/crates/lang/macro/tests/ui/fail/N-03-namespace-missing-argument.rs b/crates/lang/macro/tests/ui/fail/N-03-namespace-missing-argument.rs new file mode 100644 index 0000000000..a4af79c249 --- /dev/null +++ b/crates/lang/macro/tests/ui/fail/N-03-namespace-missing-argument.rs @@ -0,0 +1,20 @@ +use ink_lang as ink; + +#[ink::contract] +mod invalid_namespace_identifier { + #[ink(storage)] + pub struct MyStorage {} + + #[ink(namespace)] + impl MyStorage { + #[ink(constructor)] + pub fn constructor() -> Self { + Self {} + } + + #[ink(message)] + pub fn message(&self) {} + } +} + +fn main() {} diff --git a/crates/lang/macro/tests/ui/fail/N-03-namespace-missing-argument.stderr b/crates/lang/macro/tests/ui/fail/N-03-namespace-missing-argument.stderr new file mode 100644 index 0000000000..e5298677d2 --- /dev/null +++ b/crates/lang/macro/tests/ui/fail/N-03-namespace-missing-argument.stderr @@ -0,0 +1,5 @@ +error: encountered #[ink(namespace)] that is missing its string parameter. Did you mean #[ink(namespace = name: str)] ? + --> $DIR/N-03-namespace-missing-argument.rs:8:11 + | +8 | #[ink(namespace)] + | ^^^^^^^^^