> And this is basically what Rust does with ownership. When the object goes out of scope and ownership is not transferred, the memory is freed. It’s just that it doesn’t always need the reference counting part. But you can rest assured that it will be freed.
That's manual memory management. Like I said, the fact that you didn't explicitly write the call to free doesn’t make it automatic - that's just syntax sugar. Explicitly transferring ownership involves the programmer manually telling the compiler "keep this alive." If you're the one doing the bookkeeping, that's manual. Rust helps you with the bookkeeping, but it doesn't eliminate altogether.
As opposed to a tracing GC, where you don't need decide on the scope of the value itself (just the scope of the reference), leave lifetime annotations, use std::move or the like to transfer explixitly ownership, or write out destructor/drop procedures to tell the compiler exactly how to free memory. The runtime does all the bookkeeping on its own.
> The programmer might forget to free the memory or free memory too soon and use an object after it’s already been freed. This is not the case in Rust.
Yes, it's possible to run into pathologic cases in any algorithm for automatic memory management where memory isn't freed - that's the nature of Turing completeness. No scheme for automatic memory management claims to be 100% foolproof. That doesn’t mean that tracing GC is actually manual memory management.
> This just isn’t true, and it would be anarchy. You know that the object will be freed sometime after the last reference to it dies. This is the whole reason to use automatic memory management.
That's a surprisingly literal interpretation of what I said. What I mean by "you have no idea" is that if you read a function that uses reference counting or tracing GC, you cannot say for sure if there are going to be deallocation when that function is called, even for a pure function where you know the particular input values to that function. That's because the decision to deallocate depends on the whole program state, including references to the same value that may be held by some third party library that you linked in. As opposed to Rust, where (unless you are using Rc or Arc) you could annotate that function with comments about where things will be deallocated and if you understand the semantics of the language you will be right every time. Not because you are a genius who can divine the machinatioms of the compiler/optimizer running through algorithms to automatically insert frees, but because you actually made those decisions yourself, whether implicitly or explicitly, by leveraging the semantics of the language. Like I said, this is not a new concept. You could write C++ code without any instance of new, delete, malloc, or free all the way back in the 80s.