cell-gc 0.1.2

A fun garbage collector for that virtual machine you're writing in Rust
Documentation
# cell-gc [![Build Status]https://travis-ci.org/jorendorff/cell-gc.svg?branch=master]https://travis-ci.org/jorendorff/cell-gc [![]http://meritbadge.herokuapp.com/cell-gc]https://crates.io/crates/cell-gc

A simple garbage collector for use in Rust.

The goal is to help you quickly build a VM in Rust.
So this GC is designed for:

*   Safety

*   No dependency on linters or compiler plugins

*   An API that's consistent with a high-performance implementation
    (though right now cell-gc is not speedy)

*   Fun


## Caveats

**cell-gc only works for toy-sized programs at present.**
[See issue #4.](https://github.com/jorendorff/rust-toy-gc/issues/4)

**cell-gc is for use in VMs.** So the assumption is that the data the GC is
managing is not really *your* data; it's your end user's data. If you don't
want every field of every GC-managed object to be public and mutable, cell-gc
is not the GC for your project!

**The API is completely unstable.** I promise I will change it in ways
that will break code; you'll just have to keep up until things stabilize.

cell-gc is not designed to support multithread access to a single heap (like Java).
Instead, you can create one heap per thread (like JavaScript).

Currently it does not support lots of small heaps with random lifetimes (like Erlang),
but I have some ideas on how to get there.


## How to use it

Good luck!

```rust
#[macro_use] extern crate cell_gc;

/// A linked list of numbers that lives in the GC heap.
gc_heap_type! {
    // This declares three different related structs, but the last one is
    // for the GC's internal use. Read on to see the other two in action.
    struct IntList / RefIntList / InHeapIntList <'a> {
        head / set_head: i64,
        tail / set_tail: Option<RefIntList<'a>>
    }
}

fn main() {
    // Create a heap (you'll only do this once in your whole program)
    cell_gc::with_heap(|heap| {
        // Allocate an object (returns a RefIntList)
        let obj1 = heap.alloc(IntList { head: 17, tail: None });
        assert_eq!(obj1.head(), 17);
        assert_eq!(obj1.tail(), None);

        // Allocate another object
        let obj2 = heap.alloc(IntList { head: 33, tail: Some(obj1) });
        assert_eq!(obj2.head(), 33);
        assert_eq!(obj2.tail().unwrap().head(), 17);
    });
}
```

`RefIntList` values keep in-heap `IntList` values alive;
once the last `RefIntList` pointing at an object is gone,
it becomes available for garbage collection,
and eventually it'll be recycled.

`RefIntList` is like `std::rc::Rc`: it's `Clone` but not `Copy`,
and calling `.clone()` copies the Ref, not the object it points to.


## Heap types

Right now, there is a separate macro for declaring enums: `heap_inline_enum!{}`.
(But I hope to merge these two macros, so this will go away.)

Not every type is safe to use as a field of a heap struct or enum.
Here are the allowed field types:

* primitive types, like `i32`
* macro-declared GC types like `IntList<'a>` and `RefIntList<'a>`
* macro-declared enum types
* `Box<T>` where `T` has `'static` lifetime
* `Rc<T>` where `T` has `'static` lifetime
* `Option<T>` where `T` is any of these types

If you try to use anything else, you'll get bizarre `rustc` error messages.


## Safety

As long as you don't type the keyword `unsafe` in your code,
this GC is safe.<sup>[citation needed]</sup>

Still, there's one weird rule to be aware of:
**Don't implement `Drop` or `Clone`
for any type declared using the `gc` macros.**
It's safe in the full Rust sense of that word
(it won't cause crashes or undefined behavior,
as long as your `.drop()` or `.clone()` method does nothing `unsafe`),
but it won't do what you want.
Your `.drop()` and `.clone()` methods simply will not be called when you expect;
and they'll be called at other times that make no sense.

So don't do that!
The safe alternative is to put a `Box` or `Rc` around your value
(the one that implements `Drop` or `Clone`)
and use that as a field of a GC heap struct.


## Why is it called "cell-gc"?

In cell-gc, every field of every GC-managed object is public and mutable.

It's as though every field were a [Cell](http://doc.rust-lang.org/std/cell/struct.Cell.html).