denoland/deno · error · syn::Error

Unit structs cannot be destructured

Error message

Unit structs cannot be destructured

What it means

ToV8 codegen destructures the value with 'let Self #fields = self;' so each field can be converted; destruct_fields handles named and unnamed fields but has no pattern for Fields::Unit, so a unit struct (struct Foo;) fails with this compile error at the fields' span. The derive cannot destructure what has no fields to bind.

Source

Thrown at libs/ops/conversion/to_v8/mod.rs:74

        {
          #(#fields),*
        }
      })
    }
    Fields::Unnamed(unnamed) => {
      let fields = unnamed.unnamed.iter().enumerate().map(|(i, field)| {
        let idx = syn::Index::from(i);
        let ident = format_ident!("__{i}", span = field.span());
        quote!(#idx: #ident)
      });

      Ok(quote! {
        {
          #(#fields),*
        }
      })
    }
    Fields::Unit => Err(Error::new(
      fields.span(),
      "Unit structs cannot be destructured",
    )),
  }
}

fn convert_or_serde<T: quote::ToTokens>(
  serde: bool,
  span: proc_macro2::Span,
  value: T,
) -> TokenStream {
  if serde {
    quote_spanned! { span =>
      ::deno_core::serde_v8::to_v8(
        __scope,
        #value,
      ).map_err(::deno_error::JsErrorBox::from_err)?
    }

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Remove the ToV8 derive from the unit type — it carries no data to convert.
  2. Give it a field or make it a newtype (struct Unit(())) so destruction has something to bind.
  3. Hand-write a ToV8 impl returning v8::undefined if the type must appear in an op signature.

Example fix

// before
#[derive(ToV8)]
struct Unit; // error: Unit structs cannot be destructured

// after
// drop the derive, or carry data:
#[derive(ToV8)]
struct Unit(u32);
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Deriving ToV8 on a unit struct: #[derive(ToV8)] struct Unit; used as an op return type or nested value.

Common situations: Marker types (state machines' PhantomData-like units) caught by blanket derives; stripping a struct's fields during a refactor while leaving #[derive(ToV8)] on it.

Related errors


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