In fact, you probably loose way more by not being able to write as many/great optimizations in a low-level language than what you lose on a slight overhead — e.g. Java’s Graal JIT compiler is nowadays performing better (written in Java itself) than the “original” C2 compiler which is written in C++. But this is mostly a maintainability question.
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)
Mainly I was speaking from the experience of trying to write more complicated parser & tree transformation pieces in Rust and finding the ownership stuff a hassle.
Secondly, we were talking about how Zig makes allocation first-class. This is a prime use case: specifying your own custom arena-based allocator.