It’s more complicated than that. Maybe I’ll finally actually write a blog post.
While the semver spec has contained that line about 0.y.z, the semver spec also does not define ranges, that is, how specifying version requirements works. Cargo implements these things, like ^ and > and etc, the exact same way that every other semver implementation implements them.
That’s because very quickly the “use minor like major when major == 0” thing became the de facto way that people used semver in its earlier days. Implementations understood this, but the spec was never changed.
So Cargo does follow semver in practice, like everyone else. There’s a combination of discrepancy and under-specification in the spec; which is a great reminder that specifications tend to follow implementations, not the other way around.
It’s on my long list of things to do to eventually reconcile this in the semver specification, but it’s been a few years and I still haven’t managed it, so no promises there.