denoland/deno · error · syn::Error

cppgc inheritance requires at least one field

Error message

cppgc inheritance requires at least one field

What it means

#[derive(CppgcInherits)] with #[cppgc_inherits_from(Base)] models C++-style inheritance by embedding the base as the first field; the derive grabs that first field to build the transitive-base plumbing (field_path/field_ty_span used for the offset assertions). If the struct has no fields at all, first_field() returns None and this compile error fires on the type's span — an empty struct cannot inherit anything.

Source

Thrown at libs/ops/cppgc.rs:58

    attrs,
    ..
  } = input;

  let base = parse_base_attr(&attrs)?;
  let mut impl_generics = generics.clone();
  impl_generics.params.push(parse_quote!(__TransitiveBase));
  let where_clause = impl_generics.make_where_clause();
  where_clause
    .predicates
    .push(parse_quote!(#base: deno_core::cppgc::Inherits<__TransitiveBase>));
  where_clause
    .predicates
    .push(parse_quote!(__TransitiveBase: deno_core::cppgc::Base));

  ensure_repr_c(&attrs, ident.span())?;

  let first_field = first_field(&data).ok_or_else(|| {
    Error::new(
      ident.span(),
      "cppgc inheritance requires at least one field",
    )
  })?;

  let (field_path, field_ty_span) = match &first_field.field {
    FieldRef::Named(ident, ty_span) => (quote!(#ident), *ty_span),
    FieldRef::Unnamed(idx, ty_span) => (quote!(#idx), *ty_span),
  };

  if !types_equal(&first_field.ty, &base) {
    return Err(Error::new(
      field_ty_span,
      "first field must be the base type for cppgc inheritance",
    ));
  }

  let (transitive_impl_generics, _, transitive_where_clause) =

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Add the base field first, exactly as the derive requires: struct Square { base: Shape } — the base type named in #[cppgc_inherits_from(...)].
  2. If the type is not meant to inherit, remove #[derive(CppgcInherits)] and the #[cppgc_inherits_from] attribute.

Example fix

// before
#[derive(CppgcInherits)]
#[cppgc_inherits_from(Shape)]
#[repr(C)]
pub struct Square; // error: cppgc inheritance requires at least one field

// after
#[derive(CppgcInherits)]
#[cppgc_inherits_from(Shape)]
#[repr(C)]
pub struct Square {
  base: Shape,
}
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Declaring #[derive(CppgcInherits)] #[cppgc_inherits_from(Shape)] struct Square; (or struct Square {}) — a derived cppgc class with zero fields.

Common situations: Starting to port a JS-exposed native class and stubbing the struct empty before adding the base field; deleting all fields during a refactor and forgetting the derive now needs a base.

Related errors


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