> There is typically no need to manually free objects when you are done with them. You just let the system destroy the objects automatically when they go out of scope.
By deciding where to scope the variable with the destructor/drop function, you've already made a manual decision about memory management. The compiler implicitly inserting a call to the destructor does not automate the decision of when/where to allocate or free memory - its just syntax sugar over the decision that you already made. This is just as true of Rust in 2023 as it was of C++ 40 years ago.
With true automatic memory management like tracing GC or reference counting, you have no idea where the or when the memory will be freed as you write the code, and the answer will usually be different over different invocations of the same code.
> The ownership and borrowing system is a type of automatic memory management
No, it isn't. The borrowing system is completely orthogonal to memory management. You can write a function that takes a borrow, do all sorts of things with that borrow, including forwarding it along to other functions further down the call chain, and the memory backing that borrow could be statically allocated, dynamically allocated with the default rust allocator, or allocated by some custom solution like a slab or pool allocator. The code reads the same regardless of the memory management scheme because you make the decision on how you will allocate (and eventually free) the memory before you ever create a borrow. The borrow checker can help keep you from making use-after-free errors, but it doesn't dictate when, where, or how memory is freed. That's still up to the programmer.