pub unsafe trait GcSafe<'gc, Id: CollectorId>: Trace + TrustedDrop {
    unsafe fn trace_inside_gc<V>(
        gc: &mut Gc<'gc, Self, Id>,
        visitor: &mut V
    ) -> Result<(), V::Err>
    where
        V: GcVisitor
; }
Expand description

A marker trait correlating all garbage collected pointers corresponding to the specified Id are valid for the 'gc lifetime.

If this type is implemented for a specific CollectorId Id, it indicates the possibility of containing pointers belonging to that collector.

If a type is NullTrace, it should implement GcSafefor all possible collectors. However, if a typeNEEDS_TRACE`, it will usually only implement GcSafe for the specific CollectorIds it happens to contain (although this is not guarenteed).

Mixing with other lifetimes

Note that T: GcSafe<'gc, T> does not necessarily imply T: 'gc. This allows a garbage collected lifetime to contain shorter lifetimes

For example,

#[derive(Trace)]
#[zerogc(ignore_lifetimes("'a"), collector_ids(CollectorId))]
struct TempLifetime<'gc, 'a> {
    temp: &'a i32,
    gc: Gc<'gc, i32>
}
fn alloc_ref_temp<'gc>(ctx: &'gc GcContext, long_lived: Gc<'gc, i32>) {
    let temp = 5; // Lives for 'a (shorter than 'gc)
    let temp_ref = ctx.alloc(TempLifetime {
        temp: &temp, gc: long_lived
    });
    assert_eq!(&temp as *const _, temp_ref.temp as *const _)
}

Mixing collectors

The Id parameter allows mixing and matching pointers from different collectors, each with their own ’gc lifetime. For example,

#[derive(Trace)]
struct MixedGc<'gc, 'js> {
    internal_ptr: Gc<'gc, i32, OtherGcId>,
    js_ptr: Gc<'js, i32, JsGcId>
}
impl<'gc, 'js> MixedGc<'gc, 'js> {
    fn verify(&self) {
        assert!(<Self as GcSafe<'gc, OtherGcId>>::assert_gc_safe());
        assert!(<Self as GcSafe<'js, JsGcId>>::assert_gc_safe());
        // NOT implemented: <Self as GcSafe<'gc, ThirdId>>
    }
}

Safety

In addition to the guarantees of Trace and TrustedDrop, implementing this type requires that all Gc pointers of the specified Id have the 'gc lifetime (if there are any at all).

Required methods

Trace this object behind a Gc pointer.

This is required to delegate to one of the following methods on GcVisitor:

  1. GcVisitor::trace_gc - For regular, Sized types
  2. GcVisitor::trace_array - For slices and arrays
  3. GcVisitor::trace_trait_object - For trait objects
Safety

This must delegate to the appropriate method on GcVisitor, or undefined behavior will result.

The user is required to supply an appropriate Gc pointer.

Implementations on Foreign Types

Implementors