diff options
| author | Samuel Tardieu <sam@rfc1149.net> | 2025-03-26 19:38:09 +0100 |
|---|---|---|
| committer | Samuel Tardieu <sam@rfc1149.net> | 2025-03-26 21:10:09 +0100 |
| commit | 9b1945d9fb57516c585f7aea9dfe638ad3c7a397 (patch) | |
| tree | 5ee7cb0272a52cad567338d4a771fa76435fc8e4 | |
| parent | fe4dd5b92e603555594b9abef58405fc9f4f260e (diff) | |
| download | rust-9b1945d9fb57516c585f7aea9dfe638ad3c7a397.tar.gz rust-9b1945d9fb57516c585f7aea9dfe638ad3c7a397.zip | |
Prevent including preceeding whitespaces if line contains non blanks
This extra condition prevents a problem when removing the '}' in:
```rust
( // There was an opening bracket after the parenthesis, which has been removed
// This is a comment
})
```
Removing the whitespaces, including the linefeed, before the '}', would put the
closing parenthesis at the end of the `// This is a comment` line, which would
make it part of the comment as well. In this case, it is best to keep the span
on the '}' alone.
| -rw-r--r-- | clippy_utils/src/source.rs | 25 | ||||
| -rw-r--r-- | tests/ui-toml/collapsible_if/collapsible_if.fixed | 4 | ||||
| -rw-r--r-- | tests/ui-toml/collapsible_if/collapsible_if.stderr | 4 | ||||
| -rw-r--r-- | tests/ui/collapsible_if.fixed | 10 | ||||
| -rw-r--r-- | tests/ui/collapsible_if.rs | 10 | ||||
| -rw-r--r-- | tests/ui/collapsible_if.stderr | 20 | ||||
| -rw-r--r-- | tests/ui/manual_inspect.fixed | 11 | ||||
| -rw-r--r-- | tests/ui/manual_inspect.rs | 9 | ||||
| -rw-r--r-- | tests/ui/manual_inspect.stderr | 17 |
9 files changed, 98 insertions, 12 deletions
diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs index 80066e9702d..f15906df627 100644 --- a/clippy_utils/src/source.rs +++ b/clippy_utils/src/source.rs @@ -142,7 +142,19 @@ pub trait SpanRangeExt: SpanRange { map_range(cx.sess().source_map(), self.into_range(), f) } - /// Extends the range to include all preceding whitespace characters. + /// Extends the range to include all preceding whitespace characters, unless there + /// are non-whitespace characters left on the same line after `self`. + /// + /// This extra condition prevents a problem when removing the '}' in: + /// ```ignore + /// ( // There was an opening bracket after the parenthesis, which has been removed + /// // This is a comment + /// }) + /// ``` + /// Removing the whitespaces, including the linefeed, before the '}', would put the + /// closing parenthesis at the end of the `// This is a comment` line, which would + /// make it part of the comment as well. In this case, it is best to keep the span + /// on the '}' alone. fn with_leading_whitespace(self, cx: &impl HasSession) -> Range<BytePos> { with_leading_whitespace(cx.sess().source_map(), self.into_range()) } @@ -263,10 +275,15 @@ fn map_range( } fn with_leading_whitespace(sm: &SourceMap, sp: Range<BytePos>) -> Range<BytePos> { - map_range(sm, sp.clone(), |src, range| { - Some(src.get(..range.start)?.trim_end().len()..range.end) + map_range(sm, sp, |src, range| { + let non_blank_after = src.len() - src.get(range.end..)?.trim_start().len(); + if src.get(range.end..non_blank_after)?.contains(['\r', '\n']) { + Some(src.get(..range.start)?.trim_end().len()..range.end) + } else { + Some(range) + } }) - .unwrap_or(sp) + .unwrap() } fn trim_start(sm: &SourceMap, sp: Range<BytePos>) -> Range<BytePos> { diff --git a/tests/ui-toml/collapsible_if/collapsible_if.fixed b/tests/ui-toml/collapsible_if/collapsible_if.fixed index f695f9804d5..6f5cc47ba6c 100644 --- a/tests/ui-toml/collapsible_if/collapsible_if.fixed +++ b/tests/ui-toml/collapsible_if/collapsible_if.fixed @@ -13,7 +13,7 @@ fn main() { //~^^^^^^ collapsible_if // The following tests check for the fix of https://github.com/rust-lang/rust-clippy/issues/798 - if x == "hello" // Inner comment + if x == "hello" // Inner comment && y == "world" { println!("Hello world!"); } @@ -26,7 +26,7 @@ fn main() { } //~^^^^^^ collapsible_if - if x == "hello" /* Inner comment */ + if x == "hello" /* Inner comment */ && y == "world" { println!("Hello world!"); } diff --git a/tests/ui-toml/collapsible_if/collapsible_if.stderr b/tests/ui-toml/collapsible_if/collapsible_if.stderr index a12c2112f58..357ce4ad32d 100644 --- a/tests/ui-toml/collapsible_if/collapsible_if.stderr +++ b/tests/ui-toml/collapsible_if/collapsible_if.stderr @@ -32,7 +32,7 @@ LL | | } | help: collapse nested if block | -LL ~ if x == "hello" // Inner comment +LL ~ if x == "hello" // Inner comment LL ~ && y == "world" { LL | println!("Hello world!"); LL ~ } @@ -70,7 +70,7 @@ LL | | } | help: collapse nested if block | -LL ~ if x == "hello" /* Inner comment */ +LL ~ if x == "hello" /* Inner comment */ LL ~ && y == "world" { LL | println!("Hello world!"); LL ~ } diff --git a/tests/ui/collapsible_if.fixed b/tests/ui/collapsible_if.fixed index df281651ab1..e1ceb04f9cb 100644 --- a/tests/ui/collapsible_if.fixed +++ b/tests/ui/collapsible_if.fixed @@ -152,3 +152,13 @@ fn main() { } } } + +#[rustfmt::skip] +fn layout_check() -> u32 { + if true + && true { + } + // This is a comment, do not collapse code to it + ; 3 + //~^^^^^ collapsible_if +} diff --git a/tests/ui/collapsible_if.rs b/tests/ui/collapsible_if.rs index ce979568cc8..0b996dca22e 100644 --- a/tests/ui/collapsible_if.rs +++ b/tests/ui/collapsible_if.rs @@ -162,3 +162,13 @@ fn main() { } } } + +#[rustfmt::skip] +fn layout_check() -> u32 { + if true { + if true { + } + // This is a comment, do not collapse code to it + }; 3 + //~^^^^^ collapsible_if +} diff --git a/tests/ui/collapsible_if.stderr b/tests/ui/collapsible_if.stderr index 559db238cb1..53281146239 100644 --- a/tests/ui/collapsible_if.stderr +++ b/tests/ui/collapsible_if.stderr @@ -172,5 +172,23 @@ LL | println!("No comment, linted"); LL ~ } | -error: aborting due to 10 previous errors +error: this `if` statement can be collapsed + --> tests/ui/collapsible_if.rs:168:5 + | +LL | / if true { +LL | | if true { +... | +LL | | }; 3 + | |_____^ + | +help: collapse nested if block + | +LL ~ if true +LL ~ && true { +LL | } +LL | // This is a comment, do not collapse code to it +LL ~ ; 3 + | + +error: aborting due to 11 previous errors diff --git a/tests/ui/manual_inspect.fixed b/tests/ui/manual_inspect.fixed index 8d045c48ceb..ec87fe217ae 100644 --- a/tests/ui/manual_inspect.fixed +++ b/tests/ui/manual_inspect.fixed @@ -107,7 +107,7 @@ fn main() { let _ = || { let _x = x; }; - return; + return ; } println!("test"); }); @@ -185,3 +185,12 @@ fn main() { }); } } + +#[rustfmt::skip] +fn layout_check() { + if let Some(x) = Some(1).inspect(|&x| { println!("{x}"); //~ manual_inspect + // Do not collapse code into this comment + }) { + println!("{x}"); + } +} diff --git a/tests/ui/manual_inspect.rs b/tests/ui/manual_inspect.rs index a89d28dab68..e679636201e 100644 --- a/tests/ui/manual_inspect.rs +++ b/tests/ui/manual_inspect.rs @@ -197,3 +197,12 @@ fn main() { }); } } + +#[rustfmt::skip] +fn layout_check() { + if let Some(x) = Some(1).map(|x| { println!("{x}"); //~ manual_inspect + // Do not collapse code into this comment + x }) { + println!("{x}"); + } +} diff --git a/tests/ui/manual_inspect.stderr b/tests/ui/manual_inspect.stderr index 510325d2baa..eb98f9f5995 100644 --- a/tests/ui/manual_inspect.stderr +++ b/tests/ui/manual_inspect.stderr @@ -98,7 +98,7 @@ LL | if x.is_empty() { LL | let _ = || { LL ~ let _x = x; LL | }; -LL ~ return; +LL ~ return ; LL | } LL ~ println!("test"); | @@ -187,5 +187,18 @@ LL | LL ~ println!("{}", x); | -error: aborting due to 13 previous errors +error: using `map` over `inspect` + --> tests/ui/manual_inspect.rs:203:30 + | +LL | if let Some(x) = Some(1).map(|x| { println!("{x}"); + | ^^^ + | +help: try + | +LL ~ if let Some(x) = Some(1).inspect(|&x| { println!("{x}"); +LL | // Do not collapse code into this comment +LL ~ }) { + | + +error: aborting due to 14 previous errors |
