I've a parser where I previously tried to integrate the gc crate, replacing Rc nodes by Gc, but have run into a lot of compiler errors due to lack of implementing Serialize + Deserialize.
My type system will also rely on that: It'll use something like HashMap<ByAddress<Rc<Node>>, Symbol>.
Would it be possible to know what kind of documents are you parsing and why do you need Rc/Gc there? I could investigate if I can put into mine serde-yaml-bw but for that I need to understand the problem better.
It's because of symbol solving/type-checking, which requires attaching semantic meaning to most nodes, which can't be otherwise expressed as a field in the node. With Gc/Rc I can map something to a node, like HashMap<ByAddress<Rc<Node>>, Thingy>
Truthy is, it's possible to use fields for attaching symbol solver data, but it feels like a mess.
Using indices into a Vec (or other arena) is another option worth considering. If this is a good idea is going to depend on your allocation and deallocation pattern. But you might get better cache locality. I believe there are some crates for this, but I cannot remember their names.
Flattened AST might also be worth looking into, since those generally have better performance than traditional AST.
As a future bonus: If you have solutions based on indices you can then also start looking at struct of array (SOA) and other data oriented design approaches.