Indirect attribute macro application leads to compilation error, direct application does not

⚓ Rust    📅 2025-06-24    👤 surdeus    👁️ 6      

surdeus

Warning

This post was published 48 days ago. The information described in this article may have changed.

I'm facing an issue that has me stumped. tl;dr: I'm encountering a compiler error when using macro_rules_attr to apply a macro-generated attribute. Compilation works fine when I apply the attribute directly. cargo expand shows no difference between the two versions. Huh?

Consider the following setup, if you will.

# Cargo.toml
[package]
name = "wtf_macros"
version = "0.0.0"
edition = "2024"

[dependencies]
macro_rules_attr = "0.1.3"
proptest = "1.7.0"
test-strategy = "0.4"
// main.rs
macro_rules! prop_test {
    ($item:item) => {
        #[test_strategy::proptest]
        $item
    };
}

#[macro_rules_attr::apply(prop_test)]
fn foo(#[strategy(0..2)] _v: i32) {}

fn main() {}

It's a bit roundabout, but should work. At least, I think that it should work. The compiler doesn't think so:

    Checking wtf_macros v0.0.0 (/home/code/wtf_macros)
error: could not compile `wtf_macros` (bin "wtf_macros" test) due to 1 previous error
error[E0425]: cannot find value `args` in this scope
 --> src/main.rs:9:19
  |
9 | fn foo(#[strategy(0..2)] _v: i32) {}
  |                   ^ not found in this scope
  |
help: consider importing this function
  |
1 + use std::env::args;
  |

If I change the main.rs like so:

- #[macro_rules_attribute::apply(prop_test)]
+ #[test_strategy::proptest]

then everything works perfectly fine.

What puzzles me the most is that cargo expand reports no difference between the two versions. How can there be no difference, but one version compiles and the other does not? Is cargo expand the wrong tool for the job? How can I go about debugging this? I'm happy about any pointers, really.

1 post - 1 participant

Read full topic

🏷️ rust_feed