First readme example is confusing
frankmcsherry opened this issue · comments
The first example in README.md
is
#[macro_use]
extern crate gc_derive;
extern crate gc;
use gc::Gc;
#[derive(Trace, Finalize)]
struct Foo {
x: Gc<Foo>,
y: u8,
// ...
}
// now, `Gc<Foo>` may be used
Though it has caused some confusion because how can you construct an instance of Foo
(safely)? Perhaps the type of x
should be Option<Gc<Foo>>
?
Yes, it would be impossible to construct an instance of Foo
safely. I would definitely merge a PR which fixes this example, or I can fix it when I get the time :).
#54 is the PR you are looking for. ;)
Looks like this can be closed now.
Related question... how can I create a cycle like that? I'm making an interpreted language where... Every value has a type (type will never be null, so I don't want to make type an option). Additionally, types themselves are values. The type of a type value is the value type
. type
, being a value, also has a type. That type has to be type
.
This is the only situation I'll need to do this, so I don't mind doing something a bit scary.
A good way to describe the problem is... We can't create a val at all, until we have a val to put in its type field.
let mut type_type = unsafe{
Gc::new(Varl((Val{ ty: uninitialized(), v: Void })))
};
unsafe{
forget(replace(&mut (*type_type.0.get()).ty, type_type.clone()));
}
This compiles, but it's segfaulting.
Perhaps I should just accept that the structure Gc<Varl(UnsafeCell<Val>)>
is already so ugly that adding a MaybeUninit or an Option that is never None isn't that much of an additional burden, then keep all of that wrapped away.