Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Built-in declarative macros

Source

Initialize a new workspace with cargo init --lib.

#![allow(unused)]
fn main() {
pub fn format_args_built_in() {
    println!("Hello, world!");
}
}

Built-in declarative macros are a special type of declarative macros. They are marked with #[rustc_builtin_macro] and expanded with an internal expander function. The list of the built-in macros can be found here.

If we look at the format_args! macro as an example, we see that it is marked with #[rustc_builtin_macro] and the expander function is expand_format_args which calls expand_format_args_impl.

#![allow(unused)]
fn main() {
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "format_args_macro"]
#[allow_internal_unsafe]
#[allow_internal_unstable(fmt_internals)]
#[rustc_builtin_macro]
#[macro_export]
macro_rules! format_args {
    ($fmt:expr) => {{ /* compiler built-in */ }};
    ($fmt:expr, $($args:tt)*) => {{ /* compiler built-in */ }};
}
}

format_args_built_in

#![allow(unused)]
fn main() {
pub fn format_args_built_in() {
    println!("Hello, world!");
}
}

Built-in macros are not expanded to Rust code which means cargo expand cannot show us their expanded form:

$ cargo expand
...
pub fn format_args_built_in() {
    {
        ::std::io::_print(format_args!("Hello, world!\n"));
    };
}

Instead, they are expanded in the HIR:

$ cargo rustc --release --quiet -- -Z unpretty=hir
...
fn format_args_built_in() {
    { ::std::io::_print(format_arguments::new_const(&["Hello, world!\n"])); };
}