Letting the OS free memory at process exit is a very viable approach for single-purpose tools that don't run a reasonable risk of running out of memory. (Structs over unions are also more debuggable and less prone to bugs.)
On the other hand, if you ever want to turn what you wrote into a library instead of a standalone process, not having taken more care over memory management will hurt.
For compilers, there's often a happy medium available: pool / arena-based allocation, with one pool per translation unit.
I read an estimate that about 40% of programmer time spent writing a C or C++ program goes into memory management. Compilers often don't really need sophisticated memory management techniques, as they don't run for very long. Go in particular seems designed to never compile really large compilation units (like you might in C++).
tl;dr if I was writing a Go compiler, I wouldn't worry about memory management either.
On the other hand, if you ever want to turn what you wrote into a library instead of a standalone process, not having taken more care over memory management will hurt.
For compilers, there's often a happy medium available: pool / arena-based allocation, with one pool per translation unit.