macro_rules! trait_object_trace {
    (impl $(<$($lt:lifetime,)* $($param:ident),*>)? Trace for dyn $target:path $({ where $($where_clause:tt)* })?;
        Branded<$branded_lt:lifetime> => $branded:ty,
        collector_id => $collector_id:path,
        gc_lifetime => $gc_lt:lifetime) => { ... };
}
Expand description

Implement Trace for a dynamically dispatched trait object

This requires that the trait object extends DynTrace.

Example

trait Foo<'gc>: DynTrace<'gc, OurSpecificId> {
    fn method(&self) -> i32;
}
trait_object_trace!(
    impl<'gc,> Trace for dyn Foo<'gc>;
    Branded<'new_gc> => (dyn Foo<'new_gc> + 'new_gc),
    collector_id => OurSpecificId,
    gc_lifetime => 'gc
);
fn foo<'gc, T: ?Sized + Trace + Foo<'gc>>(t: &T) -> i32 {
    assert_eq!(t.method(), 12);
    t.method() * 2
}
fn bar<'gc>(gc: Gc<'gc, dyn Foo<'gc> + 'gc>) -> i32 {
    foo(gc.value())
}
#[derive(Trace)]
struct Bar<'gc> {
    val: Gc<'gc, i32>
}
impl<'gc> Foo<'gc> for Bar<'gc> {
    fn method(&self) -> i32 {
       *self.val
    }
}
let val = epsilon::leaked(12);
let gc: Gc<'_, Bar<'_>> = epsilon::leaked(Bar { val });
assert_eq!(bar(gc as Gc<'_, dyn Foo>), 24);

Safety

This macro is completely safe.