denoland/deno · error · syn::Error
cppgc_inherits_from specified more than once
Error message
cppgc_inherits_from specified more than once
What it means
Thrown by the `CppgcInherits` derive macro (deno_core's cppgc garbage-collector bridge). `parse_base_attr` in libs/ops/cppgc.rs scans the type's attributes for `#[cppgc_inherits_from(Base)]`, stores the first match, and raises this compile error on the span of any second occurrence because a cppgc-managed type can declare exactly one C++ base class.
Source
Thrown at libs/ops/cppgc.rs:174
{
return Ok(());
}
}
}
Err(Error::new(
span,
"cppgc inheritance requires #[repr(C)] on the type",
))
}
fn parse_base_attr(attrs: &[Attribute]) -> Result<Type> {
let mut found = None;
for attr in attrs {
if !attr.path().is_ident("cppgc_inherits_from") {
continue;
}
if found.is_some() {
return Err(Error::new(
attr.span(),
"cppgc_inherits_from specified more than once",
));
}
let base = attr.parse_args::<Type>()?;
found = Some(base);
}
found.ok_or_else(|| {
Error::new(
proc_macro2::Span::call_site(),
"derive(CppgcInherits) requires #[cppgc_inherits_from(BaseType)]",
)
})
}
#[derive(Clone)]
enum FieldRef {
Named(Ident, proc_macro2::Span),View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Delete all but one `#[cppgc_inherits_from(...)]` attribute on the type, keeping the direct base you actually wrap.
- If the type genuinely needs two bases, introduce an intermediate Rust/C++ base type that itself derives `CppgcInherits` from the grandparent, and inherit from that single intermediate.
- After a merge conflict, grep the file for `cppgc_inherits_from` and make sure only one attribute survives.
Example fix
// before
#[derive(CppgcInherits, CppgcBase)]
#[cppgc_inherits_from(DOMPointReadOnly)]
#[cppgc_inherits_from(CSSStyleValue)]
struct DOMPoint { /* ... */ }
// after
#[derive(CppgcInherits, CppgcBase)]
#[cppgc_inherits_from(DOMPointReadOnly)]
struct DOMPoint { /* ... */ } Defensive patterns
Strategy: validation
Validate before calling
# In CI or a pre-commit check, flag types with more than one cppgc_inherits_from:
# (grep-based guard; the real enforcement is the compile error itself)
! grep -rn --include='*.rs' -E '^[[:space:]]*#\[cppgc_inherits_from' path/to/file | awk -F: '{print $1}' | uniq -c | awk '$1 > 1 { exit 1 }' Prevention
- Treat `#[cppgc_inherits_from(...)]` as appearing exactly once per type; make that an explicit convention in your code review checklist.
- After merge conflicts in cppgc types, grep for `cppgc_inherits_from` and keep only one attribute.
When it happens
Trigger: Annotating one type with two `#[cppgc_inherits_from(...)]` helper attributes: `#[derive(CppgcInherits)] #[cppgc_inherits_from(A)] #[cppgc_inherits_from(B)] struct X;` — the error span points at the duplicate attribute.
Common situations: Copy-pasting an existing cppgc type (e.g. the DOMPoint example in ext/web/geometry.rs) and adding a new base without removing the old attribute; merge conflicts that leave both versions of the attribute; attempting multiple inheritance, which cppgc does not support.
Related errors
- derive(CppgcInherits) requires #[cppgc_inherits_from(BaseTyp
- cppgc inheritance requires at least one field
- first field must be the base type for cppgc inheritance
- cppgc inheritance requires #[repr(C)] on the type
- Unnamed fields are currently not supported
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/adb1b4df340330ad.
Report an issue: GitHub.