Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make getters, setters, and constructors compiler errors for enums #4278

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ad495c9
Make `getter`s, `setter`s, and `constructor`s compiler errors for enums
RunDevelopment Nov 18, 2024
e967962
Better error messages
RunDevelopment Nov 18, 2024
888ead1
rustfmt
RunDevelopment Nov 18, 2024
77c3696
Merge branch 'main' into error-enum-getter-setter-constructor
RunDevelopment Nov 29, 2024
f07b885
Add `rustversion` and `diagnostic` feature
RunDevelopment Nov 29, 2024
526400f
Different code gen for static asserts
RunDevelopment Nov 29, 2024
81f2d43
Use Rust 1.78.0 to run UI tests
RunDevelopment Nov 29, 2024
9342b6d
Fixed span
RunDevelopment Nov 29, 2024
0f75414
Updated other ui tests
RunDevelopment Nov 29, 2024
95715ec
Export marker traits under `::__rt::marker`
RunDevelopment Nov 29, 2024
4a83589
Merge branch 'main' into error-enum-getter-setter-constructor
RunDevelopment Dec 7, 2024
053c60e
Feature suggestions
RunDevelopment Dec 7, 2024
db953cc
Shared check struct
RunDevelopment Dec 7, 2024
ed462cc
Fixed main debug warning
RunDevelopment Dec 7, 2024
6ac1419
Terser error messages
RunDevelopment Dec 7, 2024
2802d40
Removed `extern crate rustversion`
RunDevelopment Dec 8, 2024
9355f5c
Merge branch 'main' into error-enum-getter-setter-constructor
RunDevelopment Dec 8, 2024
49f6c4d
Move `marker.rs` file under `rt`
RunDevelopment Dec 8, 2024
7512b07
Document `msrv` feature
RunDevelopment Dec 8, 2024
5e461ff
Remove useless `automatically_derived`
RunDevelopment Dec 8, 2024
bd9f847
Updated UI tests
RunDevelopment Dec 8, 2024
80ab2ef
Update changelog
RunDevelopment Dec 8, 2024
b240d26
Apply suggestions from code review
RunDevelopment Dec 8, 2024
e1d2358
Test MSRV and resolver v1 of new crate feature
daxpedda Dec 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,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

Expand Down Expand Up @@ -569,6 +569,8 @@ jobs:
- wasm32-unknown-unknown
features:
- --no-default-features
- --no-default-features --features std
- --no-default-features --features msrv
- ""
defaults:
run:
Expand All @@ -594,6 +596,8 @@ jobs:
- wasm32-unknown-unknown
features:
- --no-default-features
- --no-default-features --features std
- --no-default-features --features msrv
- ""
defaults:
run:
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
10 changes: 9 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,19 @@ features = ["serde-serialize"]
test = false

[features]
default = ["std"]
default = ["std", "msrv"]
enable-interning = ["std"]
serde-serialize = ["serde", "serde_json", "std"]
spans = []
std = ["wasm-bindgen-macro/std", "once_cell/std"]

# Opt-in for Rust language features that require a higher MSRV.
#
# 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"]
daxpedda marked this conversation as resolved.
Show resolved Hide resolved

# Whether or not the `#[wasm_bindgen]` macro is strict and generates an error on
# all unused attributes
strict-macro = ["wasm-bindgen-macro/strict-macro"]
Expand All @@ -43,6 +50,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.99", default-features = false }
Expand Down
48 changes: 43 additions & 5 deletions crates/backend/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::__rt::marker::SupportsConstructor for #name {}
#[automatically_derived]
impl #wasm_bindgen::__rt::marker::SupportsInstanceProperty for #name {}
#[automatically_derived]
impl #wasm_bindgen::__rt::marker::SupportsStaticProperty for #name {}

#[automatically_derived]
impl #wasm_bindgen::describe::WasmDescribe for #name {
fn describe() {
Expand Down Expand Up @@ -782,12 +789,41 @@ 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() {
// 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 => {
add_check(quote! {
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! {
let _: #wasm_bindgen::__rt::marker::CheckSupportsStaticProperty<#class>;
});
} else {
add_check(quote! {
let _: #wasm_bindgen::__rt::marker::CheckSupportsInstanceProperty<#class>;
});
}
}
_ => {}
},
}
}

(quote! {
#[automatically_derived]
const _: () = {
Expand All @@ -798,7 +834,9 @@ impl TryToTokens for ast::Export {
export_name = #export_name,
)]
pub unsafe extern "C" fn #generated_name(#(#args),*) -> #wasm_bindgen::convert::WasmRet<#projection::Abi> {
#start_check
const _: () = {
#(#checks)*
};

let #ret = #call;
#convert_ret
Expand Down
2 changes: 1 addition & 1 deletion crates/macro/ui-tests/async-errors.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ error[E0277]: the trait bound `wasm_bindgen::JsValue: From<BadType>` is not sati
--> ui-tests/async-errors.rs:35:24
|
35 | pub async fn bad3() -> BadType { loop {} }
| ^^^^^^^ the trait `From<BadType>` is not implemented for `wasm_bindgen::JsValue`
| ^^^^^^^ the trait `From<BadType>` is not implemented for `wasm_bindgen::JsValue`, which is required by `BadType: IntoJsResult`
|
= help: the following other types implement trait `From<T>`:
<wasm_bindgen::JsValue as From<bool>>
Expand Down
2 changes: 1 addition & 1 deletion crates/macro/ui-tests/main-debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!()
}
}
Expand Down
17 changes: 17 additions & 0 deletions crates/macro/ui-tests/main-infallible.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Comment on lines +6 to +22
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fun. That's a bug. We should avoid emitting this warning somehow.
Not related to this PR.

35 changes: 35 additions & 0 deletions crates/macro/ui-tests/missing-catch.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,38 @@ error[E0277]: the trait bound `Result<wasm_bindgen::JsValue, wasm_bindgen::JsVal
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<wasm_bindgen::JsValue, wasm_bindgen::JsValue>: FromWasmAbi` is not satisfied
--> ui-tests/missing-catch.rs:3:1
|
3 | #[wasm_bindgen]
| ^^^^^^^^^^^^^^^ the trait `FromWasmAbi` is not implemented for `Result<wasm_bindgen::JsValue, wasm_bindgen::JsValue>`
|
= 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<wasm_bindgen::JsValue, wasm_bindgen::JsValue>: FromWasmAbi` is not satisfied
--> ui-tests/missing-catch.rs:6:18
|
6 | pub fn foo() -> Result<JsValue, JsValue>;
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromWasmAbi` is not implemented for `Result<wasm_bindgen::JsValue, wasm_bindgen::JsValue>`
|
= help: the following other types implement trait `FromWasmAbi`:
bool
char
isize
i8
i16
i32
i64
i128
and $N others
38 changes: 38 additions & 0 deletions crates/macro/ui-tests/traits-not-implemented.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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)
82 changes: 82 additions & 0 deletions crates/macro/ui-tests/unsupported-options.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
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) {}
pub fn static_method() {}

#[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) {}
pub fn static_method() {}

#[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) {}
}

pub struct NonWasmType;

#[wasm_bindgen]
impl NonWasmType {
pub fn static_method() {}
}

fn main() {}
Loading
Loading