#[derive(JSTraceable)]
{
// Attributes available to this derive:
#[no_trace]
#[custom_trace]
}
Expand description
Implements JSTraceable
on structs and enums
Example:
#[derive(JSTraceable)]
struct S {
js_managed: JSManagedType,
#[no_trace]
non_js: NonJSManagedType,
#[custom_trace] // Extern type implements CustomTraceable that is in servo => no problem with orphan rules
extern_managed_type: Extern<JSManagedType>,
}
creates:
unsafe impl JSTraceable for S {
#[inline]
unsafe fn trace(&self, tracer: *mut js::jsapi::JSTracer) {
match *self {
S {
js_managed: ref __binding_0,
non_js: ref __binding_1,
extern_managed_type: ref __binding_2,
} => {
{
__binding_0.trace(tracer);
}
{
// __binding_1 is not traceable so we do not need to trace it
}
{
<crate::dom::bindings::trace::CustomTraceable>::trace(__binding_2, tracer);
}
},
}
}
}
In cases where there is a need to make type (empty) traceable (HashMap<NoTraceable, Traceable>
),
NoTrace wrapper can be used, because it implements empty traceble:
unsafe impl<T> JSTraceable for NoTrace<T> {
unsafe fn trace(&self, _: *mut ::js::jsapi::JSTracer) { /* nop */}
}
ยงSAFETY
Puting #[no_trace]
on fields is safe if there are no types that are JS managed in that field.
#[no_trace]
should NOT be put on field that does implement (non-empty) JSTraceable
(is JS managed).
There are safeguards in place to prevent such mistakes. Example error:
error[E0282]: type annotations needed
|
| #[derive(JSTraceable, MallocSizeOf)]
| ^^^^^^^^^^^ cannot infer type of the type parameter `Self` declared on the trait `NoTraceOnJSTraceable`
|
= note: this error originates in the derive macro `JSTraceable`
If you can assure that type has empty JSTraceable impl, you can bypass guards, providing your reasoning:
#[derive(JSTraceable)]
struct S {
#[no_trace = "Safe because both u32 and u64 are empty traceable"]
field: HashMap<u32, u64>,
}