Skip to content

Hygiene broken in multi-statement macros #31856

Closed
@durka

Description

@durka

Multi-statement macros (macros that expand to multiple statements) are hard to use because hygiene runs separately on each line, meaning it's very easy to "lose" identifiers.

Here are some examples. The macro is trying to declare a variable in the scope where it was called, but it takes multiple statements to construct.

/*
// no good: $n declared in inner scope
macro_rules! m {
    ($n:ident) => ({
        let a = 1;
        let $n = a;
    })
}
*/

/*
// no good: hygiene throws away "a"
macro_rules! m {
    ($n:ident) => (
        let a = 1;
        let $n = a;
    )
}
*/

// workaround
macro_rules! m {
    ($n:ident) => (
        let $n = {
            let a = 1;
            a
        };
    )
}

fn main() {
    m!(b);
    println!("{}", b);
}

This is a long-standing bug, not a regression. I previously reported this here and here (can likely be closed) but it wasn't very visible. ping @Sgeo @chris-chambers

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions