kyren / gc-arena

Incremental garbage collection from safe Rust

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Overflow on recursive struct

puckipedia opened this issue · comments

#[derive(gc_arena::Collect)]
#[collect(no_drop)]
struct Test<'gc, T>(Option<gc_arena::Gc<'gc, Test<'gc, T>>>);

This seems to be because Gc<T> requires T to be Collect, but that depends on Gc<T> being Collect. I'm not sure on how this would be fixed, if even possible.

Just to be clear (I haven't tried this), is it the automatic Collect implementation that triggers an error? During compilation?

Indeed. Error trace is:

error[E0275]: overflow evaluating the requirement `gc_arena::gc::Gc<'_, Test<'_, T>>: std::marker::Sized`
 --> src/main.rs:3:21
  |
3 | struct Test<'gc, T>(Option<gc_arena::Gc<'gc, Test<'gc, T>>>);
  |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = help: consider adding a `#![recursion_limit="256"]` attribute to your crate
  = note: required because of the requirements on the impl of `gc_arena::collect::Collect` for `std::option::Option<gc_arena::gc::Gc<'_, Test<'_, T>>>`
  = note: required because of the requirements on the impl of `gc_arena::collect::Collect` for `Test<'_, T>`
  = note: required because of the requirements on the impl of `gc_arena::collect::Collect` for `gc_arena::gc::Gc<'_, Test<'_, T>>`
[... above three lines repeat a bunch of times]
  = note: required because of the requirements on the impl of `gc_arena::collect::Collect` for `std::option::Option<gc_arena::gc::Gc<'_, Test<'_, T>>>`
  = note: required because of the requirements on the impl of `gc_arena::collect::Collect` for `Test<'gc, T>`
  = note: required by `gc_arena::gc::Gc`

You can work around this by replacing the direct recursion with Self. (I’ve added a T field because T has to be used somewhere.)

#[derive(gc_arena::Collect)]
#[collect(no_drop)]
struct Test<'gc, T>(T, Option<gc_arena::Gc<'gc, Self>>)
where
    T: gc_arena::Collect + 'gc;

I think this is fixed by #23!