What do you suggest proc macros to be aware of each other as opposed to a static variable?

Hi I have a derive macro does a bunch of things and a function_like proc macro that depends on the state of the derive macro. I use a static global state to make this possible at the moment but sometimes there are issues based on the order of the imports or even in the same module i get errors sometimes. Is there an alternative method without reaching out to the filesystem ?

I think that depends on the nature of the interaction between the 2 macros.
So without more info on that it's going to be difficult to answer the question properly.

The first one is a derive macro which parses structs and generates a bunch of metadata and latter is a function_like macro which makes use of that metadata to produce other things

Then especially if the invocation of each of the macros happen in different source files, I think that I'd either take your approach, or store the metadata elsewhere on the file system, in dedicated files or in a sqlite db.

well that works just fine but sometimes i get my function macro executed before the metadata parse. This happens even in the same source file sometimes.

Proc macros should be expandable independently and without any side effects. We don't offer any guarantees around the order and amount of times a proc macro is expanded. For example rust-analyzer will only re-expand proc macros if you change the actual invocation of the proc macro. Rustc could also start caching proc macro outputs in the future I think.

4 Likes

Yeah, the ideal situation is that you use neither the filesystem nor global state. If you post your use case for this proc macro we could try to redesign it such that it doesn’t need these hacks?

I have a Table macro which generates a From<postgres::Row> definitions for the struct and caches the field names so later a function like macro Q can make use of it static checking the field names in a query at compile time.
I really cannot think of any other way to access this data from Q which is generated by Table

Can you add a const or function for every field on the struct and then reference them from the query? Something like

#[derive(Table)]
struct MyTable {
    a: u8,
    b: String,
}

let res = query!(MyTable, "select a, b from my_table");

would expand to


struct MyTable {
    a: u8,
    b: String,
}

impl From<postgres::Row> for MyTable { ... }

impl MyTable {
    const __TABLE_FIELD_a: () = ();
    const __TABLE_FIELD_b: () = ();
}

let res = {
    MyTable::__TABLE_FIELD_a;
    MyTable::__TABLE_FIELD_b;
    // do query ...
};
1 Like

I tried to implement that way but then it requires Q to run at runtime. In which case i could do the entire lookup at runtime. In my case Q macro produces the query completely at compile time and unless there are some runtime parameters it produces a `&'static str'

this is how i produce the final query

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.