mirror of
https://github.com/rust-lang/rust.git
synced 2026-03-14 07:12:34 +00:00
Commit efe3fe9b8c5f16bbf39af7415bbde9441bc54dbb removed the ability for `single_match` and `single_match_else` to trigger if comments were present outside of the arms, as those comments would be lost while rewriting the `match` expression. This reinstates the lint, but prevents the suggestion from being applied automatically in the presence of comments by using the `MaybeIncorrect` applicability. Also, a note is added to the lint message to warn the user about the need to preserve the comments if acting upon the suggestion.
196 lines
4.2 KiB
Rust
196 lines
4.2 KiB
Rust
//@aux-build: proc_macros.rs
|
|
//@require-annotations-for-level: WARN
|
|
|
|
#![warn(clippy::single_match_else)]
|
|
#![allow(unused, clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)]
|
|
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
|
|
use std::convert::Infallible;
|
|
if let Ok(a) = Result::<i32, &Infallible>::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
|
|
}
|