Rust: Async fn loses mut pattern when passed to attribute macro

Created on 9 May 2019  路  6Comments  路  Source: rust-lang/rust

Cargo.toml

[package]
name = "repro"
version = "0.0.0"
edition = "2018"

[lib]
proc-macro = true

src/lib.rs

extern crate proc_macro;
use proc_macro::TokenStream;

#[proc_macro_attribute]
pub fn attr(_args: TokenStream, input: TokenStream) -> TokenStream {
    println!("{}", input);
    TokenStream::new()
}

src/main.rs

#[repro::attr]
async fn f(mut x: u8) {}

fn main() {}

Between nightly-2019-05-07 and nightly-2019-05-08, the mut pattern that should be part of the macro input went missing. https://github.com/rust-lang/rust/compare/a19cf18c7dbbcc46dddea81df3a4cee1735c2349...cfdc84a009020c59e53e4039beae22eb59e41685

$ cargo +nightly-2019-05-07 check
   Compiling repro v0.0.0
async fn f(mut x: u8) { }

$ cargo +nightly-2019-05-08 check
   Compiling repro v0.0.0
async fn f(x: u8) { }

Originally reported by @kjvalencik in https://github.com/dtolnay/syn/issues/632.
Mentioning @taiki-e @cramertj @davidtwco because #60535 looks relevant and is in the right commit range.

A-async-await A-macros AsyncAwait-Focus C-bug

Most helpful comment

I've filed #60676 with a fix.

All 6 comments

FYI, &mut is not lost.

Thanks for the report, I'll look into this.

This problem only occurs with by-value binding(and simple patterns), so...

async fn foo(mut x: A) { ... }

// desugaring (current master)
fn foo(x: A) -> ... { // removed mutability
    async move {
        let mut x = x;
        ...
    }
}

// Probably it should desugar like this
fn foo(__arg0: A) -> ... {
    async move {
        let mut x = __arg0;
        ...
    }
}

I've filed #60676 with a fix.

@davidtwco Thanks for the fix!

Was this page helpful?
0 / 5 - 0 ratings