diff --git a/clippy_lints/src/collapsible_if.rs b/clippy_lints/src/collapsible_if.rs index 52e602bbac57..03564d1cadc3 100644 --- a/clippy_lints/src/collapsible_if.rs +++ b/clippy_lints/src/collapsible_if.rs @@ -140,6 +140,8 @@ impl CollapsibleIf { // Prevent "elseif" // Check that the "else" is followed by whitespace + // Note: We intentionally use char::is_whitespace instead of rustc_lexer::is_whitespace here to + // avoid visual issues with zero-width spaces. See ui tests. let requires_space = snippet(cx, up_to_else, "..").ends_with(|c: char| !c.is_whitespace()); let mut applicability = Applicability::MachineApplicable; diag.span_suggestion( diff --git a/tests/ui/collapsible_else_if.fixed b/tests/ui/collapsible_else_if.fixed index cd2d9be9f433..5af611bc4bf3 100644 --- a/tests/ui/collapsible_else_if.fixed +++ b/tests/ui/collapsible_else_if.fixed @@ -161,3 +161,32 @@ fn in_brackets() { { if y == "world" { println!("world") } else { println!("!") } } } } + +#[rustfmt::skip] +fn ends_with_zero_width_whitespace() { + // Test out snippets ending with the 2 zero-width characters recognized as whitespaces by the lexer, + // but not by u8::is_ascii_whitespace + // Behaviour shows a whitespace is inserted between else and if here which is desirable in this case + + let x = "hello"; + let y = "world"; + + + // LRM (U+200E) + if x == "hello" { + println!("hello LRM"); + } else‎ if y == "world" { + println!("LRM world"); + } + //~^^^^^ collapsible_else_if + + // RLM (U+200F) + if x == "hello" { + println!("hello RLM"); + } else‏ if y == "world" { + println!("RLM world"); + } + //~^^^^^ collapsible_else_if + + +} diff --git a/tests/ui/collapsible_else_if.rs b/tests/ui/collapsible_else_if.rs index 75f204328538..95926be478db 100644 --- a/tests/ui/collapsible_else_if.rs +++ b/tests/ui/collapsible_else_if.rs @@ -181,3 +181,36 @@ fn in_brackets() { { if y == "world" { println!("world") } else { println!("!") } } } } + +#[rustfmt::skip] +fn ends_with_zero_width_whitespace() { + // Test out snippets ending with the 2 zero-width characters recognized as whitespaces by the lexer, + // but not by u8::is_ascii_whitespace + // Behaviour shows a whitespace is inserted between else and if here which is desirable in this case + + let x = "hello"; + let y = "world"; + + + // LRM (U+200E) + if x == "hello" { + println!("hello LRM"); + } else‎{ + if y == "world" { + println!("LRM world"); + } + } + //~^^^^^ collapsible_else_if + + // RLM (U+200F) + if x == "hello" { + println!("hello RLM"); + } else‏{ + if y == "world" { + println!("RLM world"); + } + } + //~^^^^^ collapsible_else_if + + +} diff --git a/tests/ui/collapsible_else_if.stderr b/tests/ui/collapsible_else_if.stderr index ebd78d2b1ffe..0f88374953e8 100644 --- a/tests/ui/collapsible_else_if.stderr +++ b/tests/ui/collapsible_else_if.stderr @@ -177,5 +177,41 @@ LL | | (if y == "world" { println!("world") } else { println!("!") }) LL | | } | |_____^ help: collapse nested if block: `if y == "world" { println!("world") } else { println!("!") }` -error: aborting due to 10 previous errors +error: this `else { if .. }` block can be collapsed + --> tests/ui/collapsible_else_if.rs:198:12 + | +LL | } else‎{ + | ___________^ +LL | | if y == "world" { +LL | | println!("LRM world"); +LL | | } +LL | | } + | |_____^ + | +help: collapse nested if block + | +LL ~ } else‎ if y == "world" { +LL + println!("LRM world"); +LL + } + | + +error: this `else { if .. }` block can be collapsed + --> tests/ui/collapsible_else_if.rs:208:12 + | +LL | } else‏{ + | ___________^ +LL | | if y == "world" { +LL | | println!("RLM world"); +LL | | } +LL | | } + | |_____^ + | +help: collapse nested if block + | +LL ~ } else‏ if y == "world" { +LL + println!("RLM world"); +LL + } + | + +error: aborting due to 12 previous errors