rustfmt
rustfmt copied to clipboard
Braces are removed from single-item import in macro where they are required
In a macro that takes a path as an argument:
macro_rules! get_msg {
($module:path) => {
let message = {
use $module::{MESSAGE}; // note the (usually unnecessary) brackets
MESSAGE
};
println!("{}", message);
};
}
The braces around MESSAGE are required, and the code fails to compile without them. However, rustfmt removes them.
Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ca5ee49a37c35354f67d82d6303c7f5a
@junbl thank you for the report. Confirming I can reproduce this with the latest source version of rustfmt 1.7.0-nightly (cedb7b50 2024-01-25).
Some workarounds until we address this:
-
You can add a
#[rustfmt::skip]attribute to prevent rustfmt from modifying the formatting:macro_rules! get_msg { ($module:path) => { #[rustfmt::skip] let message = { use $module::{MESSAGE}; // note the (usually unnecessary) brackets MESSAGE }; println!("{}", message); }; } -
If you're using unstable rustfmt features you can turn declarative macro body formatting off by setting format_macro_bodies=false.
Also linking the tracking issue for format_macro_bodies (https://github.com/rust-lang/rustfmt/issues/3355)
Oh, and I'm not sure if this is an option for you, but if the rust playground link shows how you'll actually call the macro (with a single identifier, like get_msg!(x)), then you could possibly rewrite the macro as follows and the code will still compile after rustfmt removes the braces {}:
macro_rules! get_msg {
- ($module:path) => {
+ ($module:ident) => {
// this works but the braces in the import get lost on format
let message = {
use $module::{MESSAGE};
MESSAGE
};
// this would be nicer but doesn't work
// let message = $module::MESSAGE;
println!("{}", message);
};
}