0

I wonder how to construct a struct whose definition is within a macro. The test code like this: Play Ground Test

fn main() {
    #[macro_export]
    macro_rules! helper {
        ($a: expr) => {{
            #[derive(Debug)]
            struct Person {
                pub age: u64,
            }

            let p = Person { age: $a };
            p
        }};
    }

    let x = helper!(5);
    println!("The struct get in main.rs {:?}", x);

    let p = Person { age: 3 };
}

The error msg:

error[E0422]: cannot find struct, variant or union type `Person` in this scope
  --> src/main.rs:19:13
   |
19 |     let p = Person { age: 3 };
   |             ^^^^^^ not found in this scope

error: aborting due to previous error

For more information about this error, try `rustc --explain E0422`.

But there is another example that works fine. I want to know what happened here.

fn main() {
    #[macro_export]
    macro_rules! r {
        () => {
            #[derive(Debug)]
            struct A;
            impl A {
                fn new() -> Self { A }
            }
        };
    }

    pub mod m {
        pub use crate::r;
    }
    
    m::r! {}
    
    dbg!(A{});
}

1 Answers1

0

You can't have simply an expression declaring a struct for the outer scope.

I'd change your macro to not return an expression but to both create the structure and do the assignment:

fn main() {
    #[macro_export]
    macro_rules! helper {
        ($var:ident, $a: expr) => {
            #[derive(Debug)]
            struct Person {
                pub age: u64,
            }
            let $var = Person { age: $a };
        };
    }

    helper!(x, 5);
    println!("The struct get in main.rs {:?}", x);

    let p = Person { age: 3 };
}
Denys Séguret
  • 372,613
  • 87
  • 782
  • 758