-
Notifications
You must be signed in to change notification settings - Fork 892
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding an attribute to an unsafe
block changes its formatting
#6106
Comments
A similar issue has popped up in other cases too. #5901 and #5662 immediately come to mind, but there might be others in the backlog. I haven't looked into this, but my hunch is that rustfmt considers the newline between the attribute and the block as an indication that the block can't be written on one line. |
I'm assuming this affects all blocks, not just unsafe blocks? What about async blocks for example? |
Good call, looks like fn main() {
// #[cfg(not(fake_flag))]
async { println!() };
} fn main() {
#[cfg(not(fake_flag))]
async {
println!()
};
} Probably indeed the same issue as #5662 so close this if you see fit. I just noticed because the diff for rust-lang/rust#121894 looked kind of funny :) |
I think its the same underlying problem as #5662, but it's occurring in a different parts of the codebase. rustfmt rewrites attrs before rewriting the AST node those attrs are associated with so I think this is a distinct issue to the others I linked. |
I did a little more digging into this one. I don't know if this is actually a bug, and I'm no longer convinced this is related to #5662. It seems that it might be intentional behavior. I've tracked this down to Lines 1219 to 1228 in fbe0424
It's not clear to me why that's the case. It seems that this logic was introduced in #2075 and merged in 0dca70f. If we wanted to change that behavior we'd need to gate the change. |
Ah, thanks for the history. I have to imagine this specific case wasn't intentional - #2073 and all the tests added at 0dca70f#diff-56f48f88e4ce65cd696cc52c563399f2f751aaab2dfa3f8cd51a582b19e77070 only relate to adding attributes within This seems worth fixing to me. I have run into this a few times since writing this issue and it is always surprising that a noninvasive attribute affects the formatting of the thing it applies to, and that commenting the line affects the formatting. I think an argument could be made that this is a bugfix so doesn't require gating - at least, it doesn't seem worth supporting the current behavior forever. This pattern also seems relatively rare, only a handful of uses in Formatted example, for reference: /* Block with `unsafe` / `async` / `const` */
// Problematic example
#[cfg(target_os = "linux")]
unsafe {
println!("hi")
};
// Commenting the line affects the rest of the block
// #[cfg(target_os = "linux")]
unsafe { println!("hi") };
// Attribute has no effect for `let` expressions
#[cfg(not(target_os = "linux"))]
let x = unsafe { println!("hi") };
// Attribute has no effect for `let` expressions
// #[cfg(not(target_os = "linux"))]
let x = unsafe { println!("hi") };
/* Block without `unsafe` / `async` / `const` */
// Formatting with the attribute...
#[cfg(target_os = "linux")]
{
println!("hi")
};
// ...is exactly the same as formatting without the attribute
// #[cfg(target_os = "linux")]
{
println!("hi")
};
// Attribute has no effect for `let` expressions
#[cfg(not(target_os = "linux"))]
let x = { println!("hi") };
// Attribute has no effect for `let` expressions
// #[cfg(not(target_os = "linux"))]
let x = { println!("hi") }; |
Because of rustfmt's stability guarantee we'd need to gate this change since changing #[cfg(target_os = "linux")]
unsafe {
println!("hi")
}; to #[cfg(target_os = "linux")]
unsafe { println!("hi")}; would be a breaking formatting change. |
This is the
rustfmt
result for anunsafe
block:But uncomment the attribute, and it reformats it as:
Changing the attribute probably should not change the formatting.
rustfmt 1.7.0-nightly (5119208f 2024-03-02)
The text was updated successfully, but these errors were encountered: