denoland/deno · error · syn::Error

variants with fields are not allowed for enum converters

Error message

variants with fields are not allowed for enum converters

What it means

WebIDL enums are string enumerations — each variant maps to a string value. `get_variant_name` in libs/ops/webidl/enum.rs therefore rejects any variant that carries fields (tuple or struct variants), with the error on the variant's field span.

Source

Thrown at libs/ops/webidl/enum.rs:62

  let as_str = quote! {
    impl #ident {
      pub fn as_str(&self) -> &'static str {
        match self {
          #(Self::#idents => #names),*,
        }
      }
    }
  };

  Ok((impl_body, as_str))
}

fn get_variant_name(value: Variant) -> Result<(String, Ident), Error> {
  let mut rename: Option<String> = None;

  if !value.fields.is_empty() {
    return Err(Error::new(
      value.fields.span(),
      "variants with fields are not allowed for enum converters",
    ));
  }

  for attr in value.attrs {
    if attr.path().is_ident("webidl") {
      let list = attr.meta.require_list()?;
      let args = list.parse_args_with(
        Punctuated::<EnumVariantArgument, Token![,]>::parse_terminated,
      )?;

      for argument in args {
        match argument {
          EnumVariantArgument::Rename { value, .. } => {
            rename = Some(value.value())
          }
        }

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Strip the fields so every variant is a plain unit variant; WebIDL enums are sets of string values only.
  2. If you need data-carrying variants, model them as a dictionary with a discriminator field, or write the conversion manually instead of `#[webidl(enum)]`.
  3. Use `#[webidl(rename = "...")]` on variants when the JS string must differ from the Rust name.

Example fix

// before
#[derive(WebIDL)]
#[webidl(enum)]
enum Shape { Circle, Rect { w: f64, h: f64 } }

// after
#[derive(WebIDL)]
#[webidl(enum)]
enum Shape { Circle, Rect }
Defensive patterns

Strategy: validation

Validate before calling

// Compile-time: `cargo check`. Keep every variant of a #[webidl(enum)] enum
// a unit variant; use #[webidl(rename = "...")] for custom JS strings.

Prevention

When it happens

Trigger: `#[derive(WebIDL)] #[webidl(enum)] enum Msg { Plain, Wrapped(u8), Named { x: u8 } }` — the `Wrapped` and `Named` variants trigger this error; only `Plain`-style unit variants are allowed.

Common situations: Trying to reuse a Rust sum type (data-carrying enum) as a WebIDL enum converter; adding a payload to a variant of an already-converted enum.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/726ee67e5b21aea4. Report an issue: GitHub.