This paper makes a strong argument that “pure” tracing garbage collection and “rote” reference counting are effectively duals at the opposite ends of a spectrum of implementation choices.
For example, GC’s often optimize differently for young vs. old objects. How do they distinguish these? By “counting” (one bit) their references across one or more traces in a series of sweeps.
What you are equating with "garbage collection" is Mark-Sweep, which is an another way to implement GC, with a very different set of tradeoffs. (Broadly, better throughput at the expense of higher latency.)
You can call a pointer to a value a "one-element static array."
This feels like people arguing that atheism is a kind of religion. Borrow checking and a library of safe default primitives make it so you don't really have to think about memory management; except to the extent that you generally stick to those primitives, and that you have to install the borrow checker into your own head to write Rust comfortably (although the compiler will help.)
Rust doesn't have any garbage collection, but it can just assume how you would want to deal with memory by forcing you to be very specific about when values should be created or destroyed.
Ugh, “Arc”, aka (automatic) reference counting, is an implementation of GC as well. It may have certain characteristics, like having worse throughput, corner cases, and better predictability/latency characteristics, but it's GC nonetheless. That's not manual memory management. Swift is not a non-GC language.
And that's the big issue that people are missing — Rust tackles some hard problems regarding memory management, and a friendlier alternative exists: garbage collection.