diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ebdefce452..a0c5857479e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,11 @@ * Add support for `Option<*const T>`, `Option<*mut T>` and `NonNull`. [#3852](https://github.com/rustwasm/wasm-bindgen/pull/3852) +### Changed + +* Allow using `'static` lifetimes in functions marked with `#[wasm_bindgen]`. This does not allow references where they were not allowed before! + [#3856](https://github.com/rustwasm/wasm-bindgen/pull/3856) + ### Fixed * Make .wasm output deterministic when using `--reference-types`. diff --git a/crates/macro-support/src/parser.rs b/crates/macro-support/src/parser.rs index eee4f66e95d..5778eb50d41 100644 --- a/crates/macro-support/src/parser.rs +++ b/crates/macro-support/src/parser.rs @@ -1652,12 +1652,14 @@ fn assert_no_lifetimes(sig: &syn::Signature) -> Result<(), Diagnostic> { } impl<'ast> syn::visit::Visit<'ast> for Walk { - fn visit_lifetime(&mut self, i: &'ast syn::Lifetime) { - self.diagnostics.push(err_span!( - i, - "it is currently not sound to use lifetimes in function \ + fn visit_lifetime(&mut self, lifetime: &'ast syn::Lifetime) { + if lifetime.ident != "static" { + self.diagnostics.push(err_span!( + lifetime, + "it is currently not sound to use lifetimes in function \ signatures" - )); + )); + } } } let mut walk = Walk { diff --git a/crates/macro/ui-tests/invalid-imports-1.rs b/crates/macro/ui-tests/invalid-imports-1.rs new file mode 100644 index 00000000000..e73ab2162d3 --- /dev/null +++ b/crates/macro/ui-tests/invalid-imports-1.rs @@ -0,0 +1,41 @@ +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +extern "C" { + type A; + + #[wasm_bindgen(method)] + fn f1(); + #[wasm_bindgen(method)] + fn f2(x: u32); + #[wasm_bindgen(method)] + fn f3(x: &&u32); + #[wasm_bindgen(method)] + fn f4(x: &foo::Bar); + #[wasm_bindgen(method)] + fn f4(x: &::Bar); + #[wasm_bindgen(method)] + fn f4(x: &Bar); + #[wasm_bindgen(method)] + fn f4(x: &dyn Fn(T)); + + #[wasm_bindgen(constructor)] + fn f(); + #[wasm_bindgen(constructor)] + fn f() -> ::Bar; + #[wasm_bindgen(constructor)] + fn f() -> &Bar; + + #[wasm_bindgen(catch)] + fn f() -> u32; + #[wasm_bindgen(catch)] + fn f() -> &u32; + #[wasm_bindgen(catch)] + fn f() -> Result<>; + #[wasm_bindgen(catch)] + fn f() -> Result<'a>; + #[wasm_bindgen(catch)] + fn f() -> Result<&'static u32>; +} + +fn main() {} diff --git a/crates/macro/ui-tests/invalid-imports-1.stderr b/crates/macro/ui-tests/invalid-imports-1.stderr new file mode 100644 index 00000000000..24367ed92a9 --- /dev/null +++ b/crates/macro/ui-tests/invalid-imports-1.stderr @@ -0,0 +1,65 @@ +error: imported methods must have at least one argument + --> ui-tests/invalid-imports-1.rs:8:5 + | +8 | fn f1(); + | ^^^^^^^^ + +error: first argument of method must be a shared reference + --> ui-tests/invalid-imports-1.rs:10:14 + | +10 | fn f2(x: u32); + | ^^^ + +error: first argument of method must be a path + --> ui-tests/invalid-imports-1.rs:12:15 + | +12 | fn f3(x: &&u32); + | ^^^^ + +error: paths with type parameters are not supported yet + --> ui-tests/invalid-imports-1.rs:18:15 + | +18 | fn f4(x: &Bar); + | ^^^^^^ + +error: first argument of method must be a path + --> ui-tests/invalid-imports-1.rs:20:15 + | +20 | fn f4(x: &dyn Fn(T)); + | ^^^^^^^^^ + +error: constructor returns must be bare types + --> ui-tests/invalid-imports-1.rs:23:5 + | +23 | fn f(); + | ^^^^^^^ + +error: return value of constructor must be a bare path + --> ui-tests/invalid-imports-1.rs:27:5 + | +27 | fn f() -> &Bar; + | ^^^^^^^^^^^^^^^ + +error: must be Result<...> + --> ui-tests/invalid-imports-1.rs:30:15 + | +30 | fn f() -> u32; + | ^^^ + +error: must be Result<...> + --> ui-tests/invalid-imports-1.rs:32:15 + | +32 | fn f() -> &u32; + | ^^^^ + +error: must have at least one generic parameter + --> ui-tests/invalid-imports-1.rs:34:15 + | +34 | fn f() -> Result<>; + | ^^^^^^^^ + +error: it is currently not sound to use lifetimes in function signatures + --> ui-tests/invalid-imports-1.rs:36:22 + | +36 | fn f() -> Result<'a>; + | ^^ diff --git a/crates/macro/ui-tests/invalid-imports-2.rs b/crates/macro/ui-tests/invalid-imports-2.rs new file mode 100644 index 00000000000..5cf461dec94 --- /dev/null +++ b/crates/macro/ui-tests/invalid-imports-2.rs @@ -0,0 +1,8 @@ +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +extern "C" { + fn f() -> &'static u32; +} + +fn main() {} diff --git a/crates/macro/ui-tests/invalid-imports-2.stderr b/crates/macro/ui-tests/invalid-imports-2.stderr new file mode 100644 index 00000000000..aee456ba278 --- /dev/null +++ b/crates/macro/ui-tests/invalid-imports-2.stderr @@ -0,0 +1,5 @@ +error: cannot return references in #[wasm_bindgen] imports yet + --> ui-tests/invalid-imports-2.rs:5:15 + | +5 | fn f() -> &'static u32; + | ^^^^^^^^^^^^ diff --git a/crates/macro/ui-tests/invalid-imports.rs b/crates/macro/ui-tests/invalid-imports.rs index ceb7d33bf81..7fc9e74510a 100644 --- a/crates/macro/ui-tests/invalid-imports.rs +++ b/crates/macro/ui-tests/invalid-imports.rs @@ -36,6 +36,8 @@ extern "C" { fn f() -> Result<>; #[wasm_bindgen(catch)] fn f() -> Result<'a>; + #[wasm_bindgen(catch)] + fn f() -> Result<&'static u32>; } fn main() {} diff --git a/crates/macro/ui-tests/invalid-imports.stderr b/crates/macro/ui-tests/invalid-imports.stderr index c83c040e862..e1fbeb97ba2 100644 --- a/crates/macro/ui-tests/invalid-imports.stderr +++ b/crates/macro/ui-tests/invalid-imports.stderr @@ -1,9 +1,3 @@ -error: it is currently not sound to use lifetimes in function signatures - --> ui-tests/invalid-imports.rs:7:16 - | -7 | fn f() -> &'static u32; - | ^^^^^^^ - error: imported methods must have at least one argument --> ui-tests/invalid-imports.rs:10:5 |