Rust has very good reasons for not wanting to bless an executor by bringing it into the standard library. But most of those would be moot if pollster was brought in. It wouldn't stifle experimentation and refinement of other approaches because it's so limited in scope and useless to all but the simplest of use cases.
But it does in practice solve what many mislabel as the function coloring problem. Powerful rust libraries tend to be async because that's maximally useful. Many provide an alternate synchronous interface but they all do it differently and it forces selection of an executor even if the library wouldn't otherwise force such a selection. (Although to be clear such libraries do often depend on I/O in a manner that also forces a specific executor selection).
Pollster or similar in standard library would allow external crates to be async with essentially no impact on synchronous users.
_Some_ code from 2015 still compiles today. Quite a lot of code from January 2024 won't compile today.
Turns out that in practice, the promise not to break code in the past isn't that strong, exceptions that break most of the ecosystem are "Acceptable", and the rust developers response is "Sucks for you, you'll just have to update". See:
[1] https://internals.rust-lang.org/t/type-inference-breakage-in...
[2] https://github.com/rust-lang/rust/issues/127343#issuecomment...
'replace C' is a much narrower brief and effectively forces you to accept a lot of the warts that C exposes to the world. This results in friction between what you wanted to do and end up doing as well as being stuck with some decisions made in the 1970's. It revisits a subset of those decisions whilst keeping the remainder. And Rust's ambitions now seem to have grown beyond 'replace C', it is trying very hard to be everything to everybody and includes a package manager and language features that a systems language does not need. In that sense it is becoming more like C++ than like C. C is small. Rust is now large.
Async/Await is a mental model that makes code (much) harder to reason about than synchronous code, in spite of all of the claims to the contrary (and I'm not even sure if all of the people making those claims really believe them, it may be hard to admit that reasoning about code you wrote yourself can be difficult). It obfuscates the thread of execution as well as the state and that's an important support to hold on to while attempting to understand what a chunk of code does. It effectively turns all of your code into a soft equivalent of interrupt driven code, and that is probably the most difficult kind of code you could try to write.
The actor model recognizes this fact and creates an abstraction that - for once - is not leaky, the code is extremely easy to reason about whilst under the hood the complexity of the implementation is hidden from the application programmer. This means that relative novices (which probably describes the bulk of all programmers alive today) can safely and predictably implement complex systems with multiple moving parts because it does not require them to have a mental model akin to a scheduler with multiple processes in flight all of which are at different stages of their execution. Reasoning about the state of a program suddenly becomes a global exercise rather than a local one and locality of state is an important tool if you want to write code that is predictable, the smaller the scope the better you will understand what you are doing.
It is funny because this would suggest that the likes of Erlang and other languages that implement the actor model are beginners languages because most experienced programmers would balk at the barrier to entry. But that barrier is mostly about a lot of the superstructure built on top of Erlang, and probably about the fact that Erlang has its roots in Prolog which was already an odd duck.
But you've made me wonder: could you write Erlang in Erlang entirely without a runtime other than a language bootstrap (which even C needs) and if not to what degree would you have to extend Erlang to be able to do so. And I think here you mean 'the Erlang virtual machine that are not written in Erlang' because Erlang the language is written in Erlang as is the vast bulk of the runtime.
The fact that the BEAM is written in another language is because it is effectively a HAL, an idealized (or not so idealized, see https://www.erlang.org/blog/beam-compiler-history/) machine to run Erlang on, not because you could not write the BEAM itself entirely in Erlang. That's mostly an optimization issue, which to me is in principal evaluations like this a matter of degree rather than a qualitative difference, though if the inefficiency is large enough it could easily become one as early versions of Erlang proved.
Maybe it is the use of a VM that should disqualify a language from being a 'systems language' by your definition?
But personally I don't care about that enough to sacrifice code readability to the point that you add entirely new footguns to a language that aims for safety because for code with long term staying power readability and ability to reason about the code is a very important property. Just as I would rather have memory safety than not (but there are many ways to achieve that particular goal).
What is amusing is that the Async/Await anti-pattern is now prevalent and just about the only 'systems languages' (using your definition) that have not adopted it are C and Go.
There has already been a decade of Rust with roughly the same level of breaking changes as C++. The issue talked about above is roughly the same as, for example, how gcc can't upgrade to C++20 without a patch: https://gcc.gnu.org/pipermail/gcc-patches/2025-November/7007...
That patch is tiny. Fixing the breakage talked about above was not even changing code, it was running `cargo update -p time`. And it was a notable bit of breakage because even that level of breakage was exceptional in Rust land.
As a practical example, Meta has > 1 million lines of code in their monorepo, and last I heard, they update to each new release within a week of it coming out, and the person who does that update reports that 99% of the time, it's simply updating the version, no changes needed.
EDIT: citation on that one, from last year, it's slightly more than I remember, but not much: https://old.reddit.com/r/rust/comments/19dtz5b/freebsd_discu...
> The Facebook monorepo's Rust compiler has been updated promptly every 6 weeks for more than 7 years and 54 Rust releases, usually within 2 weeks of the upstream release.
> I estimate it's about ½ hour per 1 million lines, on average.