with_builtin!() { /* proc-macro */ }
Expand description
Pre-processor (pattern) with hard-coded implementations for some of the built-in macros, so as to be able to chain their result with custom macros.
By using a pre-processor, this also enables “using” macros where it is otherwise forbidden.
For instance, the following code fails to compile:
ⓘ
fn concat_idents!(f, o, o) ()
{}
fn main ()
{
foo();
}
But the following call does not:
use ::with_builtin_macros::with_builtin;
with_builtin!(let $fname = concat_idents!(f, o, o) in {
fn $fname ()
{}
});
fn main ()
{
foo();
}
- Note: for this behavior, with some added neat features (such as case
conversion), see the
::paste::paste!
macro.
Even if we forget about allowed macro call-sites, there is also the issue of macro evaluation order leading to things like the following not working:
ⓘ
/// Some (proc-)macro that expects a string literal containing a hexadecimal
/// sequence of digits, that it decodes into the represented byte sequence.
use ::hex_literal::hex;
const BYTES: &[u8] = hex!(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"), "/", "data.hex",
)));
With with_builtin!
, however, the following works:
/// Some (proc-)macro that expects a string literal containing a hexadecimal
/// sequence of digits, that it decodes into the represented byte sequence.
use ::hex_literal::hex;
use ::with_builtin_macros::with_builtin;
const BYTES: &[u8] = {
with_builtin!(let $hex_str = include_str_from_root!("data.hex") in {
hex!($hex_str)
})
};