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

[BUG] only C-Style enums allowed with #[wasm_bindgen] / #[cfg] field not removed #3297

Open
erwanvivien opened this issue Feb 12, 2023 · 6 comments
Labels

Comments

@erwanvivien
Copy link
Contributor

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...

@erwanvivien
Copy link
Contributor Author

@erwanvivien
Copy link
Contributor Author

Any update on this?

@daxpedda
Copy link
Collaborator

This should be fairly easy to fix in the proc-macro. I'm happy to review a PR.

@erwanvivien
Copy link
Contributor Author

Never worked on proc-macro, I'll check and see if I can manage a PR

@erwanvivien
Copy link
Contributor Author

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

erwanvivien added a commit to erwanvivien/wasm-bindgen that referenced this issue Jun 25, 2023
provides a way to avoid havind this error:
only C-Style enums allowed with #[wasm_bindgen]

```rust
\#[wasm_bindgen]
pub enum Operation {
    INCREMENT,

    #[cfg(not(target_arch = "wasm32"))]
    #[wasm_bindgen(skip)]
    CUSTOM(fn(i32) -> i32),
}
```
@daxpedda
Copy link
Collaborator

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.

erwanvivien added a commit to erwanvivien/wasm-bindgen that referenced this issue Jun 25, 2023
provides a way to avoid having this error:
only C-Style enums allowed with #[wasm_bindgen]

```rust
\#[wasm_bindgen]
pub enum Operation {
    INCREMENT,

    #[cfg(not(target_arch = "wasm32"))]
    #[wasm_bindgen(skip)]
    CUSTOM(fn(i32) -> i32),
}
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants