It doesn't though. It's not a warning or error to not use the return value of a function that only returns an error, for instance (https://go.dev/play/p/se6-zHHVezH).
There are static error checking tools you can use like https://github.com/kisielk/errcheck to work around this, but most people don't use them.
I've run into a lack of Go error checking many times. Many times it's just the trivial case, where the compiler doesn't warn about not checking the result of an error-returning function.
But often it'll be subtler, and the result of Go's API design. One example is its file writing API, which requires you to close the file and check its error to be correct. Many times people will just `defer file.Close()`, but that isn't good enough - you're ignoring the error there.
Worse still is e.g: writing to a file through a bufio.Writer. To be correct, you need to remember to flush the writer, check that error, then close the file and check that error. There's no type-level support to make sure you do that.
(And, to be extra clear, it only lets you ignore a Result if you don't care about the Ok value, if you want to use it, it does not.)
An other issue which is as big or bigger is that Go only tracks variables, it doesn't track reads and writes (unlike... well rust for starters).
So the compiler will also be perfectly happy if you call two erroring function, check the first's error but then reassign the second's error to the same variable (say, err, because it's always the variable for the error) and... completely forget to check it: https://go.dev/play/p/GJiovZwvHqj
I think errcheck also checks for it, but as you say it's not part of the language and its use is not ubiquitous.
Rust gives you seat belts.
It depends on you what you value more.
Instead, Go provides what the language designers considered solutions to most problems. Window not having Unix permissions? Just fake a bunch of them. Path not valid unicode? Probably not a problem. As long ad you agree with the way the Go designers think, that'll save you tons of work.
Just don't use Go in situations where those solutions might not work out, like when you're iterating over arbitrary files instead of the files you've created yourself in Go code.
(This does mean that Go is constraining the set of problems it's easy to solve with it. But that's the nature of programming in general... We decide what problems need to be easier to solve at the expense of putting some problems outside the "sweet spot" and requiring more work to solve them).
- `ls` is wrong and should be fixed.
- The specs are wrong and should not allow filenames to be arbitrary bytesequences.
The third option ("The user is wrong even though they did exactly what was in the spec") is just unsatisfactory because it self-contradicts.
And "The user is wrong even though they did exactly what was in the spec" is pretty much the rule, not the exception.
To avoid the car analogy, let's use construction - an in construction building should be allowed to keep the scaffolding up while it's being built.
But maybe you should still clean the floors? Uh oh, it's getting away from me already.
Rust will get out of your way if you really want it to. It just gives you a seat belt because you are on the highway (writing systems code) but you are free to take it off.