| //@aux-build:proc_macros.rs | |
| #![feature(never_type)] | |
| #![warn(clippy::redundant_else)] | |
| #![expect(clippy::unnecessary_operation)] | |
| extern crate proc_macros; | |
| use proc_macros::{external, inline_macros, with_span}; | |
| use core::hint::black_box; | |
| use core::ops::{Add, Deref, Not}; | |
| #[inline_macros] | |
| fn main() { | |
| // then syntactic diverge final expr. | |
| { | |
| if black_box(false) { | |
| return; | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| loop { | |
| if black_box(false) { | |
| break; | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| } | |
| loop { | |
| if black_box(false) { | |
| continue; | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| } | |
| } | |
| // then syntactic diverge final stmt. | |
| { | |
| if black_box(false) { | |
| return; | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| loop { | |
| if black_box(false) { | |
| break; | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| if black_box(false) { | |
| continue; | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| } | |
| } | |
| // then panic | |
| { | |
| if black_box(false) { | |
| panic!(); | |
| } | |
| //~^ redundant_else | |
| black_box(()); | |
| if black_box(false) { | |
| panic!("msg"); | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| if black_box(false) { | |
| panic!("{}", 0); | |
| } | |
| //~^ redundant_else | |
| black_box(0i32); | |
| }; | |
| // no semi on if | |
| { | |
| if black_box(false) { | |
| return; | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| if black_box(false) { | |
| return; | |
| } | |
| //~^ redundant_else | |
| let _ = 0; | |
| black_box(()); | |
| if black_box(false) { | |
| return; | |
| } | |
| //~^ redundant_else | |
| { black_box(()) } | |
| if black_box(false) { | |
| return; | |
| } | |
| //~^ redundant_else | |
| if black_box(true) { | |
| black_box(0); | |
| } | |
| if black_box(false) { | |
| return; | |
| } | |
| //~^ redundant_else | |
| if black_box(true) { | |
| // empty | |
| } else { | |
| black_box(()) | |
| } | |
| if black_box(false) { | |
| return; | |
| } | |
| //~^ redundant_else | |
| match black_box(0) { | |
| 0 => {}, | |
| 1 => { | |
| let _ = 0; | |
| }, | |
| _ => black_box(()), | |
| } | |
| if black_box(false) { | |
| return; | |
| } | |
| //~^ redundant_else | |
| loop { | |
| if black_box(true) { | |
| break black_box(()); | |
| } | |
| } | |
| if black_box(false) { | |
| return; | |
| } | |
| //~^ redundant_else | |
| while black_box(true) { | |
| if black_box(true) { | |
| break; | |
| } | |
| } | |
| if black_box(false) { | |
| return; | |
| } | |
| //~^ redundant_else | |
| for _ in black_box(0..0) { | |
| if black_box(true) { | |
| break; | |
| } | |
| }; | |
| if black_box(false) { | |
| return; | |
| } | |
| //~^ redundant_else | |
| black_box(1) | |
| }; | |
| // then nested block diverge | |
| { | |
| if black_box(false) { | |
| { | |
| let _ = black_box(0); | |
| panic!() | |
| } | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| if black_box(false) { | |
| { | |
| let _ = black_box(0); | |
| return; | |
| } | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| } | |
| // then nested branch diverge | |
| { | |
| loop { | |
| if black_box(false) { | |
| match black_box(0) { | |
| 0 => return, | |
| 1 => panic!(), | |
| 2 => break, | |
| _ => continue, | |
| } | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| } | |
| if black_box(false) { | |
| if black_box(true) { | |
| panic!(); | |
| } | |
| //~^ redundant_else | |
| return; | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| } | |
| // if chain diverge | |
| { | |
| if black_box(false) { | |
| panic!() | |
| } else if black_box(true) { | |
| return; | |
| } else if black_box(true) { | |
| let x = 0; | |
| black_box(x + 2 * 55); | |
| panic!(); | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| } | |
| // then misc fn diverge | |
| { | |
| struct S; | |
| impl Deref for S { | |
| type Target = !; | |
| fn deref(&self) -> &! { | |
| panic!() | |
| } | |
| }; | |
| impl Not for S { | |
| type Output = !; | |
| fn not(self) -> ! { | |
| panic!() | |
| } | |
| } | |
| impl Add for S { | |
| type Output = !; | |
| fn add(self, other: Self) -> ! { | |
| panic!() | |
| } | |
| } | |
| if black_box(true) { | |
| *S | |
| } else if black_box(true) { | |
| !S | |
| } else if black_box(true) { | |
| S + S | |
| } else if black_box(true) { | |
| S.not() | |
| } else if black_box(true) { | |
| S::add(S, S) | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| if black_box(true) { | |
| *S; | |
| } else if black_box(true) { | |
| !S; | |
| } else if black_box(true) { | |
| S + S; | |
| } else if black_box(true) { | |
| S.not(); | |
| } else if black_box(true) { | |
| S::add(S, S); | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| } | |
| // then no diverge | |
| { | |
| if black_box(true) { | |
| black_box(1) | |
| } else { | |
| black_box(0) | |
| }; | |
| if black_box(true) { | |
| if black_box(true) { black_box(0) } else { return } | |
| } else { | |
| black_box(0) | |
| }; | |
| if black_box(true) { | |
| if black_box(true) { return } black_box(0) | |
| //~^ redundant_else | |
| } else { | |
| black_box(0) | |
| }; | |
| loop { | |
| if black_box(true) { | |
| match black_box(1) { | |
| 0 => panic!(), | |
| 1 => return, | |
| 2 => break, | |
| _ => { | |
| if black_box(true) { | |
| break; | |
| } else if black_box(true) { | |
| panic!() | |
| } else if black_box(true) { | |
| black_box(0) | |
| } else { | |
| return; | |
| } | |
| }, | |
| } | |
| } else { | |
| black_box(0) | |
| }; | |
| } | |
| } | |
| // nested in various weird positions | |
| { | |
| black_box(if black_box(true) { | |
| return; | |
| } else { | |
| black_box(0) | |
| }); | |
| let _ = if black_box(true) { | |
| return; | |
| } else { | |
| black_box(0) | |
| }; | |
| let _ = black_box([0, 1, 2].as_slice())[if black_box(true) { | |
| return; | |
| } else { | |
| black_box(0) | |
| }]; | |
| (if black_box(true) { | |
| return; | |
| } else { | |
| black_box(0i32) | |
| }) | |
| .ilog2(); | |
| return if black_box(true) { | |
| return; | |
| } else { | |
| black_box(()) | |
| }; | |
| 1 + if black_box(true) { | |
| return; | |
| } else { | |
| black_box(0) | |
| }; | |
| } | |
| // external macros | |
| { | |
| external! {{ | |
| if black_box(true) { | |
| return | |
| } else { | |
| black_box(0) | |
| }; | |
| }} | |
| with_span! { | |
| span | |
| { | |
| if black_box(true) { | |
| return | |
| } else { | |
| black_box(0) | |
| }; | |
| } | |
| } | |
| } | |
| // internal macros | |
| { | |
| fn diverge() -> ! { | |
| panic!() | |
| } | |
| inline! {{ | |
| if black_box(true) { | |
| return | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| if black_box(true) { | |
| return; | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| if black_box(true) { | |
| if black_box(true) { | |
| return; | |
| } | |
| //~^ redundant_else | |
| let _ = (); | |
| return | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| if black_box(true) { | |
| #[expect(clippy::redundant_else)] | |
| if black_box(true) { | |
| return; | |
| } else { | |
| let _ = (); | |
| return; | |
| }; | |
| } | |
| //~^ redundant_else | |
| black_box(0); | |
| if black_box(true) { | |
| diverge(); | |
| } else { | |
| black_box(0); | |
| } | |
| // Needs a semicolon in the suggestion due to the macro call | |
| if black_box(true) { | |
| return | |
| } | |
| //~^ redundant_else | |
| inline!({ black_box(()); }); | |
| // Needs a semicolon in the suggestion due to the context switch | |
| if black_box(true) { | |
| return | |
| } | |
| //~^ redundant_else | |
| $({ black_box(()) }); | |
| let _ = 0; | |
| }}; | |
| } | |
| } |