kyren / gc-arena

Incremental garbage collection from safe Rust
Creative Commons Zero v1.0 Universal
438 stars 36 forks source link

Define a single `Arena` struct and generate a type alias in `make_arena` #18

Closed Aaron1011 closed 1 year ago

Aaron1011 commented 1 year ago

Surprisingly, this doesn't require GATs, and is actually simpler than a GAT-based solution. The core idea is to define a trait:

pub trait RootProvider<'a> {
    type Root: Collect;
}

In Arena, we use the higher-ranked trait bound R: for<'a> RootProvider<'a>. Then, writing <R as RootProvider<'gc>>::Root gives us the root type with some arbitrary lifetime 'gc substituted.

The make_arena macro can then simply declare the type alias type MyArenaName = Arena<dyn for<'a> RootProvider<'a, Root = UserRoot<'a>>>

Since a RootProvider trait object implements RootProvider, the projection <R as RootProvider<'gc>>::Root will evaluate to UserRoot<'gc>, without the need to define any additional structs or trait impls.

kyren commented 1 year ago

Oh yeah, that's a super good solution! Thank you so much!

I think we can make the Context type pub(crate) now, right? And all of the methods on it? It was only public to allow for the way the old make_arena! macro worked.

Aaron1011 commented 1 year ago

@kyren I've changed the visibility of Context

kyren commented 1 year ago

Awesome, thank you! I'm cool with merging this if you are.