For a few applications, though (e.g. a JavaScript VM, or something that deals with complex graph structures with unpredictable lifetimes), a GC is a lifesaver. Even in these applications, most of the data structures won't need GC pointers. Rust has a few GCs at hand, and lets you opt-in to GC specific pointers. In theory, this means that the GC can be extremely fast, because the graphs it needs to walk will be much smaller than in languages with a general-purpose GC. The cost, of course, is that you, as a developer, need to pay attention to what needs a GC and what doesn't.
But even there, lifetimes make your life easier. If lifetimes work out on their own you know the object will be dropped at some point (at the end of the lifetime). Only when you opt out of unique_ptr-like behavior you have to consider whether Rc/Arc will work (90% of the cases), will work with some special care by using some weak references, or whether you will require a GC
Tracing GCs can do most of the work completely independently of the user code, and in parallel. Also, only live objects are touched, which can be also beneficial for certain kinds of applications.
Rust can also circumvent some of the overhead of Arc<> as it can update the reference count whenever a true "owner" is added or removed, as opposed to just any reference to the object. But yes, you're right that relying on automated reference counting as the default memory management strategy involves some overhead, and tracing GC may be preferable to that. This is a big issue wrt/ Swift.