Indeed, having played with doing compiler / parser / transformation type work (for relational query transformation, etc) in Rust, and got stuck in a maze of borrow-checker disasters around the tree of references... what I'd say is: this kind of thing is actually better done in a higher level statically typed
garbage collected language. For myself, I'd use a mature functional something like OCaml/StandardML or a Lisp or similar. It's just easier to not have to worry about borrow checking references and allocation issues when writing stuff like that.
The case against garbage collection is where latency is key. P95, P99 latency always suffers under any kind of garbage collector, no matter how advanced. You can minimize pauses, you can move them around, you can play with different collector aspects, but in the end... compare to explicit allocation/destruction/lifetime mgmt, it's going to suffer.
I don't think compilers generally have these latency concerns. Throughput matters, but not the odd unpredictable pause.
There's only so many application domains where that is super important: Certain kinds of high traffic servers, database engines [not so much query parsing & planning, but execution, data structures, buffer mgmt, networking], operating systems, and games. Also embedded systems where a tight memory profile is important.
I like Rust (and Zig) but sometimes when people have a good hammer, they go looking for nails where there aren't any...
(All that said, I feel like some tree/DAG-heavy problems in garbage collected languages could benefit from static (and runtime) reference analysis tools that look a lot like Rust's borrow checker, purely for code sanitation/tracing.
Also, GC tracing and some of the programming patterns GC encourages can cause havoc on L1 caches reducing throughput as well as a side-effect, so there's that)