pub trait Trace: 'static {
    fn trace(&self, tracer: &mut Tracer<'_>) { ... }
    fn is_type_tracked() -> bool
    where
        Self: Sized
, { ... } }
Expand description

Defines how the cycle collector should collect a type.

Customized Drop implementation

The Drop implementation should avoid dereferencing other [Cc<T>] objects. Failing to do so might cause panic or undefined behavior. For example, T1 has a field Cc<T2>. The collector might have already dropped T2 by the time T1::drop runs.

The Drop implementation should also be careful about cloning (resurrecting) [Cc<T>] objects. If it must do so, the trace implementation should match by avoiding visiting those cloned objects.

The 'static bound

Types tracked by the collector can potentially be kept alive forever. Therefore types with non-static references are not allowed.

Provided Methods

Define how to visit values referred by this value.

For example, if self.x is a value referred by self, call self.x.trace(tracer) to visit it.

The values that are visited must match the Drop::drop implementation. Otherwise memory leak or panic might happen. After the panic, dereferencing already collected Cc<T> can trigger:

  • Undefined behavior on release build.
  • Another panic on debug build.

Ideally this can be generated by the compiler, since the compiler already knows how to generate Drop::drop.

Whether this type should be tracked by the collector.

Types that might include Cc<T> where T can form a cycle should be tracked. This allows the collector to visit the Cc values from its parents and count references correctly.

If a type T is tracked, Cc<T> will be 3 usize larger and the collector will check them.

For example,

  • Vec<u8> is not tracked. It does include any kind of Cc<T>.
  • Box<Cc<u8>> is not tracked. It includes Cc<u8> but u8 cannot create cycles.
  • Box<dyn Trace> is tracked. The trait object can be anything, including any kinds of types that contains a Cc<T>.

Usually, concrete Rust types can opt-out the cycle collector. There are a few exceptions:

  • Trait objects, and types containing trait objects. Trait objects can be anything so they should be tracked.
  • Recursive types. Such as, struct S(RefCell<Option<Rc<Box<S>>>>). Those types need an explicit name like S, and a manual implementation of the Trace trait. That implementation should make is_type_tracked return true directly.

This is an optimization for performance. When in-doubt, return true for correctness.

Trait Implementations

Define how to visit values referred by this value. Read more

Whether this type should be tracked by the collector. Read more

Define how to visit values referred by this value. Read more

Whether this type should be tracked by the collector. Read more

Define how to visit values referred by this value. Read more

Whether this type should be tracked by the collector. Read more

Implementations on Foreign Types

Implementors