cell-gc 0.1.2

A fun garbage collector for that virtual machine you're writing in Rust
Documentation
Things to do:

-   support multiple pages of objects (#4)

-   fix nested heap structs (no tests, ergo it's broken)

-   usability
    -   write a longer Tree example and see if the thing is the slightest bit usable
    -   having a struct as a field of a struct (like `children: Vec<ObjectRef>`)
        is possible but not very useful without interior references. Given

            struct Point / PointRef / PointInHeap {
                x: u32,
                y: u32
            }

            struct Rect / RectRef / RectInHeap {
                top_left: Point,
                bottom_right: Point
            }

        RectRef::top_left() should return a reference to that PointInHeap
        embedded in the RectInHeap allocation.

    -   compatibility with the `custom_derive!` crate

-   move toward a stable API
    -   remove the RefStorage type
    -   rename `Heap -> GCHeap`, `with_heap -> with_gc_heap`
        or maybe just `GC` and `with_gc`
    -   decide which is better: `X / RefX / InHeapX/ InHeapRefX`
        or `X / XRef / XStorage / XRefStorage`
        and convert all the examples and tests :-P
    -   figure out if any of this stuff needs to be `!Send` or `!Sync`
    -   macros: allow (and probably require) explicitly providing the desired `#[derive]`
        attributes for the "main" type, to avoid errors deriving Clone and Debug in tests
        where they aren't even wanted

-   documentation
    -   maybe use #[doc(hidden)] on the macro, document it in the README?
        all that macro goop is not useful for people to read
    -   add a more detailed example to the readme
    -   add a *bunch* more examples to the doc comment on the macro
    -   (make sure macro documentation is actually attached in generated html)
    -   experimentally figure out common errors from macro gaffes and document them
        (for example, leaving off the `/ set_foo` on a field causes
        something bizarre about `@gc_heap_struct` not being expected,
        sheer nonsense)

-   performance
    -   add some bench tests
    -   profile
    -   if a lot of time is spent in into_heap/from_heap methods (particularly
        from_heap), we can probably take advantage of the fact that IntoHeap
        and in-heap values have the same bit-pattern.

-   check in this todo list!

-   upload to crates.io

-   in debug builds, scribble on uninitialized memory

-   review provided implementations of the traits:
    -   add comment: why Box is safe as written
    -   make sure there's a way to store a std::fs::File in the heap and borrow it for use
        (today, could use an `Rc<RefCell<File>>`, I think?)
    -   consider Arc
    -   support HashMap
    -   consider PhantomData (oooooooooh)
    -   support small arrays
    -   consider non-'static refs that live at least as long as the Heap.
        This is probably safe. (?!)

-   figure out how to statically ensure Heap methods can't be reentered
    from GC (e.g. via destructors or wayward mark methods);
    or else add assertions against it: maybe `unsafe_deref(ptr, |r| { ... })`

-   features
    -   IntoHeapAllocation::Ref should have get_all and set_all methods
    -   support typed allocators (to avoid the hash lookup per allocation)
    -   macros
        -   support immutable fields, with get and borrow accessors rather than get and set
        -   support more kinds of struct and enum syntax (particularly tuple structs and generics)
        -   support enum ref types and struct inline types
    -   consider toplevel type alias `type GCRef<'a, T: IntoHeapAllocation<'a>> = T::Ref;`
    -   support an "everything else" allocation-class with its own pages
    -   make tuples allocate-able, add `get_0` and `set_0` methods to the ref class

-   review unsafe code and consider ways to isolate it

-   test that when importing both GCRef and a macro-defined struct T from other modules,
    the GCRef<'a, T> accessors are visible

-   avoid stack overflow during marking

-   get rid of BitVec and inline the "allocated" and "marked" bits into the page,
    after the header (perf - but also eliminates a dependency)

-   delete collections::VecStorage, just use Vec<T::In>

Things to test:

-   boxed closures can live in the heap, as long as the lifetime is right
-   destructor is also called when setting a field using the accessor
-   a heap struct is destroyed: destructors for all fields are called too, transitively
-   a ref can't be assigned to a variable of a different-lifetime ref type
-   same goes for a struct even if it doesn't have any refs in it
-   the next GC after unpinning a large amount of garbage collects it all
-   multiple pages (type-classes) work
-   it's safe to declare a destructor on a ref type, and even to chase the ref and use the heap
    during destruction
-   a heap struct can be nested inside a struct
-   two types can refer to each other (byref)
-   if two heap structs try to include each other inline, it won't compile
-   types too big to fit in a page: won't compile?
-   heap vectors are marked correctly

Done:

-   test using it from another crate
-   make Heap::id private again and retry all the "shouldn't compile" tests
-   automate the "shouldn't compile" tests
-   rename `$ref_type::address()` to `as_ptr()`
-   consider not calling destructors but rather adding a `gc_drop()` method.
    (it turns out `Drop` is safe!)
-   test that destructors are called
-   consider renaming the project to `tUnE_yArDs` (decided narrowly against it)
-   make a `toy_gc::prelude` module (turns out most people are only going to need
    `Heap` and `with_heap`, so this isn't worth it)
-   don't expose the traits from the root - only from `traits`, so they don't
    dominate the docs
-   consider making `mark()` a plain old method, taking a non-`mut` self reference
    (went ahead and did it)
-   test gc is actually suitable for use in a toy vm (toy_vm.rs, a qualified success)
-   worry about safety of user-defined Drop and statics with internal
    mutability (it's ok)
-   support heap structs of up to page size (issue #3)
-   rename the project to something other than "toy_gc" (chose "cell_gc", catchy, i know)
-   autogenerate README.md from crate doc-comments
-   set up travis-ci
-   check out meritbadge.herokuapp.com (yup, can haz badge)
-   consider simplifying by unifying traits and loosening restrictions.
    for example, maybe InHeap is not necessary; if not, it would eliminate the need
    for the `$ref_storage_type` struct. (removed InHeap)

-   review provided implementations of the traits:
    -   make sure the current bounds on the Box impls are the best ones (yep)
    -   make sure the current bounds on the Rc impls are the best ones (yep)
    -   consider non-'static refs that simply outlive the Heap (nope, can't write that bound)
    -   support tuples
    -   support 'static refs
    -   Vec<T: IntoHeap>
    -   consider Cell (seems redundant) and RefCell (could be useful - but I want
        to be able to switch to a moving GC later without changing API; I think
        borrowing will have to be much more restricted than that)

- macros
    -   unify the two macros
    -   allow declaring non-pub types,
        to avoid `private type in public interface` errors in tests