Early Rust used M:N exclusively and didn't need dynamic dispatch for I/O.
...but a large part of the reason to ditch M:N was the overhead it added to 1:1-style IO in a language quickly moving toward the C++ space.
They didn't decide to move off of M:N when it was exclusively M:N.
This is, from what I can tell, their main advantage in performance over other implementations. (In Rust, at least- the performance story may easily be different in garbage collected languages like Go or Java.)
Another caveat: Rust's claims to have implemented M:N in the past must be tempered a bit by two factors. First, Rust had to use segmented stacks, which Go moved away from and which Loom seems to be avoiding, precisely because they're so expensive. Second, Rust had to dispatch all IO APIs dynamically based on the currently selected runtime, which Go avoids by not having two runtimes, and which Loom can probably avoid via its scheduler implementation and/or JIT devirtualization.