gccrs icon indicating copy to clipboard operation
gccrs copied to clipboard

macros: Built-in macros do not get expanded recursively

Open liushuyu opened this issue 2 years ago • 3 comments

I tried this code:

macro_rules! include_str {
    () => {{}};
}

fn main() -> i32 {
    let _ = include_str!(file!());

    0
}

I expected to see this happen: The program compiles successfully. Instead, this happened: Rust GCC reported:

rust1: note: SUCCESSFULLY FINISHED INJECTION 
rust1: note: started expansion
macro11.rs:6:13: error: argument must be a string literal
    6 |     let _ = include_str!(file!());
      |             ^
rust1: note: finished expansion
rust1: note: SUCCESSFULLY FINISHED EXPANSION

Meta

  • Rust GCC version: 9011184f38a04f81ba3194b826bec3f30a11c07b

liushuyu avatar Apr 06 '22 08:04 liushuyu

Thanks :D I think this is basically the same issue as #1084. Having macros as return values is not an issue, but having macro invocations as macro arguments does not work.

CohenArthur avatar Apr 06 '22 10:04 CohenArthur

Thanks :D I think this is basically the same issue as #1084. Having macros as return values is not an issue, but having macro invocations as macro arguments does not work.

Oh, I see. I thought this was due to the way MacroInvocData was passed to the built-in macros. Because I tried expanding the following code and it did work:

macro_rules! add {
    ($e:expr, $($es:expr),*) => {
        $e + add!($($es),*)
    };
    ($e:expr) => {
        $e
    };
}

fn main() -> i32 {
    let b = add!(add!(15, 20), add!(3,4));

    0
}

So I guess two different parsing logic were used in these two cases? The MacroExpander::expand_invoc_semi and MacroExpander::expand_invoc are a bit confusing when I was trying to understand what the actual issue was.

liushuyu avatar Apr 06 '22 10:04 liushuyu

Ah, that's really interesting. I'm investigating right now, thank you for the precisions :)

CohenArthur avatar Apr 07 '22 08:04 CohenArthur