concat-idents icon indicating copy to clipboard operation
concat-idents copied to clipboard

`concat_idents` doesn't work on inner definition of `macro_rules`

Open minghu6 opened this issue 2 years ago • 1 comments

I've found concat_idents doesn't replace ident inside of the declarative macro.

Exp:

struct S {
    a: i32,
}

impl S {
    fn a_mut(&mut self) -> &mut i32 {
        &mut self.a
    }
}

macro_rules! def_macro {
    ($name:ident) => {
        concat_idents::concat_idents!(name_mut = $name, _mut {
            // Here replacement works
            macro_rules! name_mut {
                ($s:expr) => {
                    // Here, however, name_mut keeps
                    $s.name_mut()
                }
            }
        });
    };
}

def_macro!(a);

pub fn test() {
    let mut s = S { a:1 };

    println!("a: {}", a_mut!(s));
}

The compiler complains that:

no method named `name_mut` found for struct `S` in the current scope

And this peace of code did works with paste crate:

macro_rules! def_macro {
    ($name:ident) => {
        paste::paste!(
            macro_rules! [<$name _mut>] {
                ($s:expr) => {
                    $s.[<$name _mut>]()
                }
            }
        );
    };
}

minghu6 avatar Feb 22 '23 03:02 minghu6