Macro zerogc::trait_object_trace
source · [−]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.