Skip to content

Allow shadowing of procedural macro generated macros #57283

Closed
@dtolnay

Description

@dtolnay

The following expression compiles if macro_rules! m is generated by a macro_rules macro, but not if macro_rules! m is generated by a procedural macro. I believe it should compile in both cases. The invocation of m! should resolve to the innermost one, as happens for all other types of items.

{
    macro_rules! m { ... }
    {
        macro_rules! m { ... }
        m!()
    }
}

Repro:

src/main.rs

#![allow(unused_macros)]

macro_rules! eval_with_m {
    ($e:expr) => {{
        macro_rules! m {
            () => {
                println!("success");
            };
        }

        $e
    }};
}

macro_rules! eval_with_m_derived {
    ($e:expr) => {{
        #[derive(repro::M)]
        struct S;

        $e
    }};
}

fn main() {
    // Expanded code looks like:
    //
    //    {
    //        macro_rules! m { ... }
    //        {
    //            macro_rules! m { ... }
    //            m!()
    //        }
    //    }
    //
    eval_with_m! {
        eval_with_m! {
            m!()
        }
    }

    // Expanded code is the same but fails to compile.
    //
    //    error[E0659]: `m` is ambiguous (macro-expanded name vs less
    //    macro-expanded name from outer scope during import/macro resolution)
    //
    eval_with_m_derived! {
        eval_with_m_derived! {
            m!()
        }
    }
}

src/lib.rs

extern crate proc_macro;

use proc_macro::TokenStream;
use quote::quote;

#[proc_macro_derive(M)]
pub fn emit_m(_input: TokenStream) -> TokenStream {
    TokenStream::from(quote! {
        macro_rules! m {
            () => {
                println!("success");
            };
        }
    })
}

Mentioning @petrochenkov who worked on #52841 and fixed #53205.
Mentioning @cramertj who hit this using proc-macro-hack in futures.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions