I’ve run into this exact wall in Rust, and I’ve landed in the same place you’re describing: indices into a Vec (or arena + IDs) is often the most production-friendly solution.
It keeps things cache-friendly, makes lifetimes explicit, and avoids the “it compiles but panics later” trade-offs that can come with Rc patterns.
The big win for me was treating node references as stable IDs (often generational) and being disciplined about mutation/deletion rules once you do that, the design feels a lot less like “fighting Rust” and more like leaning into what it’s trying to protect you from.