| //@aux-build: proc_macros.rs | |
| //@require-annotations-for-level: WARN | |
| #![warn(clippy::single_match_else)] | |
| #![expect(clippy::needless_return)] | |
| extern crate proc_macros; | |
| use proc_macros::with_span; | |
| enum ExprNode { | |
| ExprAddrOf, | |
| Butterflies, | |
| Unicorns, | |
| } | |
| static NODE: ExprNode = ExprNode::Unicorns; | |
| fn unwrap_addr() -> Option<&'static ExprNode> { | |
| let _ = if let ExprNode::ExprAddrOf = ExprNode::Butterflies { Some(&NODE) } else { | |
| let x = 5; | |
| None | |
| }; | |
| //~^^^^^^^ single_match_else | |
| // Don't lint | |
| with_span!(span match ExprNode::Butterflies { | |
| ExprNode::ExprAddrOf => Some(&NODE), | |
| _ => { | |
| let x = 5; | |
| None | |
| }, | |
| }) | |
| } | |
| macro_rules! unwrap_addr { | |
| ($expression:expr) => { | |
| match $expression { | |
| ExprNode::ExprAddrOf => Some(&NODE), | |
| _ => { | |
| let x = 5; | |
| None | |
| }, | |
| } | |
| }; | |
| } | |
| #[rustfmt::skip] | |
| fn main() { | |
| unwrap_addr!(ExprNode::Unicorns); | |
| // | |
| // don't lint single exprs/statements | |
| // | |
| // don't lint here | |
| match Some(1) { | |
| Some(a) => println!("${:?}", a), | |
| None => return, | |
| } | |
| // don't lint here | |
| match Some(1) { | |
| Some(a) => println!("${:?}", a), | |
| None => { | |
| return | |
| }, | |
| } | |
| // don't lint here | |
| match Some(1) { | |
| Some(a) => println!("${:?}", a), | |
| None => { | |
| return; | |
| }, | |
| } | |
| // | |
| // lint multiple exprs/statements "else" blocks | |
| // | |
| // lint here | |
| if let Some(a) = Some(1) { println!("${:?}", a) } else { | |
| println!("else block"); | |
| return | |
| } | |
| //~^^^^^^^ single_match_else | |
| // lint here | |
| if let Some(a) = Some(1) { println!("${:?}", a) } else { | |
| println!("else block"); | |
| return; | |
| } | |
| //~^^^^^^^ single_match_else | |
| if let Some(a) = Some(1) { println!("${:?}", a) } else { | |
| println!("else block"); | |
| return; | |
| } | |
| //~^^^^^^^^ single_match_else | |
| //~| NOTE: you might want to preserve the comments from inside the `match` | |
| // lint here | |
| if let Ok(a) = Result::<i32, &!>::Ok(1) { println!("${:?}", a) } else { | |
| println!("else block"); | |
| return; | |
| } | |
| //~^^^^^^^ single_match_else | |
| enum Uninhabited {} | |
| // lint here | |
| if let Ok(a) = Result::<i32, &Uninhabited>::Ok(1) { println!("${:?}", a) } else { | |
| println!("else block"); | |
| return; | |
| } | |
| //~^^^^^^^ single_match_else | |
| use std::borrow::Cow; | |
| if let Cow::Owned(a) = Cow::from("moo") { println!("${:?}", a) } else { | |
| println!("else block"); | |
| return; | |
| } | |
| //~^^^^^^^ single_match_else | |
| } | |
| fn issue_10808(bar: Option<i32>) { | |
| if let Some(v) = bar { unsafe { | |
| let r = &v as *const i32; | |
| println!("{}", *r); | |
| } } else { | |
| println!("None1"); | |
| println!("None2"); | |
| } | |
| //~^^^^^^^^^^ single_match_else | |
| if let Some(v) = bar { | |
| println!("Some"); | |
| println!("{v}"); | |
| } else { unsafe { | |
| let v = 0; | |
| let r = &v as *const i32; | |
| println!("{}", *r); | |
| } } | |
| //~^^^^^^^^^^^ single_match_else | |
| if let Some(v) = bar { unsafe { | |
| let r = &v as *const i32; | |
| println!("{}", *r); | |
| } } else { unsafe { | |
| let v = 0; | |
| let r = &v as *const i32; | |
| println!("{}", *r); | |
| } } | |
| //~^^^^^^^^^^^ single_match_else | |
| if let Some(v) = bar { | |
| unsafe { | |
| let r = &v as *const i32; | |
| println!("{}", *r); | |
| } | |
| } else { | |
| println!("None"); | |
| println!("None"); | |
| } | |
| //~^^^^^^^^^^^^^ single_match_else | |
| match bar { | |
| Some(v) => { | |
| println!("Some"); | |
| println!("{v}"); | |
| }, | |
| #[rustfmt::skip] | |
| None => { | |
| unsafe { | |
| let v = 0; | |
| let r = &v as *const i32; | |
| println!("{}", *r); | |
| } | |
| }, | |
| } | |
| match bar { | |
| #[rustfmt::skip] | |
| Some(v) => { | |
| unsafe { | |
| let r = &v as *const i32; | |
| println!("{}", *r); | |
| } | |
| }, | |
| #[rustfmt::skip] | |
| None => { | |
| unsafe { | |
| let v = 0; | |
| let r = &v as *const i32; | |
| println!("{}", *r); | |
| } | |
| }, | |
| } | |
| } | |
| fn irrefutable_match() -> Option<&'static ExprNode> { | |
| Some(&NODE) | |
| //~^^^^^^^ single_match_else | |
| } |