Naive question, since I tried my hand at rust years ago, but haven't looked at it since: isn't it possible to write another crate to build go-like channels? A kind of "write, then lose the reference" function call that places a value on a queue, and an accompanying receiver. That could make life easier for "normal" software development.
There are many such primitives in Rust (including one in the standard library). And it's effectively the default, the only annoying thing is the libraries which use async (it is possible to just wrap the async code in sync code, just a little annoying. But I think it's what most users of the language should do.)
But "most" users can live with a bit of overhead in return for safe parallelism. It's just a handful that wants to squeeze the last bit of power out of a CPU.
The other day, Intel revealed a processor with 66 thread support per core. 64 of those threads were called "slow", because there's no prefetching and speculative execution, as they are supposed to be waiting (mainly for memory, but networking could be another option). Perhaps very many cheap hardware threads is a way out of this.
That is my point. For most people just using synchronous code with threads is the best option. Async only shines if you really want to push your I/O relative to your compute (which is becoming more of a challenge on modern hardware as I/O bandwidth is rapidly expanding compared to compute), or if you need to keep track of an extremely large number of tasks with low memory overhead. Starting off with "I'm writing a network application, I should use async" is likely already a mistake, especially in Rust.