{"record":{"id":"b67f5e98ca874e38","repo":"denoland/deno","slug":"first-field-must-be-the-base-type-for-cppgc-inheri","errorCode":null,"errorMessage":"first field must be the base type for cppgc inheritance","messagePattern":"first field must be the base type for cppgc inheritance","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"libs/ops/cppgc.rs","lineNumber":70,"sourceCode":"    .predicates\n    .push(parse_quote!(__TransitiveBase: deno_core::cppgc::Base));\n\n  ensure_repr_c(&attrs, ident.span())?;\n\n  let first_field = first_field(&data).ok_or_else(|| {\n    Error::new(\n      ident.span(),\n      \"cppgc inheritance requires at least one field\",\n    )\n  })?;\n\n  let (field_path, field_ty_span) = match &first_field.field {\n    FieldRef::Named(ident, ty_span) => (quote!(#ident), *ty_span),\n    FieldRef::Unnamed(idx, ty_span) => (quote!(#idx), *ty_span),\n  };\n\n  if !types_equal(&first_field.ty, &base) {\n    return Err(Error::new(\n      field_ty_span,\n      \"first field must be the base type for cppgc inheritance\",\n    ));\n  }\n\n  let (transitive_impl_generics, _, transitive_where_clause) =\n    impl_generics.split_for_impl();\n  let (base_impl_generics, base_ty_generics, base_where_clause) =\n    generics.split_for_impl();\n\n  let offset_assert = quote! {\n    const _: () = {\n      const OFFSET: usize = ::core::mem::offset_of!(#ident #base_ty_generics, #field_path);\n      assert!(OFFSET == 0, \"base field must be at offset 0\");\n    };\n  };\n  let size_align_assert = quote! {\n    const _: () = {","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/libs/ops/cppgc.rs#L52-L88","documentation":"After finding the first field, the CppgcInherits derive verifies its type is exactly the base named in #[cppgc_inherits_from(Base)] (types_equal check) because the generated offset/layout code assumes field 0 IS the base subobject. A first field of any other type — or the right base placed second — fails with this compile error pointing at the field's type span.","triggerScenarios":"struct Rectangle { width: GcCell<f64>, base: Shape } (base not first), or struct Rectangle { shape: Shape, ... } where the field is named differently than the attribute's type — the check is on the field's TYPE, so any first field whose type is not the exact #[cppgc_inherits_from(...)] argument triggers it.","commonSituations":"Reordering fields (Rust allows any order; the derive does not); renaming the base type or the attribute argument so they no longer match textually; using a type alias or wrapper (Box<Shape>) instead of the bare base type.","solutions":["Move the base to be the literal first field: struct Rectangle { base: Shape, width: GcCell<f64> }.","Make the first field's type token-for-token the same type you passed to #[cppgc_inherits_from(...)] — no aliases, references, or Boxes.","If you changed the base type, update #[cppgc_inherits_from(...)] and #[op2(inherit = ...)] to match."],"exampleFix":"// before\n#[derive(CppgcInherits)]\n#[cppgc_inherits_from(Shape)]\n#[repr(C)]\npub struct Rectangle {\n  width: GcCell<f64>, // error: first field must be the base type for cppgc inheritance\n  base: Shape,\n}\n\n// after\n#[derive(CppgcInherits)]\n#[cppgc_inherits_from(Shape)]\n#[repr(C)]\npub struct Rectangle {\n  base: Shape, // first field, exact base type\n  width: GcCell<f64>,\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always put the base field first and type it exactly as the #[cppgc_inherits_from(...)] argument — no aliases, boxes, or references.","When renaming a base type, update the derive attribute, the first field's type, and #[op2(inherit = ...)] in one commit."],"tags":["proc-macro","cppgc","inheritance","field-order","compile-time","deno-core"],"backgroundTag":"cppgc-inheritance-misuse","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}