Skip to content

Fix string-enum codegen to compile against wasm-bindgen#30

Open
connyay wants to merge 2 commits into
wasm-bindgen:mainfrom
connyay:cjh-enum-fix
Open

Fix string-enum codegen to compile against wasm-bindgen#30
connyay wants to merge 2 commits into
wasm-bindgen:mainfrom
connyay:cjh-enum-fix

Conversation

@connyay

@connyay connyay commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

The string-enum output had never been compiled against wasm-bindgen. The snapshot tests only compare text, so several constructs slipped through that wasm-bindgen rejects. Surfaced while generating Cloudflare's Vectorize bindings (the $eq / $in metadata filter operators and the returnMetadata: boolean | <enum> union). Four fixes:

  • enums.rs: emit string enums in the discriminant form (Variant = "value") rather than a per-variant #[wasm_bindgen(js_name = "...")] attribute, which wasm-bindgen does not accept on enum variants.

  • typemap.rs: pass string/numeric enums by value in argument position. They lower to Copy enums whose IntoWasmAbi is implemented by value, so &Enum fails to satisfy IntoWasmAbi. Adds CodegenContext::value_enum_kind / resolves_to_value_enum and the ValueEnumKind type.

  • mod.rs: when a union member is a string/numeric enum, lower it to its JsString / Number wrapper. Value enums don't implement JsCast, so they can't be a wasm-bindgen union-enum payload directly, but the wrapper carries the same FFI value.

  • naming.rs: strip leading non-alphanumerics in to_enum_variant before PascalCasing, so $eq -> Eq and $in -> In (the latter also dodges the in keyword) instead of eq / r#in.

Snapshots re-blessed; only string-enum/union output changes.

The string-enum output had never been compiled against wasm-bindgen. The
snapshot tests only compare text, so several constructs slipped through that
wasm-bindgen rejects. Surfaced while generating Cloudflare's Vectorize bindings
(the `$eq` / `$in` metadata filter operators and the
`returnMetadata: boolean | <enum>` union). Four fixes:

- enums.rs: emit string enums in the discriminant form (`Variant = "value"`)
  rather than a per-variant `#[wasm_bindgen(js_name = "...")]` attribute, which
  wasm-bindgen does not accept on enum variants.

- typemap.rs: pass string/numeric enums by value in argument position. They
  lower to `Copy` enums whose `IntoWasmAbi` is implemented by value, so `&Enum`
  fails to satisfy `IntoWasmAbi`. Adds `CodegenContext::value_enum_kind` /
  `resolves_to_value_enum` and the `ValueEnumKind` type.

- mod.rs: when a union member is a string/numeric enum, lower it to its
  `JsString` / `Number` wrapper. Value enums don't implement `JsCast`, so they
  can't be a wasm-bindgen union-enum payload directly, but the wrapper carries
  the same FFI value.

- naming.rs: strip leading non-alphanumerics in `to_enum_variant` before
  PascalCasing, so `$eq` -> `Eq` and `$in` -> `In` (the latter also dodges the
  `in` keyword) instead of `eq` / `r#in`.

Snapshots re-blessed; only string-enum/union output changes.

@guybedford guybedford left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Great work, thank you.

Comment on lines 41051 to 41344
@@ -41558,7 +41168,7 @@ pub enum TlsClientAuthKind {
}
#[wasm_bindgen]
pub enum CountryKind {
Iso3166Alpha2Code(Iso3166Alpha2Code),
JsString(JsString),
T1 = "T1",
}
#[wasm_bindgen]
@@ -41730,7 +41340,7 @@ pub enum AttributeValueKind {
#[wasm_bindgen]
pub enum ReturnMetadataKind {
Bool(bool),
VectorizeMetadataRetrievalLevel(VectorizeMetadataRetrievalLevel),
JsString(JsString),
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

These seem to have been dropped somehow?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Iso3166Alpha2Code(Iso3166Alpha2Code) / VectorizeMetadataRetrievalLevel(VectorizeMetadataRetrievalLevel) don't impl JsCast so this code would fail to compile. This change lowers to JsString so it does compile.

error[E0277]: the trait bound `Iso3166Alpha2Code: TryFromJsValue` is not satisfied
   --> src/lib.rs:14:23
   14 |     Iso3166Alpha2Code(Iso3166Alpha2Code),
      |                       ^^^^^^^^^^^^^^^^^ unsatisfied trait bound
help: the trait `JsCast` is not implemented for `Iso3166Alpha2Code`
   = note: required for `Iso3166Alpha2Code` to implement `TryFromJsValue`

does this not seem right to you?

integration test caught that the fix wasnt applied
to module scoped enums
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants