{"record":{"id":"a59514ff136aac74","repo":"denoland/deno","slug":"cppgc-inheritance-requires-repr-c-on-the-type","errorCode":null,"errorMessage":"cppgc inheritance requires #[repr(C)] on the type","messagePattern":"cppgc inheritance requires #\\[repr\\(C\\)\\] on the type","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"libs/ops/cppgc.rs","lineNumber":161,"sourceCode":"}\n\nfn ensure_repr_c(attrs: &[Attribute], span: proc_macro2::Span) -> Result<()> {\n  for attr in attrs {\n    if !attr.path().is_ident(\"repr\") {\n      continue;\n    }\n    if let Meta::List(list) = &attr.meta {\n      let nested: Punctuated<Meta, Token![,]> =\n        list.parse_args_with(Punctuated::parse_terminated)?;\n      if nested\n        .iter()\n        .any(|meta| matches!(meta, Meta::Path(path) if path.is_ident(\"C\")))\n      {\n        return Ok(());\n      }\n    }\n  }\n  Err(Error::new(\n    span,\n    \"cppgc inheritance requires #[repr(C)] on the type\",\n  ))\n}\n\nfn parse_base_attr(attrs: &[Attribute]) -> Result<Type> {\n  let mut found = None;\n  for attr in attrs {\n    if !attr.path().is_ident(\"cppgc_inherits_from\") {\n      continue;\n    }\n    if found.is_some() {\n      return Err(Error::new(\n        attr.span(),\n        \"cppgc_inherits_from specified more than once\",\n      ));\n    }\n    let base = attr.parse_args::<Type>()?;","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/libs/ops/cppgc.rs#L143-L179","documentation":"The CppgcInherits derive emits compile-time offset assertions that rely on a stable C layout, so the target type must be #[repr(C)]. ensure_repr_c scans the type's attributes and only accepts a bare #[repr(C)] or a repr list containing C (e.g. #[repr(C, packed)]); anything else — no repr, #[repr(u8)], #[repr(Rust)] — yields this compile error.","triggerScenarios":"Declaring a derived cppgc class without a repr attribute, or with a non-C repr like #[repr(u8)] or #[repr(transparent)], under #[derive(CppgcInherits)] #[cppgc_inherits_from(...)].","commonSituations":"Converting an existing repr-Rust struct into a cppgc base/derived class and forgetting the layout attribute; enum-like reprs copy-pasted onto the struct; multi-level inheritance where an intermediate type was never marked.","solutions":["Add #[repr(C)] directly above the struct: #[derive(CppgcInherits)] #[cppgc_inherits_from(Base)] #[repr(C)] struct Derived { base: Base, ... }.","In multi-level chains, verify every type in the chain (base and derived) carries #[repr(C)], as the offset assertions walk the whole chain."],"exampleFix":"// before\n#[derive(CppgcInherits)]\n#[cppgc_inherits_from(Shape)]\npub struct Rectangle { // error: cppgc inheritance requires #[repr(C)] on the type\n  base: Shape,\n}\n\n// after\n#[derive(CppgcInherits)]\n#[cppgc_inherits_from(Shape)]\n#[repr(C)]\npub struct Rectangle {\n  base: Shape,\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Add #[repr(C)] at the moment you add #[derive(CppgcInherits)], not later — the layout is load-bearing for the offset assertions.","In multi-level inheritance chains, check every type (base, intermediates, derived) carries #[repr(C)]."],"tags":["proc-macro","cppgc","inheritance","repr-c","layout","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"}