Rust, with the borrow-checker, strong-arms the developer into using memory patterns that the compiler manage handle without the overhead of reference counting or other runtime mechanism.
Those same memory patterns are available in Swift as well, which the compiler can then optimize as well (in theory -- as far as I'm aware there are various unimplemented optimization opportunities in Swift).
So in a sense, in Swift you can opt-in or out of rust-level memory management.
Of course, a big difference is that Rust tells you up-front when you've got it right, but in Swift it's not at all clear. You need to profile. Swift does have a clear delineation between reference types (which use ARC) and values types, so you can get on the right path by choosing value types. Value types in Swift are very rich and powerful so it's not a hard path to follow.