Considering Go is the only language with a garbage collector out of the three languages you mentioned, I'm not sure how you reach the conclusion they're all as close to the metal.
C and Rust both have predictable memory behaviour, Go does not.
> When I read the article it was very clear, due to the compiler's in-memory graphs, that they needed a GC.
It's actually pretty easy to do something like this with C, just using something like an arena allocator, or honestly, leaking memory. I actually wrote a little allocator yesterday that just dumps memory into a linkedlist, it's not very complicated: http://github.com/danieltuveson/dsalloc/
You allocate wherever you want, and when you're done with the big messy memory graph, you throw it all out at once.
There are obviously a lot of other reasons to choose go over C, though (easier to learn, nicer tooling, memory safety, etc).
Go isn't that bad in terms of memory predictability to be honest. It generally has roughly 100% overhead in terms of memory usage compared to no GC. This can be reduced by using GOGC env variable, at the cost of worse performance if not careful.
C and Rust both have predictable memory behaviour, Go does not.