I wrote a bit about this. After years of having move semantics and borrow checking I don't really agree. I find that GCs are way way harder to reason about. They make it very hard to know when I'm sharing something or not, when something can be mutated, when it will be copied, etc. And then I still have to clean up other resources with a whole other, separate system.
At the end of the day I find languages like Java much harder to reason about and actually a bit harder to write.
You're not wrong, but I believe that we're talking of different properties.
Move semantics and borrow checker shine when you don't want your data structure to be shared and when you want to control mutation. In some domains, that brings you an unequaled level of safety and Rust is the obvious choice.
Move semantics and borrow checker slow you down when you sharing and mutation are properties you don't care about (or at least not enough to prove them to the compiler). In such cases, I'd rather code in OCaml (or Haskell, or TypeScript, ...)
I hope that one day we'll be able to have the best of both worlds, but I don't see a path forward at the moment.
At the end of the day I find languages like Java much harder to reason about and actually a bit harder to write.
https://insanitybit.github.io/2023/06/09/Java-GC-Rust