Rfcs: Unify closure and block

Created on 28 Nov 2019  路  8Comments  路  Source: rust-lang/rfcs

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 block return type infer issue

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(())
    };
}

Now you would think, what's the point about ||, it's the second use case about my proposal: make Rust a more expilict language.

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 { ... }

Of cause all is optional, just specify if you need

```rust
// same thing with while, loop ...
while true ||->xxx{}
loop ||->{}

All 8 comments

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 a is impl Future<Output = i32>, while the type of b is fn() -> 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

  1. Closure have arguments, complier will look for variables match closure arguments, if compiler found all compile success, otherwise
    compilation error,
  2. Closure don't have arguments, just convert it, done

Forget it, won't work

Was this page helpful?
0 / 5 - 0 ratings

Related issues

marinintim picture marinintim  路  3Comments

torkleyy picture torkleyy  路  3Comments

onelson picture onelson  路  3Comments

mqudsi picture mqudsi  路  3Comments

Diggsey picture Diggsey  路  3Comments