TokenStream iteration is breaking rust-analyzer code action, is this a bug in the compiler?

First I define two proc macros that should both just return the input stream.

#[proc_macro]
pub fn identity_correct(input: TokenStream) -> TokenStream {
    input
}

#[proc_macro]
pub fn identity_broken(input: TokenStream) -> TokenStream {
    let mut out = TokenStream::new();
    out.extend(input.into_iter());
    out
}

Then I use these proc macros on a struct defintion that is incomplete:

struct Test {
    x: u32,
    y: u32,
};

fn main() {
    identity_correct!(Test { x: 0 });
    identity_broken!(Test { x: 0 });
}

When I then apply the rust-analyzer "Fill struct fields" code action on both I get the following result:

fn main() {
    identity_correct!(Test {x:0, y: todo!() });
    identity_broken!(Test {x:0, y: todo!() } });
}

Note that there is one extra closing brace } for the broken macro.

Clearly input.into_iter() loses some information. My question then is if this is a bug and whose fault it is that the code action doesn't work anymore.

1 Like

On first glance this seems like a bug. I'm not sure if anything can be done about it because proc macros are complicated. It should be fine to file an issue in the rust-analyzer repository, as that's where the bug would be (not the compiler).