Motivation: make Rust more explicit , consistent and sovle this issue
The idea is basically like every block could written as closure so can specify return type and parameters(will explain in detail later)
async fn a() -> Result<(), reqwest::Error> {Ok(())}
async fn b() -> Result<(), std::io::Error> {Ok(())}
fn c() {
async {
a().await?;
b().await?;
Ok(())
};
}
This will raise compilation error:
error[E0282]: type annotations needed --> src/x.rs:6:9
|
6 | a().await?;
| ^^^^^^^^^^ cannot infer type
error: aborting due to previous error
For more information about this error, try `rustc --explain E0282`.
error: could not compile `v2yay`.
with my proposal, will become like this:
fn c() {
async || -> Result<(), impl std::error::Error> {
a().await?;
b().await?;
Ok(())
};
}
In rust, almost every block could return a value, and could use some variables outset of itself
let a: Vec<u32> = Vec::new();
let _ = if true {
a
} else {
Vec::new()
}
println!("{:?}", a);
```
33 | println!("{:?}", a);
| ^ value borrowed here after move
With my proposal, every block is just same as closure, you can do this if you want instead of change `a` to `&a` everywhere:
```rust
let _ = if true |&a| -> .... {
// ^ specify return type explicitly
// ^ specify borrow explicitly, others will move by default, all variables between || , just a new temp variable that shadows original
// maybe add some feature so that borrow by default, specify move explicity, that will be more convenient
} else { ... }
```rust
// same thing with while, loop ...
while true ||->xxx{}
loop ||->{}
I'm pretty sure that
async || -> ...
Is going to mean async closures. Also, with generalized type ascription, we can insert type hints anywhere.
I'm pretty sure that
async || -> ...Is going to mean async closures. Also, with generalized type ascription, we can insert type hints anywhere.
That's what I mean by Title, unify closure and block, in my opinion: block just closures without arguments, but it could also use "arguments" outside of it's scope which could treat as arguments as well. So just unify these two types, make block a special closure.
This proposal is indeed backward compatible
Unifying the the two would break
let a = async { 1 };
let b = async || { 1 };
The type of a is impl Future<Output = i32>, while the type of b is fn() -> impl Future<Output = i32>.
Unifying the the two would break
let a = async { 1 }; let b = async || { 1 };The type of
aisimpl Future<Output = i32>, while the type ofbisfn() -> impl Future<Output = i32>.
Just a closure instant called, didn't break at all
Also, Rust already has control flow like return, break, continue and ? whose behavior depends on what function/closure they're in. A block and an immediately-invoked closure must be genuinely different constructs for that reason alone. async isn't introducing anything new in that regard.
@CGQAQ so what happens with
let b = async || { 1 };
b().await;
b().await;
under this proposal
@CGQAQ so what happens with
let b = async || { 1 }; b().await; b().await;under this proposal
When you . await a closure, compiler will try to convert it to a block
Forget it, won't work