Wishing for a good old `#define` (proc macros eval before const)

I'm wondering if anyone has a good solution for the fact that proc macros evaluate before const expressions get their value? Basically, I just want to do something like this:

    use seq_macro::seq;

    const COUNT: usize = 2;

    seq!(N in 0..COUNT {
        #(
            type T~N;
        )*
    });

Any ideas are appreciated. Thank you.

What exactly do you want this code to do/expand to?

Basically this:

    use seq_macro::seq;

    seq!(N in 0..2 {
        #(
            type T~N;
        )*
    });

The problem is that the const (and not its value) is passed to the seq! macro, generating this error: error: expected integer

When I replace the const with its value everything is fine.

const evaluation always happens after macro expansion, so I don't think this is possible. But since you are asking for a #define, I don't think you actually need a const.

If the reason you want the macro to operate over the value of the const is that you want to keep the macro output consistent with the const value, then I suggest you go the other way around: let the macro expand to the definition of the const:

macro_rules! define_const_and_seq {
    ($value:lit) => {
        const COUNT: usize = $value;

        seq!(N in 0..$value {
            #(
                type T~N;
            )*
        });
    }
}
5 Likes

That's a very good idea, in general.

It doesn't solve my particular issue as I'm trying to make sure multiple invocations of the macro (across multiple modules) have the same constant. But it's still an excellent idea.

Thank you.

I guess, in the absence of a language feature, this could be accomplished with a preprocessor executed by the build.rs. Seems a bit heavy-weight.

In the meantime, I'll just use big scary comments around all of the numbers that must be kept in sync.

The response from @H2CO3 is the closest to a solution, so I'll mark that unless somebody has a different suggestion.