Expand description
Proc-macro derives for bun_css.
#[derive(DeepClone)] is the compile-time port of Zig’s
css.implementDeepClone(@This(), this, allocator) (src/css/generics.zig).
The Zig original is @typeInfo(T) reflection that walks struct fields /
union variants and calls .deepClone(allocator) on each. Rust has no
reflection, so the derive emits the equivalent field-wise / variant-wise
recursion as an impl bun_css::generics::DeepClone<'bump> for T.
The generated body uses UFCS dispatch
(::bun_css::generics::DeepClone::deep_clone(&field, bump)), so the call
resolves only through the trait — never an inherent. This sidesteps Rust’s
method-probe rule that selects an inherent by name only (and would
otherwise let an unrelated Vec::deep_clone(&self) -> Result<_,_>
shadow the blanket impl DeepClone for Vec<T> and fail E0061).
Consequence: every leaf type reached by a derive must carry a real
DeepClone (or CssEql/CssHash/IsCompatible) trait impl — an
inherent pub fn deep_clone alone is no longer sufficient. The blanket
impls in bun_css::generics cover Option, Vec, Box, slices, primitives,
SmallList, Vec, …; everything else derives or hand-implements the
trait.
Generics handling:
- If the deriving type already carries a lifetime parameter, the first
one is reused as the arena lifetime (
DeepClone<'that>). Every CSS AST type that borrows from the parser arena threads exactly one'bump. - Otherwise a fresh
'__bumpis introduced on the impl. - Each type parameter
Tgets aT: DeepClone<'bump>where-bound so generic containers likeCssRule<R>constrain their payload.