Nugine / const-str

Compile-time string operations
MIT License
80 stars 4 forks source link

Eager expansion #2

Open Nugine opened 4 years ago

Nugine commented 4 years ago
Nugine commented 4 years ago

https://rustc-dev-guide.rust-lang.org/macro-expansion.html#eager-expansion

safinaskar commented 1 week ago

@Nugine, I found solution to "eager evaluation" problem!

🚀 I found a way to evaluate concat_idents (and concat and few other built-in macros) before evaluating other macro, which takes concat_idents as an argument! I. e. I found a way to evaluate a!(concat_idents!(...)) such way, that concat_idents evaluates before a. Answer is crate https://crates.io/crates/with_builtin_macros !!! In other words, with_builtin_macros is paste, but not only for concat_idents, but also for concat and some other macros.

And in other words, with_builtin_macros allows one to achieve eager evaluation of macros in limited way.

Also, with_builtin_macros allows one to use concat_idents when defining new identifier.

Also, https://crates.io/crates/with_builtin_macros allows one to use concat_idents in stable Rust.

// (This code was not tested, may contain typos)

fn concat_idents!(a, b) () {} // Doesn't work

with_builtin_macros::with_eager_expansions! {
  fn #{ concat_idents!(a, b) } () {} // Works! Even on stable!
}

macro_rules! this_macro_accepts_ident {
  ($a:ident) => {}
}

this_macro_accepts_ident!(concat_idents!(a, b)); // Doesn't work, because "this_macro_accepts_ident" evaluates before "concat_idents"

with_builtin_macros::with_eager_expansions! {
  this_macro_accepts_ident!(#{ concat_idents!(a, b) }); // Works! Even on stable!
}