You need lifetimes in order to make the affine types ergonomic to use through borrowings and aliasing mechanics. You want the affine types to prove all kinds of things about resource management, beyond just freeing allocations, which we generally call RAII. You model file and network handles as RAII, mutex locks as RAII.
Other languages use constructs like context managers or try-with-resources to capture this, but these constructs are very limited and make it very hard or impossible for these resource types to be put into a container and passed between threads. In Rust this is trivial and actually just works.
Garbage collectors usually give much weaker guarantees about when objects are freed, so destructors (which are sometimes not even available, like in JS) might only be called much later. You can't rely on a GC to unlock a muted for you. But in Rust it happens when the guard is dropped, always, immediately after it's last needed.
Since you're mentionning it : i was surprised to find no golang "context" equivalent in rust's axum. How do you manage cancelling a long-running operation triggered inside an http request handler when the connection closes ? is it via RAII ?
Yeah due to the design rule that "futures do nothing unless polled", it's enough to simply drop them and it cancels the whole tree of work. That doesn't necessarily cancel other tasks that were spawned that the future might have been waiting on. That's really easy to build if it's needed, since we do have RAII. This is part of why Rust's futures compose really well in ways that goroutines just do not and JS promises struggle with.
> Why do I need to? Why can't I let the garbage collector deal with it?
Determinism.
With Rust lifetimes, you can statically prove when resources will be released. Garbage collectors provide no such guarantees. It has been shown that garbage-collected languages have a space-performance tradeoff: you need five times as much RAM to achieve the same performance, even with a "good" GC, as the same program with explicit memory management:
Rust's macros on the other hand are excellent, and more languages should have expressive macros like that.