From ad495c9bf274cbf280938330a8255bbbb7307a44 Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Mon, 18 Nov 2024 19:54:21 +0100 Subject: [PATCH 01/21] Make `getter`s, `setter`s, and `constructor`s compiler errors for enums --- crates/backend/src/codegen.rs | 51 +++++++++++-- crates/macro/ui-tests/unsupported-options.rs | 73 ++++++++++++++++++ .../macro/ui-tests/unsupported-options.stderr | 75 +++++++++++++++++++ src/lib.rs | 7 +- src/marker.rs | 58 ++++++++++++++ 5 files changed, 256 insertions(+), 8 deletions(-) create mode 100644 crates/macro/ui-tests/unsupported-options.rs create mode 100644 crates/macro/ui-tests/unsupported-options.stderr create mode 100644 src/marker.rs diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index 0cb52f3472c..c36bb10f703 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -224,6 +224,13 @@ impl ToTokens for ast::Struct { let unwrap_fn = Ident::new(&shared::unwrap_function(&name_str), Span::call_site()); let wasm_bindgen = &self.wasm_bindgen; (quote! { + #[automatically_derived] + impl #wasm_bindgen::marker::SupportsConstructor for #name {} + #[automatically_derived] + impl #wasm_bindgen::marker::SupportsInstanceProperty for #name {} + #[automatically_derived] + impl #wasm_bindgen::marker::SupportsStaticProperty for #name {} + #[automatically_derived] impl #wasm_bindgen::describe::WasmDescribe for #name { fn describe() { @@ -780,12 +787,43 @@ impl TryToTokens for ast::Export { let nargs = self.function.arguments.len() as u32; let attrs = &self.function.rust_attrs; - let start_check = if self.start { - quote! { const _ASSERT: fn() = || -> #projection::Abi { loop {} }; } - } else { - quote! {} + let mut checks = Vec::new(); + if self.start { + checks.push(quote! { const _ASSERT: fn() = || -> #projection::Abi { loop {} }; }); }; + if let Some(class) = self.rust_class.as_ref() { + // change span of class, so it points to the location of the + // function causing the assert to fail + let mut class = class.clone(); + class.set_span(self.rust_name.span()); + + match &self.method_kind { + ast::MethodKind::Constructor => { + checks.push(quote! { + const fn assert_supports_constructor() {} + assert_supports_constructor::<#class>(); + }); + } + ast::MethodKind::Operation(operation) => match operation.kind { + ast::OperationKind::Getter(_) | ast::OperationKind::Setter(_) => { + if operation.is_static { + checks.push(quote! { + const fn assert_supports_static_property() {} + assert_supports_static_property::<#class>(); + }); + } else { + checks.push(quote! { + const fn assert_supports_instance_property() {} + assert_supports_instance_property::<#class>(); + }); + } + } + _ => {} + }, + } + } + (quote! { #[automatically_derived] const _: () = { @@ -796,7 +834,10 @@ impl TryToTokens for ast::Export { )] #[cfg_attr(wasm_bindgen_unstable_test_coverage, coverage(off))] pub unsafe extern "C" fn #generated_name(#(#args),*) -> #wasm_bindgen::convert::WasmRet<#projection::Abi> { - #start_check + #[automatically_derived] + const _: () = { + #(#checks)* + }; let #ret = #call; #convert_ret diff --git a/crates/macro/ui-tests/unsupported-options.rs b/crates/macro/ui-tests/unsupported-options.rs new file mode 100644 index 00000000000..b9167dd821a --- /dev/null +++ b/crates/macro/ui-tests/unsupported-options.rs @@ -0,0 +1,73 @@ +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub struct RustStruct { + data: u32, +} + +#[wasm_bindgen] +impl RustStruct { + pub fn instance_method(&self) {} + fn priv_instance_method(&self) {} + + #[wasm_bindgen(constructor)] + pub fn new() -> Self { + Self { data: 0 } + } + + #[wasm_bindgen(getter)] + pub fn prop(self) -> u32 { + 32 + } + #[wasm_bindgen(setter)] + pub fn set_prop(self, _value: u32) {} + + #[wasm_bindgen(getter)] + pub fn static_prop() -> u32 { + 32 + } + #[wasm_bindgen(setter)] + pub fn set_static_prop(_value: u32) {} + + #[wasm_bindgen(indexing_getter)] + pub fn indexing_getter(self) -> u32 { + 32 + } + #[wasm_bindgen(indexing_setter)] + pub fn indexing_setter(self, _value: u32) {} + #[wasm_bindgen(indexing_deleter)] + pub fn indexing_deleter(self, _value: u32) {} +} + +#[wasm_bindgen] +pub enum RustEnum { + A = 0, + B = 1, +} + +#[wasm_bindgen] +impl RustEnum { + pub fn instance_method(self) {} + fn priv_instance_method(self) {} + + #[wasm_bindgen(constructor)] + pub fn new() -> Self { + Self::A + } + + #[wasm_bindgen(getter)] + pub fn prop(self) -> u32 { + 32 + } + #[wasm_bindgen(setter)] + pub fn set_prop(self, _value: u32) {} + + #[wasm_bindgen(getter)] + pub fn static_prop() -> u32 { + 32 + } + #[wasm_bindgen(setter)] + pub fn set_static_prop(_value: u32) {} +} + +fn main() {} diff --git a/crates/macro/ui-tests/unsupported-options.stderr b/crates/macro/ui-tests/unsupported-options.stderr new file mode 100644 index 00000000000..24f2ac55389 --- /dev/null +++ b/crates/macro/ui-tests/unsupported-options.stderr @@ -0,0 +1,75 @@ +error[E0277]: JavaScript constructors are not supported for `RustEnum` + --> ui-tests/unsupported-options.rs:54:12 + | +54 | pub fn new() -> Self { + | ^^^ the trait `SupportsConstructor` is not implemented for `RustEnum` + | + = note: `#[wasm_bindgen(constructor)]` is generally only supported for `struct`s with `#[wasm_bindgen]` and cannot be used for `enum`s. + = note: Consider removing the `constructor` option and using a regular static method instead. + = help: the trait `SupportsConstructor` is implemented for `RustStruct` +note: required by a bound in `__wasm_bindgen_generated_RustEnum_new::_::assert_supports_constructor` + --> ui-tests/unsupported-options.rs:48:1 + | +48 | #[wasm_bindgen] + | ^^^^^^^^^^^^^^^ required by this bound in `assert_supports_constructor` + = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: JavaScript instance getters and setters are not supported for `RustEnum` + --> ui-tests/unsupported-options.rs:59:12 + | +59 | pub fn prop(self) -> u32 { + | ^^^^ the trait `SupportsInstanceProperty` is not implemented for `RustEnum` + | + = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. + = help: the trait `SupportsInstanceProperty` is implemented for `RustStruct` +note: required by a bound in `__wasm_bindgen_generated_RustEnum_prop::_::assert_supports_instance_property` + --> ui-tests/unsupported-options.rs:48:1 + | +48 | #[wasm_bindgen] + | ^^^^^^^^^^^^^^^ required by this bound in `assert_supports_instance_property` + = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: JavaScript instance getters and setters are not supported for `RustEnum` + --> ui-tests/unsupported-options.rs:63:12 + | +63 | pub fn set_prop(self, _value: u32) {} + | ^^^^^^^^ the trait `SupportsInstanceProperty` is not implemented for `RustEnum` + | + = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. + = help: the trait `SupportsInstanceProperty` is implemented for `RustStruct` +note: required by a bound in `__wasm_bindgen_generated_RustEnum_set_prop::_::assert_supports_instance_property` + --> ui-tests/unsupported-options.rs:48:1 + | +48 | #[wasm_bindgen] + | ^^^^^^^^^^^^^^^ required by this bound in `assert_supports_instance_property` + = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: JavaScript static getters and setters are not supported for `RustEnum` + --> ui-tests/unsupported-options.rs:66:12 + | +66 | pub fn static_prop() -> u32 { + | ^^^^^^^^^^^ the trait `SupportsStaticProperty` is not implemented for `RustEnum` + | + = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. + = help: the trait `SupportsStaticProperty` is implemented for `RustStruct` +note: required by a bound in `__wasm_bindgen_generated_RustEnum_static_prop::_::assert_supports_static_property` + --> ui-tests/unsupported-options.rs:48:1 + | +48 | #[wasm_bindgen] + | ^^^^^^^^^^^^^^^ required by this bound in `assert_supports_static_property` + = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: JavaScript static getters and setters are not supported for `RustEnum` + --> ui-tests/unsupported-options.rs:70:12 + | +70 | pub fn set_static_prop(_value: u32) {} + | ^^^^^^^^^^^^^^^ the trait `SupportsStaticProperty` is not implemented for `RustEnum` + | + = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. + = help: the trait `SupportsStaticProperty` is implemented for `RustStruct` +note: required by a bound in `__wasm_bindgen_generated_RustEnum_set_static_prop::_::assert_supports_static_property` + --> ui-tests/unsupported-options.rs:48:1 + | +48 | #[wasm_bindgen] + | ^^^^^^^^^^^^^^^ required by this bound in `assert_supports_static_property` + = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/lib.rs b/src/lib.rs index 6c6961cf942..3bec96d3a4c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,7 +16,7 @@ use alloc::boxed::Box; use alloc::string::String; use alloc::vec::Vec; use core::convert::TryFrom; -use core::marker; +use core::marker::PhantomData; use core::mem; use core::ops::{ Add, BitAnd, BitOr, BitXor, Deref, DerefMut, Div, Mul, Neg, Not, Rem, Shl, Shr, Sub, @@ -71,6 +71,7 @@ pub use wasm_bindgen_macro::link_to; pub mod closure; pub mod convert; pub mod describe; +pub mod marker; mod link; mod cast; @@ -92,7 +93,7 @@ if_std! { /// but for now it may be slightly slow. pub struct JsValue { idx: u32, - _marker: marker::PhantomData<*mut u8>, // not at all threadsafe + _marker: PhantomData<*mut u8>, // not at all threadsafe } const JSIDX_OFFSET: u32 = 128; // keep in sync with js/mod.rs @@ -119,7 +120,7 @@ impl JsValue { const fn _new(idx: u32) -> JsValue { JsValue { idx, - _marker: marker::PhantomData, + _marker: PhantomData, } } diff --git a/src/marker.rs b/src/marker.rs new file mode 100644 index 00000000000..509b5f9e15c --- /dev/null +++ b/src/marker.rs @@ -0,0 +1,58 @@ +//! This module contains marker traits used by `wasm-bindgen` to verify its +//! generated code. +//! +//! # ⚠️ Unstable +//! +//! This is an internal module, no stability guarantees are provided. Use at +//! your own risk. + +/// Marker trait for types that support `#[wasm_bindgen(constructor)]`. +/// +/// **DO NOT** implement this trait manually. It is implemented automatically +/// for types that support constructors. +/// +/// # ⚠️ Unstable +/// +/// This is part of the internal [`convert`](crate::marker) module, **no +/// stability guarantees** are provided. Use at your own risk. See its +/// documentation for more details. +#[diagnostic::on_unimplemented( + message = "JavaScript constructors are not supported for `{Self}`", + note = "`#[wasm_bindgen(constructor)]` is generally only supported for `struct`s with `#[wasm_bindgen]` and cannot be used for `enum`s.", + note = "Consider removing the `constructor` option and using a regular static method instead.", +)] +pub trait SupportsConstructor {} + +/// Marker trait for types that support `#[wasm_bindgen(getter)]` or +/// `#[wasm_bindgen(Setter)]` on instance methods. +/// +/// **DO NOT** implement this trait manually. It is implemented automatically +/// for types that support instance properties. +/// +/// # ⚠️ Unstable +/// +/// This is part of the internal [`convert`](crate::marker) module, **no +/// stability guarantees** are provided. Use at your own risk. See its +/// documentation for more details. +#[diagnostic::on_unimplemented( + message = "JavaScript instance getters and setters are not supported for `{Self}`", + note = "`#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s.", +)] +pub trait SupportsInstanceProperty {} + +/// Marker trait for types that support `#[wasm_bindgen(getter)]` or +/// `#[wasm_bindgen(Setter)]` on static methods. +/// +/// **DO NOT** implement this trait manually. It is implemented automatically +/// for types that support static properties. +/// +/// # ⚠️ Unstable +/// +/// This is part of the internal [`convert`](crate::marker) module, **no +/// stability guarantees** are provided. Use at your own risk. See its +/// documentation for more details. +#[diagnostic::on_unimplemented( + message = "JavaScript static getters and setters are not supported for `{Self}`", + note = "`#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s.", +)] +pub trait SupportsStaticProperty {} From e967962e18fe38bb3d1b7ff90a5b5865f542942f Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Mon, 18 Nov 2024 20:16:39 +0100 Subject: [PATCH 02/21] Better error messages --- crates/macro/ui-tests/unsupported-options.rs | 9 +++ .../macro/ui-tests/unsupported-options.stderr | 55 ++++++++++--------- src/marker.rs | 9 ++- 3 files changed, 45 insertions(+), 28 deletions(-) diff --git a/crates/macro/ui-tests/unsupported-options.rs b/crates/macro/ui-tests/unsupported-options.rs index b9167dd821a..1589027f30c 100644 --- a/crates/macro/ui-tests/unsupported-options.rs +++ b/crates/macro/ui-tests/unsupported-options.rs @@ -9,6 +9,7 @@ pub struct RustStruct { impl RustStruct { pub fn instance_method(&self) {} fn priv_instance_method(&self) {} + pub fn static_method() {} #[wasm_bindgen(constructor)] pub fn new() -> Self { @@ -49,6 +50,7 @@ pub enum RustEnum { impl RustEnum { pub fn instance_method(self) {} fn priv_instance_method(self) {} + pub fn static_method() {} #[wasm_bindgen(constructor)] pub fn new() -> Self { @@ -70,4 +72,11 @@ impl RustEnum { pub fn set_static_prop(_value: u32) {} } +pub struct NonWasmType; + +#[wasm_bindgen] +impl NonWasmType { + pub fn static_method() {} +} + fn main() {} diff --git a/crates/macro/ui-tests/unsupported-options.stderr b/crates/macro/ui-tests/unsupported-options.stderr index 24f2ac55389..e411e051cc6 100644 --- a/crates/macro/ui-tests/unsupported-options.stderr +++ b/crates/macro/ui-tests/unsupported-options.stderr @@ -1,75 +1,80 @@ error[E0277]: JavaScript constructors are not supported for `RustEnum` - --> ui-tests/unsupported-options.rs:54:12 + --> ui-tests/unsupported-options.rs:56:12 | -54 | pub fn new() -> Self { - | ^^^ the trait `SupportsConstructor` is not implemented for `RustEnum` +56 | pub fn new() -> Self { + | ^^^ this function cannot be the constructor of `RustEnum` | + = help: the trait `SupportsConstructor` is not implemented for `RustEnum` = note: `#[wasm_bindgen(constructor)]` is generally only supported for `struct`s with `#[wasm_bindgen]` and cannot be used for `enum`s. = note: Consider removing the `constructor` option and using a regular static method instead. = help: the trait `SupportsConstructor` is implemented for `RustStruct` note: required by a bound in `__wasm_bindgen_generated_RustEnum_new::_::assert_supports_constructor` - --> ui-tests/unsupported-options.rs:48:1 + --> ui-tests/unsupported-options.rs:49:1 | -48 | #[wasm_bindgen] +49 | #[wasm_bindgen] | ^^^^^^^^^^^^^^^ required by this bound in `assert_supports_constructor` = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: JavaScript instance getters and setters are not supported for `RustEnum` - --> ui-tests/unsupported-options.rs:59:12 + --> ui-tests/unsupported-options.rs:61:12 | -59 | pub fn prop(self) -> u32 { - | ^^^^ the trait `SupportsInstanceProperty` is not implemented for `RustEnum` +61 | pub fn prop(self) -> u32 { + | ^^^^ this method cannot be a getter or setter for `RustEnum` | + = help: the trait `SupportsInstanceProperty` is not implemented for `RustEnum` = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. = help: the trait `SupportsInstanceProperty` is implemented for `RustStruct` note: required by a bound in `__wasm_bindgen_generated_RustEnum_prop::_::assert_supports_instance_property` - --> ui-tests/unsupported-options.rs:48:1 + --> ui-tests/unsupported-options.rs:49:1 | -48 | #[wasm_bindgen] +49 | #[wasm_bindgen] | ^^^^^^^^^^^^^^^ required by this bound in `assert_supports_instance_property` = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: JavaScript instance getters and setters are not supported for `RustEnum` - --> ui-tests/unsupported-options.rs:63:12 + --> ui-tests/unsupported-options.rs:65:12 | -63 | pub fn set_prop(self, _value: u32) {} - | ^^^^^^^^ the trait `SupportsInstanceProperty` is not implemented for `RustEnum` +65 | pub fn set_prop(self, _value: u32) {} + | ^^^^^^^^ this method cannot be a getter or setter for `RustEnum` | + = help: the trait `SupportsInstanceProperty` is not implemented for `RustEnum` = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. = help: the trait `SupportsInstanceProperty` is implemented for `RustStruct` note: required by a bound in `__wasm_bindgen_generated_RustEnum_set_prop::_::assert_supports_instance_property` - --> ui-tests/unsupported-options.rs:48:1 + --> ui-tests/unsupported-options.rs:49:1 | -48 | #[wasm_bindgen] +49 | #[wasm_bindgen] | ^^^^^^^^^^^^^^^ required by this bound in `assert_supports_instance_property` = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: JavaScript static getters and setters are not supported for `RustEnum` - --> ui-tests/unsupported-options.rs:66:12 + --> ui-tests/unsupported-options.rs:68:12 | -66 | pub fn static_prop() -> u32 { - | ^^^^^^^^^^^ the trait `SupportsStaticProperty` is not implemented for `RustEnum` +68 | pub fn static_prop() -> u32 { + | ^^^^^^^^^^^ this static function cannot be a static getter or setter on `RustEnum` | + = help: the trait `SupportsStaticProperty` is not implemented for `RustEnum` = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. = help: the trait `SupportsStaticProperty` is implemented for `RustStruct` note: required by a bound in `__wasm_bindgen_generated_RustEnum_static_prop::_::assert_supports_static_property` - --> ui-tests/unsupported-options.rs:48:1 + --> ui-tests/unsupported-options.rs:49:1 | -48 | #[wasm_bindgen] +49 | #[wasm_bindgen] | ^^^^^^^^^^^^^^^ required by this bound in `assert_supports_static_property` = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: JavaScript static getters and setters are not supported for `RustEnum` - --> ui-tests/unsupported-options.rs:70:12 + --> ui-tests/unsupported-options.rs:72:12 | -70 | pub fn set_static_prop(_value: u32) {} - | ^^^^^^^^^^^^^^^ the trait `SupportsStaticProperty` is not implemented for `RustEnum` +72 | pub fn set_static_prop(_value: u32) {} + | ^^^^^^^^^^^^^^^ this static function cannot be a static getter or setter on `RustEnum` | + = help: the trait `SupportsStaticProperty` is not implemented for `RustEnum` = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. = help: the trait `SupportsStaticProperty` is implemented for `RustStruct` note: required by a bound in `__wasm_bindgen_generated_RustEnum_set_static_prop::_::assert_supports_static_property` - --> ui-tests/unsupported-options.rs:48:1 + --> ui-tests/unsupported-options.rs:49:1 | -48 | #[wasm_bindgen] +49 | #[wasm_bindgen] | ^^^^^^^^^^^^^^^ required by this bound in `assert_supports_static_property` = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/marker.rs b/src/marker.rs index 509b5f9e15c..4e764212524 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -18,8 +18,9 @@ /// documentation for more details. #[diagnostic::on_unimplemented( message = "JavaScript constructors are not supported for `{Self}`", + label = "this function cannot be the constructor of `{Self}`", note = "`#[wasm_bindgen(constructor)]` is generally only supported for `struct`s with `#[wasm_bindgen]` and cannot be used for `enum`s.", - note = "Consider removing the `constructor` option and using a regular static method instead.", + note = "Consider removing the `constructor` option and using a regular static method instead." )] pub trait SupportsConstructor {} @@ -36,7 +37,8 @@ pub trait SupportsConstructor {} /// documentation for more details. #[diagnostic::on_unimplemented( message = "JavaScript instance getters and setters are not supported for `{Self}`", - note = "`#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s.", + label = "this method cannot be a getter or setter for `{Self}`", + note = "`#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s." )] pub trait SupportsInstanceProperty {} @@ -53,6 +55,7 @@ pub trait SupportsInstanceProperty {} /// documentation for more details. #[diagnostic::on_unimplemented( message = "JavaScript static getters and setters are not supported for `{Self}`", - note = "`#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s.", + label = "this static function cannot be a static getter or setter on `{Self}`", + note = "`#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s." )] pub trait SupportsStaticProperty {} From 888ead1303a392f6d440ab8d64d15444015197f4 Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Mon, 18 Nov 2024 20:30:49 +0100 Subject: [PATCH 03/21] rustfmt --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 3bec96d3a4c..6ef1d7b24f1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,8 +71,8 @@ pub use wasm_bindgen_macro::link_to; pub mod closure; pub mod convert; pub mod describe; -pub mod marker; mod link; +pub mod marker; mod cast; pub use crate::cast::{JsCast, JsObject}; From f07b885edf43f2210f04e1282441e2184d580f3c Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Fri, 29 Nov 2024 17:06:46 +0100 Subject: [PATCH 04/21] Add `rustversion` and `diagnostic` feature --- Cargo.toml | 11 ++++++++++- src/marker.rs | 47 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 873238e5999..bdbf869aad3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,12 +22,20 @@ features = ["serde-serialize"] test = false [features] -default = ["spans", "std"] +default = ["spans", "std", "diagnostic"] enable-interning = ["std"] serde-serialize = ["serde", "serde_json", "std"] spans = ["wasm-bindgen-macro/spans"] std = ["wasm-bindgen-macro/std", "once_cell/std"] +# Enables the use of Rust's `diagnostic` macro for several traits to provide +# better error messages when those traits are not implemented. +# +# Diagnostic messages are only available since Rust 1.78. Enabling this feature +# for older compilers will NOT improve error message and will NOT result in a +# compilation error. +diagnostic = ["rustversion"] + # Whether or not the `#[wasm_bindgen]` macro is strict and generates an error on # all unused attributes strict-macro = ["wasm-bindgen-macro/strict-macro"] @@ -43,6 +51,7 @@ xxx_debug_only_print_generated_code = ["wasm-bindgen-macro/xxx_debug_only_print_ [dependencies] cfg-if = "1.0.0" once_cell = { version = "1.12", default-features = false } +rustversion = { version = "1.0", optional = true } serde = { version = "1.0", optional = true } serde_json = { version = "1.0", optional = true } wasm-bindgen-macro = { path = "crates/macro", version = "=0.2.95", default-features = false } diff --git a/src/marker.rs b/src/marker.rs index 4e764212524..ed4319cdb5d 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -6,6 +6,9 @@ //! This is an internal module, no stability guarantees are provided. Use at //! your own risk. +#[cfg(feature = "diagnostic")] +extern crate rustversion; + /// Marker trait for types that support `#[wasm_bindgen(constructor)]`. /// /// **DO NOT** implement this trait manually. It is implemented automatically @@ -16,11 +19,17 @@ /// This is part of the internal [`convert`](crate::marker) module, **no /// stability guarantees** are provided. Use at your own risk. See its /// documentation for more details. -#[diagnostic::on_unimplemented( - message = "JavaScript constructors are not supported for `{Self}`", - label = "this function cannot be the constructor of `{Self}`", - note = "`#[wasm_bindgen(constructor)]` is generally only supported for `struct`s with `#[wasm_bindgen]` and cannot be used for `enum`s.", - note = "Consider removing the `constructor` option and using a regular static method instead." +#[cfg_attr( + feature = "diagnostic", + rustversion::attr( + since(1.78), + diagnostic::on_unimplemented( + message = "JavaScript constructors are not supported for `{Self}`", + label = "this function cannot be the constructor of `{Self}`", + note = "`#[wasm_bindgen(constructor)]` is generally only supported for `struct`s with `#[wasm_bindgen]` and cannot be used for `enum`s.", + note = "Consider removing the `constructor` option and using a regular static method instead." + ) + ) )] pub trait SupportsConstructor {} @@ -35,10 +44,16 @@ pub trait SupportsConstructor {} /// This is part of the internal [`convert`](crate::marker) module, **no /// stability guarantees** are provided. Use at your own risk. See its /// documentation for more details. -#[diagnostic::on_unimplemented( - message = "JavaScript instance getters and setters are not supported for `{Self}`", - label = "this method cannot be a getter or setter for `{Self}`", - note = "`#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s." +#[cfg_attr( + feature = "diagnostic", + rustversion::attr( + since(1.78), + diagnostic::on_unimplemented( + message = "JavaScript instance getters and setters are not supported for `{Self}`", + label = "this method cannot be a getter or setter for `{Self}`", + note = "`#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s." + ) + ) )] pub trait SupportsInstanceProperty {} @@ -53,9 +68,15 @@ pub trait SupportsInstanceProperty {} /// This is part of the internal [`convert`](crate::marker) module, **no /// stability guarantees** are provided. Use at your own risk. See its /// documentation for more details. -#[diagnostic::on_unimplemented( - message = "JavaScript static getters and setters are not supported for `{Self}`", - label = "this static function cannot be a static getter or setter on `{Self}`", - note = "`#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s." +#[cfg_attr( + feature = "diagnostic", + rustversion::attr( + since(1.78), + diagnostic::on_unimplemented( + message = "JavaScript static getters and setters are not supported for `{Self}`", + label = "this static function cannot be a static getter or setter on `{Self}`", + note = "`#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s." + ) + ) )] pub trait SupportsStaticProperty {} From 526400fd8831d4554a16f6d26f7f6ca73b9b595a Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Fri, 29 Nov 2024 17:35:01 +0100 Subject: [PATCH 05/21] Different code gen for static asserts --- crates/backend/src/codegen.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index 542a0126968..649ac7fe8e2 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -804,22 +804,22 @@ impl TryToTokens for ast::Export { match &self.method_kind { ast::MethodKind::Constructor => { checks.push(quote! { - const fn assert_supports_constructor() {} - assert_supports_constructor::<#class>(); + struct CheckSupportsConstructor(T); + let _: CheckSupportsConstructor<#class>; }); } ast::MethodKind::Operation(operation) => match operation.kind { ast::OperationKind::Getter(_) | ast::OperationKind::Setter(_) => { if operation.is_static { checks.push(quote! { - const fn assert_supports_static_property() {} - assert_supports_static_property::<#class>(); - }); + struct CheckSupportsStaticProperty(T); + let _: CheckSupportsStaticProperty<#class>; + }); } else { checks.push(quote! { - const fn assert_supports_instance_property() {} - assert_supports_instance_property::<#class>(); - }); + struct CheckSupportsInstanceProperty(T); + let _: CheckSupportsInstanceProperty<#class>; + }); } } _ => {} From 81f2d431cc4a9ee6351af460ed52b2268c87c814 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Fri, 29 Nov 2024 17:45:16 +0100 Subject: [PATCH 06/21] Use Rust 1.78.0 to run UI tests --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b5e9de0542a..60567280971 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -29,7 +29,7 @@ jobs: - run: rustup update --no-self-update stable && rustup default stable - run: rustup component add rustfmt - run: cargo fmt --all -- --check - + # Check TOML style by using Taplo. taplo: name: Taplo @@ -325,7 +325,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - run: rustup update --no-self-update 1.76.0 && rustup default 1.76.0 + - run: rustup update --no-self-update 1.78.0 && rustup default 1.78.0 - run: cargo test -p wasm-bindgen-macro - run: cargo test -p wasm-bindgen-test-macro From 9342b6dbd9331ef6cb4d17a6b20275761631688f Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Fri, 29 Nov 2024 18:29:31 +0100 Subject: [PATCH 07/21] Fixed span --- crates/backend/src/codegen.rs | 15 ++-- .../macro/ui-tests/unsupported-options.stderr | 70 +++++++++++++------ 2 files changed, 58 insertions(+), 27 deletions(-) diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index 649ac7fe8e2..b50d2fc64ed 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -796,14 +796,15 @@ impl TryToTokens for ast::Export { }; if let Some(class) = self.rust_class.as_ref() { - // change span of class, so it points to the location of the - // function causing the assert to fail - let mut class = class.clone(); - class.set_span(self.rust_name.span()); + // little helper function to make sure the check points to the + // location of the function causing the assert to fail + let mut add_check = |token_stream| { + checks.push(respan(token_stream, &self.rust_name)); + }; match &self.method_kind { ast::MethodKind::Constructor => { - checks.push(quote! { + add_check(quote! { struct CheckSupportsConstructor(T); let _: CheckSupportsConstructor<#class>; }); @@ -811,12 +812,12 @@ impl TryToTokens for ast::Export { ast::MethodKind::Operation(operation) => match operation.kind { ast::OperationKind::Getter(_) | ast::OperationKind::Setter(_) => { if operation.is_static { - checks.push(quote! { + add_check(quote! { struct CheckSupportsStaticProperty(T); let _: CheckSupportsStaticProperty<#class>; }); } else { - checks.push(quote! { + add_check(quote! { struct CheckSupportsInstanceProperty(T); let _: CheckSupportsInstanceProperty<#class>; }); diff --git a/crates/macro/ui-tests/unsupported-options.stderr b/crates/macro/ui-tests/unsupported-options.stderr index e411e051cc6..c9fc3b2e902 100644 --- a/crates/macro/ui-tests/unsupported-options.stderr +++ b/crates/macro/ui-tests/unsupported-options.stderr @@ -1,6 +1,9 @@ error[E0277]: JavaScript constructors are not supported for `RustEnum` --> ui-tests/unsupported-options.rs:56:12 | +49 | #[wasm_bindgen] + | --------------- in this procedural macro expansion +... 56 | pub fn new() -> Self { | ^^^ this function cannot be the constructor of `RustEnum` | @@ -8,73 +11,100 @@ error[E0277]: JavaScript constructors are not supported for `RustEnum` = note: `#[wasm_bindgen(constructor)]` is generally only supported for `struct`s with `#[wasm_bindgen]` and cannot be used for `enum`s. = note: Consider removing the `constructor` option and using a regular static method instead. = help: the trait `SupportsConstructor` is implemented for `RustStruct` -note: required by a bound in `__wasm_bindgen_generated_RustEnum_new::_::assert_supports_constructor` - --> ui-tests/unsupported-options.rs:49:1 +note: required by a bound in `__wasm_bindgen_generated_RustEnum_new::_::CheckSupportsConstructor` + --> ui-tests/unsupported-options.rs:56:12 | 49 | #[wasm_bindgen] - | ^^^^^^^^^^^^^^^ required by this bound in `assert_supports_constructor` - = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) + | --------------- in this procedural macro expansion +... +56 | pub fn new() -> Self { + | ^^^ required by this bound in `CheckSupportsConstructor` + = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` which comes from the expansion of the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: JavaScript instance getters and setters are not supported for `RustEnum` --> ui-tests/unsupported-options.rs:61:12 | +49 | #[wasm_bindgen] + | --------------- in this procedural macro expansion +... 61 | pub fn prop(self) -> u32 { | ^^^^ this method cannot be a getter or setter for `RustEnum` | = help: the trait `SupportsInstanceProperty` is not implemented for `RustEnum` = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. = help: the trait `SupportsInstanceProperty` is implemented for `RustStruct` -note: required by a bound in `__wasm_bindgen_generated_RustEnum_prop::_::assert_supports_instance_property` - --> ui-tests/unsupported-options.rs:49:1 +note: required by a bound in `__wasm_bindgen_generated_RustEnum_prop::_::CheckSupportsInstanceProperty` + --> ui-tests/unsupported-options.rs:61:12 | 49 | #[wasm_bindgen] - | ^^^^^^^^^^^^^^^ required by this bound in `assert_supports_instance_property` - = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) + | --------------- in this procedural macro expansion +... +61 | pub fn prop(self) -> u32 { + | ^^^^ required by this bound in `CheckSupportsInstanceProperty` + = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` which comes from the expansion of the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: JavaScript instance getters and setters are not supported for `RustEnum` --> ui-tests/unsupported-options.rs:65:12 | +49 | #[wasm_bindgen] + | --------------- in this procedural macro expansion +... 65 | pub fn set_prop(self, _value: u32) {} | ^^^^^^^^ this method cannot be a getter or setter for `RustEnum` | = help: the trait `SupportsInstanceProperty` is not implemented for `RustEnum` = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. = help: the trait `SupportsInstanceProperty` is implemented for `RustStruct` -note: required by a bound in `__wasm_bindgen_generated_RustEnum_set_prop::_::assert_supports_instance_property` - --> ui-tests/unsupported-options.rs:49:1 +note: required by a bound in `__wasm_bindgen_generated_RustEnum_set_prop::_::CheckSupportsInstanceProperty` + --> ui-tests/unsupported-options.rs:65:12 | 49 | #[wasm_bindgen] - | ^^^^^^^^^^^^^^^ required by this bound in `assert_supports_instance_property` - = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) + | --------------- in this procedural macro expansion +... +65 | pub fn set_prop(self, _value: u32) {} + | ^^^^^^^^ required by this bound in `CheckSupportsInstanceProperty` + = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` which comes from the expansion of the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: JavaScript static getters and setters are not supported for `RustEnum` --> ui-tests/unsupported-options.rs:68:12 | +49 | #[wasm_bindgen] + | --------------- in this procedural macro expansion +... 68 | pub fn static_prop() -> u32 { | ^^^^^^^^^^^ this static function cannot be a static getter or setter on `RustEnum` | = help: the trait `SupportsStaticProperty` is not implemented for `RustEnum` = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. = help: the trait `SupportsStaticProperty` is implemented for `RustStruct` -note: required by a bound in `__wasm_bindgen_generated_RustEnum_static_prop::_::assert_supports_static_property` - --> ui-tests/unsupported-options.rs:49:1 +note: required by a bound in `__wasm_bindgen_generated_RustEnum_static_prop::_::CheckSupportsStaticProperty` + --> ui-tests/unsupported-options.rs:68:12 | 49 | #[wasm_bindgen] - | ^^^^^^^^^^^^^^^ required by this bound in `assert_supports_static_property` - = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) + | --------------- in this procedural macro expansion +... +68 | pub fn static_prop() -> u32 { + | ^^^^^^^^^^^ required by this bound in `CheckSupportsStaticProperty` + = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` which comes from the expansion of the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: JavaScript static getters and setters are not supported for `RustEnum` --> ui-tests/unsupported-options.rs:72:12 | +49 | #[wasm_bindgen] + | --------------- in this procedural macro expansion +... 72 | pub fn set_static_prop(_value: u32) {} | ^^^^^^^^^^^^^^^ this static function cannot be a static getter or setter on `RustEnum` | = help: the trait `SupportsStaticProperty` is not implemented for `RustEnum` = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. = help: the trait `SupportsStaticProperty` is implemented for `RustStruct` -note: required by a bound in `__wasm_bindgen_generated_RustEnum_set_static_prop::_::assert_supports_static_property` - --> ui-tests/unsupported-options.rs:49:1 +note: required by a bound in `__wasm_bindgen_generated_RustEnum_set_static_prop::_::CheckSupportsStaticProperty` + --> ui-tests/unsupported-options.rs:72:12 | 49 | #[wasm_bindgen] - | ^^^^^^^^^^^^^^^ required by this bound in `assert_supports_static_property` - = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) + | --------------- in this procedural macro expansion +... +72 | pub fn set_static_prop(_value: u32) {} + | ^^^^^^^^^^^^^^^ required by this bound in `CheckSupportsStaticProperty` + = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` which comes from the expansion of the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) From 0f7541476b17d4e952e61c83186c736fdfc5354c Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Fri, 29 Nov 2024 18:38:57 +0100 Subject: [PATCH 08/21] Updated other ui tests --- crates/macro/ui-tests/async-errors.stderr | 2 +- crates/macro/ui-tests/main-debug.stderr | 8 ++++ crates/macro/ui-tests/main-infallible.stderr | 17 +++++++++ crates/macro/ui-tests/missing-catch.stderr | 35 +++++++++++++++++ .../ui-tests/traits-not-implemented.stderr | 38 +++++++++++++++++++ crates/macro/ui-tests/wasm-bindgen.stderr | 2 +- 6 files changed, 100 insertions(+), 2 deletions(-) diff --git a/crates/macro/ui-tests/async-errors.stderr b/crates/macro/ui-tests/async-errors.stderr index 5526851f1d3..a13c8fceac8 100644 --- a/crates/macro/ui-tests/async-errors.stderr +++ b/crates/macro/ui-tests/async-errors.stderr @@ -22,7 +22,7 @@ error[E0277]: the trait bound `wasm_bindgen::JsValue: From` is not sati --> ui-tests/async-errors.rs:35:24 | 35 | pub async fn bad3() -> BadType { loop {} } - | ^^^^^^^ the trait `From` is not implemented for `wasm_bindgen::JsValue` + | ^^^^^^^ the trait `From` is not implemented for `wasm_bindgen::JsValue`, which is required by `BadType: IntoJsResult` | = help: the following other types implement trait `From`: > diff --git a/crates/macro/ui-tests/main-debug.stderr b/crates/macro/ui-tests/main-debug.stderr index 2b3c670ecf6..fc9ed9e23c4 100644 --- a/crates/macro/ui-tests/main-debug.stderr +++ b/crates/macro/ui-tests/main-debug.stderr @@ -3,3 +3,11 @@ error: the main function has to be called main | 18 | fn fail() {} | ^^^^ + +warning: unused variable: `f` + --> ui-tests/main-debug.rs:12:19 + | +12 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + | ^ help: if this is intentional, prefix it with an underscore: `_f` + | + = note: `#[warn(unused_variables)]` on by default diff --git a/crates/macro/ui-tests/main-infallible.stderr b/crates/macro/ui-tests/main-infallible.stderr index fd8c9c99769..4487bdcfcf6 100644 --- a/crates/macro/ui-tests/main-infallible.stderr +++ b/crates/macro/ui-tests/main-infallible.stderr @@ -3,3 +3,20 @@ error: the main function has to be called main | 10 | fn fail() {} | ^^^^ + +warning: unreachable expression + --> ui-tests/main-infallible.rs:4:1 + | +4 | #[wasm_bindgen(main)] + | ^^^^^^^^^^^^^^^^^^^^^ + | | + | unreachable expression + | any code following this expression is unreachable + | +note: this expression has type `Infallible`, which is uninhabited + --> ui-tests/main-infallible.rs:4:1 + | +4 | #[wasm_bindgen(main)] + | ^^^^^^^^^^^^^^^^^^^^^ + = note: `#[warn(unreachable_code)]` on by default + = note: this warning originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/macro/ui-tests/missing-catch.stderr b/crates/macro/ui-tests/missing-catch.stderr index 4fc6b3ed6de..b420b787da7 100644 --- a/crates/macro/ui-tests/missing-catch.stderr +++ b/crates/macro/ui-tests/missing-catch.stderr @@ -18,3 +18,38 @@ error[E0277]: the trait bound `Result: FromWasmAbi` is not satisfied + --> ui-tests/missing-catch.rs:3:1 + | +3 | #[wasm_bindgen] + | ^^^^^^^^^^^^^^^ the trait `FromWasmAbi` is not implemented for `Result` + | + = help: the following other types implement trait `FromWasmAbi`: + bool + char + isize + i8 + i16 + i32 + i64 + i128 + and $N others + = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the trait bound `Result: FromWasmAbi` is not satisfied + --> ui-tests/missing-catch.rs:6:18 + | +6 | pub fn foo() -> Result; + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromWasmAbi` is not implemented for `Result` + | + = help: the following other types implement trait `FromWasmAbi`: + bool + char + isize + i8 + i16 + i32 + i64 + i128 + and $N others diff --git a/crates/macro/ui-tests/traits-not-implemented.stderr b/crates/macro/ui-tests/traits-not-implemented.stderr index 82aeb56b6fe..2f7e9887747 100644 --- a/crates/macro/ui-tests/traits-not-implemented.stderr +++ b/crates/macro/ui-tests/traits-not-implemented.stderr @@ -15,3 +15,41 @@ error[E0277]: the trait bound `A: IntoWasmAbi` is not satisfied i128 and $N others = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the trait bound `A: IntoWasmAbi` is not satisfied + --> ui-tests/traits-not-implemented.rs:8:19 + | +8 | pub fn foo(a: A); + | ^ the trait `IntoWasmAbi` is not implemented for `A` + | + = help: the following other types implement trait `IntoWasmAbi`: + bool + char + isize + i8 + i16 + i32 + i64 + i128 + and $N others + +error[E0277]: the trait bound `A: IntoWasmAbi` is not satisfied + --> ui-tests/traits-not-implemented.rs:8:12 + | +5 | #[wasm_bindgen] + | --------------- in this procedural macro expansion +... +8 | pub fn foo(a: A); + | ^^^ the trait `IntoWasmAbi` is not implemented for `A` + | + = help: the following other types implement trait `IntoWasmAbi`: + bool + char + isize + i8 + i16 + i32 + i64 + i128 + and $N others + = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/macro/ui-tests/wasm-bindgen.stderr b/crates/macro/ui-tests/wasm-bindgen.stderr index 2ec13836be6..a831c1e08a0 100644 --- a/crates/macro/ui-tests/wasm-bindgen.stderr +++ b/crates/macro/ui-tests/wasm-bindgen.stderr @@ -7,7 +7,7 @@ error[E0433]: failed to resolve: could not find `convert` in `test` = note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider importing one of these items | -3 + use crate::test::test::convert; +3 + use crate::extern_test::convert; | 3 + use wasm_bindgen::convert; | From 95715ecb6b8a9dc5e5e5698e5ba4d4834c89fd20 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Fri, 29 Nov 2024 18:55:20 +0100 Subject: [PATCH 09/21] Export marker traits under `::__rt::marker` --- crates/backend/src/codegen.rs | 12 ++++++------ src/lib.rs | 6 +++++- src/marker.rs | 3 +++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index b50d2fc64ed..84e9cbf45cd 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -227,11 +227,11 @@ impl ToTokens for ast::Struct { let maybe_no_coverage = coverage(); (quote! { #[automatically_derived] - impl #wasm_bindgen::marker::SupportsConstructor for #name {} + impl #wasm_bindgen::__rt::marker::SupportsConstructor for #name {} #[automatically_derived] - impl #wasm_bindgen::marker::SupportsInstanceProperty for #name {} + impl #wasm_bindgen::__rt::marker::SupportsInstanceProperty for #name {} #[automatically_derived] - impl #wasm_bindgen::marker::SupportsStaticProperty for #name {} + impl #wasm_bindgen::__rt::marker::SupportsStaticProperty for #name {} #[automatically_derived] impl #wasm_bindgen::describe::WasmDescribe for #name { @@ -805,7 +805,7 @@ impl TryToTokens for ast::Export { match &self.method_kind { ast::MethodKind::Constructor => { add_check(quote! { - struct CheckSupportsConstructor(T); + struct CheckSupportsConstructor(T); let _: CheckSupportsConstructor<#class>; }); } @@ -813,12 +813,12 @@ impl TryToTokens for ast::Export { ast::OperationKind::Getter(_) | ast::OperationKind::Setter(_) => { if operation.is_static { add_check(quote! { - struct CheckSupportsStaticProperty(T); + struct CheckSupportsStaticProperty(T); let _: CheckSupportsStaticProperty<#class>; }); } else { add_check(quote! { - struct CheckSupportsInstanceProperty(T); + struct CheckSupportsInstanceProperty(T); let _: CheckSupportsInstanceProperty<#class>; }); } diff --git a/src/lib.rs b/src/lib.rs index 9e284124d2d..027daf08f53 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -77,7 +77,7 @@ pub mod convert; pub mod describe; mod externref; mod link; -pub mod marker; +mod marker; mod cast; pub use crate::cast::{JsCast, JsObject}; @@ -1583,6 +1583,10 @@ pub mod __rt { use alloc::boxed::Box; use alloc::rc::Rc; + pub mod marker { + pub use super::super::marker::*; + } + pub mod once_cell { #[cfg(any(target_feature = "atomics", feature = "std"))] pub use once_cell::*; diff --git a/src/marker.rs b/src/marker.rs index ed4319cdb5d..3b6b7ffdca4 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -1,6 +1,9 @@ //! This module contains marker traits used by `wasm-bindgen` to verify its //! generated code. //! +//! NOTE: This module is not exported as is. It is re-exported under +//! `wasm_bindgen::__rt::marker`. +//! //! # ⚠️ Unstable //! //! This is an internal module, no stability guarantees are provided. Use at From 053c60edeecba5cf6ad773fa981ba3252bf158b9 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Sat, 7 Dec 2024 13:38:02 +0100 Subject: [PATCH 10/21] Feature suggestions --- Cargo.toml | 13 ++++++------- src/marker.rs | 46 ++++------------------------------------------ 2 files changed, 10 insertions(+), 49 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7864437d0a2..d27d6a8dd0c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,19 +22,18 @@ features = ["serde-serialize"] test = false [features] -default = ["spans", "std", "diagnostic"] +default = ["spans", "std", "msrv"] enable-interning = ["std"] serde-serialize = ["serde", "serde_json", "std"] spans = ["wasm-bindgen-macro/spans"] std = ["wasm-bindgen-macro/std", "once_cell/std"] -# Enables the use of Rust's `diagnostic` macro for several traits to provide -# better error messages when those traits are not implemented. +# Opt-in for Rust language features that require a higher MSRV. # -# Diagnostic messages are only available since Rust 1.78. Enabling this feature -# for older compilers will NOT improve error message and will NOT result in a -# compilation error. -diagnostic = ["rustversion"] +# The current rustc version is detected at compile-time, so enabling this +# feature for older compilers will NOT result in a compilation error. Instead, +# any unsupported language feature will not be used. +msrv = ["rustversion"] # Whether or not the `#[wasm_bindgen]` macro is strict and generates an error on # all unused attributes diff --git a/src/marker.rs b/src/marker.rs index 3b6b7ffdca4..4979af72a19 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -1,29 +1,9 @@ -//! This module contains marker traits used by `wasm-bindgen` to verify its -//! generated code. -//! -//! NOTE: This module is not exported as is. It is re-exported under -//! `wasm_bindgen::__rt::marker`. -//! -//! # ⚠️ Unstable -//! -//! This is an internal module, no stability guarantees are provided. Use at -//! your own risk. - -#[cfg(feature = "diagnostic")] +#[cfg(feature = "msrv")] extern crate rustversion; /// Marker trait for types that support `#[wasm_bindgen(constructor)]`. -/// -/// **DO NOT** implement this trait manually. It is implemented automatically -/// for types that support constructors. -/// -/// # ⚠️ Unstable -/// -/// This is part of the internal [`convert`](crate::marker) module, **no -/// stability guarantees** are provided. Use at your own risk. See its -/// documentation for more details. #[cfg_attr( - feature = "diagnostic", + feature = "msrv", rustversion::attr( since(1.78), diagnostic::on_unimplemented( @@ -38,17 +18,8 @@ pub trait SupportsConstructor {} /// Marker trait for types that support `#[wasm_bindgen(getter)]` or /// `#[wasm_bindgen(Setter)]` on instance methods. -/// -/// **DO NOT** implement this trait manually. It is implemented automatically -/// for types that support instance properties. -/// -/// # ⚠️ Unstable -/// -/// This is part of the internal [`convert`](crate::marker) module, **no -/// stability guarantees** are provided. Use at your own risk. See its -/// documentation for more details. #[cfg_attr( - feature = "diagnostic", + feature = "msrv", rustversion::attr( since(1.78), diagnostic::on_unimplemented( @@ -62,17 +33,8 @@ pub trait SupportsInstanceProperty {} /// Marker trait for types that support `#[wasm_bindgen(getter)]` or /// `#[wasm_bindgen(Setter)]` on static methods. -/// -/// **DO NOT** implement this trait manually. It is implemented automatically -/// for types that support static properties. -/// -/// # ⚠️ Unstable -/// -/// This is part of the internal [`convert`](crate::marker) module, **no -/// stability guarantees** are provided. Use at your own risk. See its -/// documentation for more details. #[cfg_attr( - feature = "diagnostic", + feature = "msrv", rustversion::attr( since(1.78), diagnostic::on_unimplemented( From db953cc0e43ebf2dfb863487ec87de17c9f80739 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Sat, 7 Dec 2024 13:42:20 +0100 Subject: [PATCH 11/21] Shared check struct --- crates/backend/src/codegen.rs | 9 +-- .../macro/ui-tests/unsupported-options.stderr | 55 +++++++------------ src/marker.rs | 3 + 3 files changed, 26 insertions(+), 41 deletions(-) diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index 0092ce9a15e..223eba72569 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -804,21 +804,18 @@ impl TryToTokens for ast::Export { match &self.method_kind { ast::MethodKind::Constructor => { add_check(quote! { - struct CheckSupportsConstructor(T); - let _: CheckSupportsConstructor<#class>; + let _: #wasm_bindgen::__rt::marker::CheckSupportsConstructor<#class>; }); } ast::MethodKind::Operation(operation) => match operation.kind { ast::OperationKind::Getter(_) | ast::OperationKind::Setter(_) => { if operation.is_static { add_check(quote! { - struct CheckSupportsStaticProperty(T); - let _: CheckSupportsStaticProperty<#class>; + let _: #wasm_bindgen::__rt::marker::CheckSupportsStaticProperty<#class>; }); } else { add_check(quote! { - struct CheckSupportsInstanceProperty(T); - let _: CheckSupportsInstanceProperty<#class>; + let _: #wasm_bindgen::__rt::marker::CheckSupportsInstanceProperty<#class>; }); } } diff --git a/crates/macro/ui-tests/unsupported-options.stderr b/crates/macro/ui-tests/unsupported-options.stderr index c9fc3b2e902..0bd4ad8b410 100644 --- a/crates/macro/ui-tests/unsupported-options.stderr +++ b/crates/macro/ui-tests/unsupported-options.stderr @@ -11,14 +11,11 @@ error[E0277]: JavaScript constructors are not supported for `RustEnum` = note: `#[wasm_bindgen(constructor)]` is generally only supported for `struct`s with `#[wasm_bindgen]` and cannot be used for `enum`s. = note: Consider removing the `constructor` option and using a regular static method instead. = help: the trait `SupportsConstructor` is implemented for `RustStruct` -note: required by a bound in `__wasm_bindgen_generated_RustEnum_new::_::CheckSupportsConstructor` - --> ui-tests/unsupported-options.rs:56:12 +note: required by a bound in `CheckSupportsConstructor` + --> $WORKSPACE/src/marker.rs | -49 | #[wasm_bindgen] - | --------------- in this procedural macro expansion -... -56 | pub fn new() -> Self { - | ^^^ required by this bound in `CheckSupportsConstructor` + | pub struct CheckSupportsConstructor(T); + | ^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckSupportsConstructor` = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` which comes from the expansion of the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: JavaScript instance getters and setters are not supported for `RustEnum` @@ -33,14 +30,11 @@ error[E0277]: JavaScript instance getters and setters are not supported for `Rus = help: the trait `SupportsInstanceProperty` is not implemented for `RustEnum` = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. = help: the trait `SupportsInstanceProperty` is implemented for `RustStruct` -note: required by a bound in `__wasm_bindgen_generated_RustEnum_prop::_::CheckSupportsInstanceProperty` - --> ui-tests/unsupported-options.rs:61:12 +note: required by a bound in `CheckSupportsInstanceProperty` + --> $WORKSPACE/src/marker.rs | -49 | #[wasm_bindgen] - | --------------- in this procedural macro expansion -... -61 | pub fn prop(self) -> u32 { - | ^^^^ required by this bound in `CheckSupportsInstanceProperty` + | pub struct CheckSupportsInstanceProperty(T); + | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckSupportsInstanceProperty` = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` which comes from the expansion of the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: JavaScript instance getters and setters are not supported for `RustEnum` @@ -55,14 +49,11 @@ error[E0277]: JavaScript instance getters and setters are not supported for `Rus = help: the trait `SupportsInstanceProperty` is not implemented for `RustEnum` = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. = help: the trait `SupportsInstanceProperty` is implemented for `RustStruct` -note: required by a bound in `__wasm_bindgen_generated_RustEnum_set_prop::_::CheckSupportsInstanceProperty` - --> ui-tests/unsupported-options.rs:65:12 +note: required by a bound in `CheckSupportsInstanceProperty` + --> $WORKSPACE/src/marker.rs | -49 | #[wasm_bindgen] - | --------------- in this procedural macro expansion -... -65 | pub fn set_prop(self, _value: u32) {} - | ^^^^^^^^ required by this bound in `CheckSupportsInstanceProperty` + | pub struct CheckSupportsInstanceProperty(T); + | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckSupportsInstanceProperty` = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` which comes from the expansion of the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: JavaScript static getters and setters are not supported for `RustEnum` @@ -77,14 +68,11 @@ error[E0277]: JavaScript static getters and setters are not supported for `RustE = help: the trait `SupportsStaticProperty` is not implemented for `RustEnum` = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. = help: the trait `SupportsStaticProperty` is implemented for `RustStruct` -note: required by a bound in `__wasm_bindgen_generated_RustEnum_static_prop::_::CheckSupportsStaticProperty` - --> ui-tests/unsupported-options.rs:68:12 +note: required by a bound in `CheckSupportsStaticProperty` + --> $WORKSPACE/src/marker.rs | -49 | #[wasm_bindgen] - | --------------- in this procedural macro expansion -... -68 | pub fn static_prop() -> u32 { - | ^^^^^^^^^^^ required by this bound in `CheckSupportsStaticProperty` + | pub struct CheckSupportsStaticProperty(T); + | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckSupportsStaticProperty` = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` which comes from the expansion of the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: JavaScript static getters and setters are not supported for `RustEnum` @@ -99,12 +87,9 @@ error[E0277]: JavaScript static getters and setters are not supported for `RustE = help: the trait `SupportsStaticProperty` is not implemented for `RustEnum` = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. = help: the trait `SupportsStaticProperty` is implemented for `RustStruct` -note: required by a bound in `__wasm_bindgen_generated_RustEnum_set_static_prop::_::CheckSupportsStaticProperty` - --> ui-tests/unsupported-options.rs:72:12 +note: required by a bound in `CheckSupportsStaticProperty` + --> $WORKSPACE/src/marker.rs | -49 | #[wasm_bindgen] - | --------------- in this procedural macro expansion -... -72 | pub fn set_static_prop(_value: u32) {} - | ^^^^^^^^^^^^^^^ required by this bound in `CheckSupportsStaticProperty` + | pub struct CheckSupportsStaticProperty(T); + | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckSupportsStaticProperty` = note: this error originates in the attribute macro `wasm_bindgen::prelude::__wasm_bindgen_class_marker` which comes from the expansion of the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/marker.rs b/src/marker.rs index 4979af72a19..a9a9fd1d3d3 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -15,6 +15,7 @@ extern crate rustversion; ) )] pub trait SupportsConstructor {} +pub struct CheckSupportsConstructor(T); /// Marker trait for types that support `#[wasm_bindgen(getter)]` or /// `#[wasm_bindgen(Setter)]` on instance methods. @@ -30,6 +31,7 @@ pub trait SupportsConstructor {} ) )] pub trait SupportsInstanceProperty {} +pub struct CheckSupportsInstanceProperty(T); /// Marker trait for types that support `#[wasm_bindgen(getter)]` or /// `#[wasm_bindgen(Setter)]` on static methods. @@ -45,3 +47,4 @@ pub trait SupportsInstanceProperty {} ) )] pub trait SupportsStaticProperty {} +pub struct CheckSupportsStaticProperty(T); From ed462cc8631447e9db849accfd4f9f09125f4a85 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Sat, 7 Dec 2024 13:43:24 +0100 Subject: [PATCH 12/21] Fixed main debug warning --- crates/macro/ui-tests/main-debug.rs | 2 +- crates/macro/ui-tests/main-debug.stderr | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/crates/macro/ui-tests/main-debug.rs b/crates/macro/ui-tests/main-debug.rs index 2fc9aa7ca6a..ba163e4cf18 100644 --- a/crates/macro/ui-tests/main-debug.rs +++ b/crates/macro/ui-tests/main-debug.rs @@ -9,7 +9,7 @@ fn main() -> Result<(), Test> { struct Test; impl fmt::Debug for Test { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { unimplemented!() } } diff --git a/crates/macro/ui-tests/main-debug.stderr b/crates/macro/ui-tests/main-debug.stderr index fc9ed9e23c4..2b3c670ecf6 100644 --- a/crates/macro/ui-tests/main-debug.stderr +++ b/crates/macro/ui-tests/main-debug.stderr @@ -3,11 +3,3 @@ error: the main function has to be called main | 18 | fn fail() {} | ^^^^ - -warning: unused variable: `f` - --> ui-tests/main-debug.rs:12:19 - | -12 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - | ^ help: if this is intentional, prefix it with an underscore: `_f` - | - = note: `#[warn(unused_variables)]` on by default From 6ac1419aa184e8f7e1a5b8989a90bdd6bbebf733 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Sat, 7 Dec 2024 13:46:13 +0100 Subject: [PATCH 13/21] Terser error messages --- crates/macro/ui-tests/unsupported-options.stderr | 10 +++++----- src/marker.rs | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/macro/ui-tests/unsupported-options.stderr b/crates/macro/ui-tests/unsupported-options.stderr index 0bd4ad8b410..84ec8f23560 100644 --- a/crates/macro/ui-tests/unsupported-options.stderr +++ b/crates/macro/ui-tests/unsupported-options.stderr @@ -8,7 +8,7 @@ error[E0277]: JavaScript constructors are not supported for `RustEnum` | ^^^ this function cannot be the constructor of `RustEnum` | = help: the trait `SupportsConstructor` is not implemented for `RustEnum` - = note: `#[wasm_bindgen(constructor)]` is generally only supported for `struct`s with `#[wasm_bindgen]` and cannot be used for `enum`s. + = note: `#[wasm_bindgen(constructor)]` is only supported for `struct`s and cannot be used for `enum`s. = note: Consider removing the `constructor` option and using a regular static method instead. = help: the trait `SupportsConstructor` is implemented for `RustStruct` note: required by a bound in `CheckSupportsConstructor` @@ -28,7 +28,7 @@ error[E0277]: JavaScript instance getters and setters are not supported for `Rus | ^^^^ this method cannot be a getter or setter for `RustEnum` | = help: the trait `SupportsInstanceProperty` is not implemented for `RustEnum` - = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. + = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are only supported for `struct`s and cannot be used for `enum`s. = help: the trait `SupportsInstanceProperty` is implemented for `RustStruct` note: required by a bound in `CheckSupportsInstanceProperty` --> $WORKSPACE/src/marker.rs @@ -47,7 +47,7 @@ error[E0277]: JavaScript instance getters and setters are not supported for `Rus | ^^^^^^^^ this method cannot be a getter or setter for `RustEnum` | = help: the trait `SupportsInstanceProperty` is not implemented for `RustEnum` - = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. + = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are only supported for `struct`s and cannot be used for `enum`s. = help: the trait `SupportsInstanceProperty` is implemented for `RustStruct` note: required by a bound in `CheckSupportsInstanceProperty` --> $WORKSPACE/src/marker.rs @@ -66,7 +66,7 @@ error[E0277]: JavaScript static getters and setters are not supported for `RustE | ^^^^^^^^^^^ this static function cannot be a static getter or setter on `RustEnum` | = help: the trait `SupportsStaticProperty` is not implemented for `RustEnum` - = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. + = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are only supported for `struct`s and cannot be used for `enum`s. = help: the trait `SupportsStaticProperty` is implemented for `RustStruct` note: required by a bound in `CheckSupportsStaticProperty` --> $WORKSPACE/src/marker.rs @@ -85,7 +85,7 @@ error[E0277]: JavaScript static getters and setters are not supported for `RustE | ^^^^^^^^^^^^^^^ this static function cannot be a static getter or setter on `RustEnum` | = help: the trait `SupportsStaticProperty` is not implemented for `RustEnum` - = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s. + = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are only supported for `struct`s and cannot be used for `enum`s. = help: the trait `SupportsStaticProperty` is implemented for `RustStruct` note: required by a bound in `CheckSupportsStaticProperty` --> $WORKSPACE/src/marker.rs diff --git a/src/marker.rs b/src/marker.rs index a9a9fd1d3d3..0432f6f55b0 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -9,7 +9,7 @@ extern crate rustversion; diagnostic::on_unimplemented( message = "JavaScript constructors are not supported for `{Self}`", label = "this function cannot be the constructor of `{Self}`", - note = "`#[wasm_bindgen(constructor)]` is generally only supported for `struct`s with `#[wasm_bindgen]` and cannot be used for `enum`s.", + note = "`#[wasm_bindgen(constructor)]` is only supported for `struct`s and cannot be used for `enum`s.", note = "Consider removing the `constructor` option and using a regular static method instead." ) ) @@ -26,7 +26,7 @@ pub struct CheckSupportsConstructor(T); diagnostic::on_unimplemented( message = "JavaScript instance getters and setters are not supported for `{Self}`", label = "this method cannot be a getter or setter for `{Self}`", - note = "`#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s." + note = "`#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are only supported for `struct`s and cannot be used for `enum`s.", ) ) )] @@ -42,7 +42,7 @@ pub struct CheckSupportsInstanceProperty(T); diagnostic::on_unimplemented( message = "JavaScript static getters and setters are not supported for `{Self}`", label = "this static function cannot be a static getter or setter on `{Self}`", - note = "`#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are generally only supported for `struct`s with `#[wasm_bindgen]`. They cannot be used for `enum`s." + note = "`#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are only supported for `struct`s and cannot be used for `enum`s.", ) ) )] From 2802d40c8dc60e8dcbdef567391f1509cc1417b6 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Sun, 8 Dec 2024 15:07:35 +0100 Subject: [PATCH 14/21] Removed `extern crate rustversion` --- src/marker.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/marker.rs b/src/marker.rs index 0432f6f55b0..8d4641b6772 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -1,6 +1,3 @@ -#[cfg(feature = "msrv")] -extern crate rustversion; - /// Marker trait for types that support `#[wasm_bindgen(constructor)]`. #[cfg_attr( feature = "msrv", From 49f6c4dbf2b55eced60f263f78bde1e99a7749d2 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Mon, 9 Dec 2024 00:09:45 +0100 Subject: [PATCH 15/21] Move `marker.rs` file under `rt` --- src/lib.rs | 3 +-- src/{ => rt}/marker.rs | 0 src/{rt.rs => rt/mod.rs} | 2 ++ 3 files changed, 3 insertions(+), 2 deletions(-) rename src/{ => rt}/marker.rs (100%) rename src/{rt.rs => rt/mod.rs} (99%) diff --git a/src/lib.rs b/src/lib.rs index 645b6d6c832..aa0920e9477 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -117,7 +117,6 @@ pub mod convert; pub mod describe; mod externref; mod link; -mod marker; mod cast; pub use crate::cast::{JsCast, JsObject}; @@ -130,7 +129,7 @@ if_std! { } #[doc(hidden)] -#[path = "rt.rs"] +#[path = "rt/mod.rs"] pub mod __rt; /// Representation of an object owned by JS. diff --git a/src/marker.rs b/src/rt/marker.rs similarity index 100% rename from src/marker.rs rename to src/rt/marker.rs diff --git a/src/rt.rs b/src/rt/mod.rs similarity index 99% rename from src/rt.rs rename to src/rt/mod.rs index 2aac5ce3a41..82e97f691f5 100644 --- a/src/rt.rs +++ b/src/rt/mod.rs @@ -16,6 +16,8 @@ use alloc::alloc::{alloc, dealloc, realloc, Layout}; use alloc::boxed::Box; use alloc::rc::Rc; +pub mod marker; + /// Wrapper around [`::once_cell::unsync::Lazy`] adding some compatibility methods with /// [`std::thread::LocalKey`] and adding `Send + Sync` when `atomics` is not enabled. #[cfg(not(feature = "std"))] From 7512b0796b494dbafab7655c0cbbe98717d9f37e Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Mon, 9 Dec 2024 00:16:44 +0100 Subject: [PATCH 16/21] Document `msrv` feature --- src/lib.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index aa0920e9477..64900e9cf5d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,6 +14,16 @@ //! This feature currently enables the `std` feature, meaning that it is not //! compatible with `no_std` environments. //! +//! ### `msrv` (default) +//! +//! Enables Rust language features that requires a higher MSRV. Enabling this +//! feature on older compilers will NOT result in a compilation error, the newer +//! language features will simply not be used. +//! +//! Right now, this feature only enables the use of +//! `diagnostic::on_unimplemented` (Rust 1.78 or later) to provide better error +//! messages. +//! //! ### `std` (default) //! //! Enabling this feature will make the crate depend on the Rust standard library. From 5e461ffcd1b13cd33852ae30b0e6b793d85aabf5 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Mon, 9 Dec 2024 00:20:30 +0100 Subject: [PATCH 17/21] Remove useless `automatically_derived` --- crates/backend/src/codegen.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index 223eba72569..63b9376e35d 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -834,7 +834,6 @@ impl TryToTokens for ast::Export { export_name = #export_name, )] pub unsafe extern "C" fn #generated_name(#(#args),*) -> #wasm_bindgen::convert::WasmRet<#projection::Abi> { - #[automatically_derived] const _: () = { #(#checks)* }; From bd9f84712a3f0fa6e9bf848381cfa82f7e0dbe24 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Mon, 9 Dec 2024 00:24:52 +0100 Subject: [PATCH 18/21] Updated UI tests --- crates/macro/ui-tests/unsupported-options.stderr | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/macro/ui-tests/unsupported-options.stderr b/crates/macro/ui-tests/unsupported-options.stderr index 84ec8f23560..7a6dcd70537 100644 --- a/crates/macro/ui-tests/unsupported-options.stderr +++ b/crates/macro/ui-tests/unsupported-options.stderr @@ -12,7 +12,7 @@ error[E0277]: JavaScript constructors are not supported for `RustEnum` = note: Consider removing the `constructor` option and using a regular static method instead. = help: the trait `SupportsConstructor` is implemented for `RustStruct` note: required by a bound in `CheckSupportsConstructor` - --> $WORKSPACE/src/marker.rs + --> $WORKSPACE/src/rt/marker.rs | | pub struct CheckSupportsConstructor(T); | ^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckSupportsConstructor` @@ -31,7 +31,7 @@ error[E0277]: JavaScript instance getters and setters are not supported for `Rus = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are only supported for `struct`s and cannot be used for `enum`s. = help: the trait `SupportsInstanceProperty` is implemented for `RustStruct` note: required by a bound in `CheckSupportsInstanceProperty` - --> $WORKSPACE/src/marker.rs + --> $WORKSPACE/src/rt/marker.rs | | pub struct CheckSupportsInstanceProperty(T); | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckSupportsInstanceProperty` @@ -50,7 +50,7 @@ error[E0277]: JavaScript instance getters and setters are not supported for `Rus = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are only supported for `struct`s and cannot be used for `enum`s. = help: the trait `SupportsInstanceProperty` is implemented for `RustStruct` note: required by a bound in `CheckSupportsInstanceProperty` - --> $WORKSPACE/src/marker.rs + --> $WORKSPACE/src/rt/marker.rs | | pub struct CheckSupportsInstanceProperty(T); | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckSupportsInstanceProperty` @@ -69,7 +69,7 @@ error[E0277]: JavaScript static getters and setters are not supported for `RustE = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are only supported for `struct`s and cannot be used for `enum`s. = help: the trait `SupportsStaticProperty` is implemented for `RustStruct` note: required by a bound in `CheckSupportsStaticProperty` - --> $WORKSPACE/src/marker.rs + --> $WORKSPACE/src/rt/marker.rs | | pub struct CheckSupportsStaticProperty(T); | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckSupportsStaticProperty` @@ -88,7 +88,7 @@ error[E0277]: JavaScript static getters and setters are not supported for `RustE = note: `#[wasm_bindgen(getter)]` and `#[wasm_bindgen(setter)]` are only supported for `struct`s and cannot be used for `enum`s. = help: the trait `SupportsStaticProperty` is implemented for `RustStruct` note: required by a bound in `CheckSupportsStaticProperty` - --> $WORKSPACE/src/marker.rs + --> $WORKSPACE/src/rt/marker.rs | | pub struct CheckSupportsStaticProperty(T); | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `CheckSupportsStaticProperty` From 80ab2ef2d042190ccf132dcff9575e9aa816b566 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Mon, 9 Dec 2024 00:32:43 +0100 Subject: [PATCH 19/21] Update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17a86bbfdbd..95b8f96cbfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ * Optional parameters are now typed as `T | undefined | null` to reflect the actual JS behavior. [#4188](https://github.com/rustwasm/wasm-bindgen/pull/4188) +* Adding `getter`, `setter`, and `constructor` methods to enums now results in a compiler error. This was previously erroneously allowed and resulted in invalid JS code gen. + [#4278](https://github.com/rustwasm/wasm-bindgen/pull/4278) + ### Fixed - Fixed using [JavaScript keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#keywords) as identifiers not being handled correctly. From b240d268e590127133ea9f34a81d78b50adbff0d Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Mon, 9 Dec 2024 00:34:00 +0100 Subject: [PATCH 20/21] Apply suggestions from code review Co-authored-by: daxpedda --- src/lib.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 64900e9cf5d..810197c3072 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,13 +16,11 @@ //! //! ### `msrv` (default) //! -//! Enables Rust language features that requires a higher MSRV. Enabling this +//! Enables Rust language features that require a higher MSRV. Enabling this //! feature on older compilers will NOT result in a compilation error, the newer //! language features will simply not be used. //! -//! Right now, this feature only enables the use of -//! `diagnostic::on_unimplemented` (Rust 1.78 or later) to provide better error -//! messages. +//! When compiling with Rust v1.78 or later, this feature enables better error messages for invalid methods on structs and enums. //! //! ### `std` (default) //! From e1d2358abab72afb030710ad90047a4f9d574239 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Mon, 9 Dec 2024 00:48:45 +0100 Subject: [PATCH 21/21] Test MSRV and resolver v1 of new crate feature --- .github/workflows/main.yml | 4 ++++ crates/msrv/lib/Cargo.toml | 9 ++++++++- crates/msrv/resolver/Cargo.toml | 9 ++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e39a8763795..c477743eba8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -569,6 +569,8 @@ jobs: - wasm32-unknown-unknown features: - --no-default-features + - --no-default-features --features std + - --no-default-features --features msrv - "" defaults: run: @@ -594,6 +596,8 @@ jobs: - wasm32-unknown-unknown features: - --no-default-features + - --no-default-features --features std + - --no-default-features --features msrv - "" defaults: run: diff --git a/crates/msrv/lib/Cargo.toml b/crates/msrv/lib/Cargo.toml index 7cf0a5d4bb5..98e95deff10 100644 --- a/crates/msrv/lib/Cargo.toml +++ b/crates/msrv/lib/Cargo.toml @@ -5,7 +5,14 @@ publish = false version = "0.0.0" [features] -default = ["std"] +default = [ + "wasm-bindgen/default", + "js-sys/default", + "wasm-bindgen-futures/default", + "web-sys/default", + "wasm-bindgen-test/default", +] +msrv = ["wasm-bindgen/msrv"] std = [ "wasm-bindgen/std", "js-sys/std", diff --git a/crates/msrv/resolver/Cargo.toml b/crates/msrv/resolver/Cargo.toml index 6c7eeffbfc5..842ce86ec82 100644 --- a/crates/msrv/resolver/Cargo.toml +++ b/crates/msrv/resolver/Cargo.toml @@ -6,7 +6,14 @@ resolver = "1" version = "0.0.0" [features] -default = ["std"] +default = [ + "wasm-bindgen/default", + "js-sys/default", + "wasm-bindgen-futures/default", + "web-sys/default", + "wasm-bindgen-test/default", +] +msrv = ["wasm-bindgen/msrv"] std = [ "wasm-bindgen/std", "js-sys/std",