wasm-bindgen
wasm-bindgen copied to clipboard
[BUG] only C-Style enums allowed with #[wasm_bindgen] / #[cfg] field not removed
Describe the Bug
Cannot use a #[cfg]
macro inside a #[wasm_bindgen]
enum ?
Steps to Reproduce
cargo new test-wasm-enum --lib
cd test-wasm-enum
replace lib.rs with:
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;
#[cfg_attr(target_arch = "wasm32", wasm_bindgen, repr(C))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
pub enum Operation {
INCREMENT,
DECREMENT,
#[cfg(not(target_arch = "wasm32"))]
CUSTOM(fn(i32) -> i32),
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
pub fn apply(op: Operation, x: i32) -> i32 {
match op {
Operation::INCREMENT => x + 1,
Operation::DECREMENT => x - 1,
#[cfg(not(target_arch = "wasm32"))]
Operation::CUSTOM(f) => f(x),
}
}
Then:
wasm-pack build
Expected Behavior
No errors
Actual Behavior
test-wasm $ wasm-pack build -t web --release
[INFO]: Checking for the Wasm target...
[INFO]: Compiling to Wasm...
Compiling proc-macro2 v1.0.51
Compiling quote v1.0.23
Compiling syn v1.0.107
Compiling wasm-bindgen-shared v0.2.84
Compiling log v0.4.17
Compiling wasm-bindgen-backend v0.2.84
Compiling wasm-bindgen-macro-support v0.2.84
Compiling wasm-bindgen-macro v0.2.84
Compiling wasm-bindgen v0.2.84
Compiling test-wasm v0.1.0 (/mnt/c/Users/Erwan/SynologyDrive/development/rust/test-wasm)
error: only C-Style enums allowed with #[wasm_bindgen]
--> src/lib.rs:10:11
|
10 | CUSTOM(fn(i32) -> i32),
| ^^^^^^^^^^^^^^^^
error[E0433]: failed to resolve: use of undeclared type `Operation`
--> src/lib.rs:16:9
|
16 | Operation::INCREMENT => x + 1,
| ^^^^^^^^^ use of undeclared type `Operation`
error[E0433]: failed to resolve: use of undeclared type `Operation`
--> src/lib.rs:17:9
|
17 | Operation::DECREMENT => x - 1,
| ^^^^^^^^^ use of undeclared type `Operation`
error[E0412]: cannot find type `Operation` in this scope
--> src/lib.rs:14:18
|
14 | pub fn apply(op: Operation, x: i32) -> i32 {
| ^^^^^^^^^ help: an enum with a similar name exists: `Option`
|
::: /home/aoc/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/option.rs:518:1
|
518 | pub enum Option<T> {
| ------------------ similarly named enum `Option` defined here
Some errors have detailed explanations: E0412, E0433.
For more information about an error, try `rustc --explain E0412`.
error: could not compile `test-wasm` due to 4 previous errors
Error: Compiling your crate to WebAssembly failed
Caused by: failed to execute `cargo build`: exited with exit status: 101
full command: "cargo" "build" "--lib" "--release" "--target" "wasm32-unknown-unknown"
When adding wasm_bindgen to my enum, it doesn't remove the cfg
I need to do:
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;
#[cfg(not(target_arch = "wasm32"))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
pub enum Operation {
INCREMENT,
DECREMENT,
CUSTOM(fn(i32) -> i32),
}
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
pub enum Operation {
INCREMENT,
DECREMENT,
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
pub fn apply(op: Operation, x: i32) -> i32 {
match op {
Operation::INCREMENT => x + 1,
Operation::DECREMENT => x - 1,
#[cfg(not(target_arch = "wasm32"))]
Operation::CUSTOM(f) => f(x),
}
}
Which is ugly...
Real work example: https://github.com/erwanvivien/fast_qr/blob/master/src/convert/mod.rs#L34
Any update on this?
This should be fairly easy to fix in the proc-macro. I'm happy to review a PR.
Never worked on proc-macro, I'll check and see if I can manage a PR
Hello @daxpedda
I'm trying to do so, but I don't think it's doable in the proc-macro tho 🤔
I feel like there are many edge cases where the cfg could remove the Variant from an enum etc
#[cfg(not(target_arch = "wasm32"))]
#[cfg_attr(target_arch = "wasm32", cfg(not(target_arch = "wasm32")))]
#[cfg(feature = "...")]
CUSTOM(fn(i32) -> i32),
There are many cases that needs to be handled and writing a function for each of those could be fragile
I think what you need to do here is to store any attributes that you find on a variant and emit them on every mention of that variant by the proc-macro.
You should definitely not parse the cfg
attribute, which can be very complex and there are cases that you simply couldn't cover.
Feel free to join us on Discord, where we can probably help you in more detail if you need it.