Technically it's not true that heap allocation is your only option on go. In Go you have 0 options but stack allocation is automatically done in some cases.
Yes, escape analysis does tend to eliminate some unnecessary heap allocations but they're specifically isolated to a single subroutine (it's better than not having it). Whereas with Rust, you can safely pass around references to stack allocated memory to other subroutines, given proper lifetimes.