To nitpick, the first language to bring non-GC automatic memory management to the mainstream would be either Forth or C through stack memory.
For heaps, we have reference counting, often handled automatically through the stack (e.g., C++ smart pointers).
The thing Rust brought to mainstream is not automatic memory management - they're a dime a dozen with and without GC. It's an ownership model that is strict about whether you have read or write access within the type system. At the same time, this is also where most developer friction stems from, as it's quite unique, and you're often faced with a trade-off between explaining exactly what you want at compile-time at higher design cost, or bailing out more to runtime checks with e.g. RefCell while getting fewer guarantees about code correctness from the compiler.