My main concern is: can we make this safe.
Using Rust, I am writing a GC for an interpreted language. Standard GC techniques include RC (fails on loops), mark & sweep (may leave “holes” in memory), compacting (after sweep phase, moves all live objects together).
Now, when dealing with a compacting object which “memory moves” (not to be confused with Rust “move”) an object from memory address A to memory address B, what do I need to take care of to avoid undefined behaviour?
My gut feeling is that this just won’t work in general scenario, because quite anything can point to that address (borrows, compiler temporaries, other structures that borrow from there) and the program doesn’t really contain any information about what is a pointer and what is just a random number. It’s even legal (and used in unsafe code) to cast a pointer to usize for various reasons and then back.
You probably could come up with some trick to restrict taking the addresses out of some closure by lifetimes, so if you weren’t in any such closure and have special smart pointers that could update themselves on the compaction, but you’d probably end up with a beast hairy API you wouldn’t want.
Furthermore, there’ll be Pinned types in Rust soon. These state that no, they can never move from one place in memory to another (and usually live behind a pointer of some kind).