#[derive(Trace)]
{
// Attributes available to this derive:
#[rust_cc]
}
derive
only.Expand description
Derive macro for safely deriving Trace
implementations.
The derived implementation calls the trace
method on every field of the implementing type.
§Ignoring fields
The #[rust_cc(ignore)]
attribute can be used to avoid tracing a field (or variant, in case of an enum).
This may be useful, for example, if the field’s type doesn’t implement Trace
, like external library types or some types from std.
Not tracing a field is safe, although it may lead to memory leaks if the ignored field contains any Cc
.
§Automatic Drop
implementation
This macro enforces the Drop
-related safety requirements of Trace
by always emitting an empty Drop
implementation for the implementing type.
The #[rust_cc(unsafe_no_drop)]
attribute can be used to suppress the automatic Drop
implementation, allowing to implement a custom one. Using this attribute
is considered unsafe and must respect the safety requirements of Trace
.
Safe alternatives to #[rust_cc(unsafe_no_drop)]
are finalizers and cleaners.
§Example
#[derive(Trace)]
struct Foo<A: Trace + 'static, B: Trace + 'static> {
a_field: Cc<A>,
another_field: Cc<B>,
}
Ignoring a field:
#[derive(Trace)]
struct Foo<T: Trace + 'static> {
traced_field: Cc<T>,
#[rust_cc(ignore)] // Cell doesn't implement Trace, let's ignore it
ignored_field: Cell<i32>, // ignored_field doesn't contain any Cc, so there will be no memory leak
}
#[derive(Trace)]
enum Bar<T: Trace + 'static> {
#[rust_cc(ignore)] // Ignores the A variant
A {
// ...
},
B(Cc<T>, #[rust_cc(ignore)] Cell<u32>), // Only the Cell is ignored
}
Implementing a custom Drop
implementation:
#[derive(Trace)]
#[rust_cc(unsafe_no_drop)] // UNSAFE!!!
struct Foo {
// ...
}
impl Drop for Foo {
fn drop(&mut self) {
// MUST respect the safety requirements of Trace
}
}