swc-project/swc · error

#[derive(FromVariant)] requires all variants to be tuple wit

Error message

#[derive(FromVariant)] requires all variants to be tuple with exactly one field

What it means

Compile-time panic from `#[derive(FromVariant)]` (crates/from_variant). Each non-ignored variant must be a tuple variant with exactly one field, because the generated `From<T>` impl constructs `#ident::#variant_name(v)` with the single payload. A tuple variant whose unnamed field list has length != 1 panics at expansion.

Source

Thrown at crates/from_variant/src/lib.rs:61

    }: DeriveInput,
) -> Vec<ItemImpl> {
    let variants = match data {
        Data::Enum(DataEnum { variants, .. }) => variants,
        _ => panic!("#[derive(FromVariant)] only works for an enum."),
    };

    let mut from_impls: Vec<ItemImpl> = Vec::new();

    for v in variants {
        if is_ignored(&v.attrs) {
            continue;
        }

        let variant_name = v.ident;
        match v.fields {
            Fields::Unnamed(FieldsUnnamed { unnamed, .. }) => {
                if unnamed.len() != 1 {
                    panic!(
                        "#[derive(FromVariant)] requires all variants to be tuple with exactly \
                         one field"
                    )
                }
                let field = unnamed.into_iter().next().unwrap();

                let variant_type = &field.ty;

                let from_impl: ItemImpl = parse_quote!(
                    impl From<#variant_type> for #ident {
                        fn from(v: #variant_type) -> Self {
                            #ident::#variant_name(v)
                        }
                    }
                );

                let from_impl = from_impl.with_generics(generics.clone());

View on GitHub (pinned to 5176682b65)

Solutions

  1. Reduce the variant to a single field: `A(Expr)`
  2. Bundle extra data into one payload struct: `A(ExprWithSpan)`
  3. Exclude the variant with `#[from_variant(ignore)]` if it should not get a From impl

Example fix

// before
#[derive(FromVariant)]
enum Node {
    Expr(Expr, Span),
}

// after
#[derive(FromVariant)]
enum Node {
    Expr(Expr),
}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: `enum E { A(Expr, Span) }` or `enum E { A() }` with the derive applied; `unnamed.len() != 1` triggers the panic.

Common situations: Growing a variant to carry extra metadata (span, context) alongside its main payload while using FromVariant.

Related errors


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/91f26175634b0bd5. Report an issue: GitHub.