Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions clippy_lints/src/matches/single_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,16 @@ use super::{MATCH_BOOL, SINGLE_MATCH, SINGLE_MATCH_ELSE};
/// span, e.g. a string literal `"//"`, but we know that this isn't the case for empty
/// match arms.
fn empty_arm_has_comment(cx: &LateContext<'_>, span: Span) -> bool {
if let Some(ff) = span.get_source_range(cx)
&& let Some(text) = ff.as_str()
{
text.as_bytes().windows(2).any(|w| w == b"//" || w == b"/*")
} else {
false
}
span.check_source_text(cx, |text| text.as_bytes().windows(2).any(|w| w == b"//" || w == b"/*"))
}

#[rustfmt::skip]
pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>], expr: &'tcx Expr<'_>, contains_comments: bool) {
pub(crate) fn check<'tcx>(
cx: &LateContext<'tcx>,
ex: &'tcx Expr<'_>,
arms: &'tcx [Arm<'_>],
expr: &'tcx Expr<'_>,
contains_comments: bool,
) {
if let [arm1, arm2] = arms
&& !arms.iter().any(|arm| arm.guard.is_some() || arm.pat.span.from_expansion())
&& !expr.span.from_expansion()
Expand Down Expand Up @@ -226,13 +225,13 @@ enum PatState<'a> {
Wild,
/// A std enum we know won't be extended. Tracks the states of each variant separately.
///
/// This is not used for `Option` since it uses the current pattern to track it's state.
/// This is not used for `Option` since it uses the current pattern to track its state.
StdEnum(&'a mut [PatState<'a>]),
/// Either the initial state for a pattern or a non-std enum. There is currently no need to
/// distinguish these cases.
///
/// For non-std enums there's no need to track the state of sub-patterns as the state of just
/// this pattern on it's own is enough for linting. Consider two cases:
/// this pattern on its own is enough for linting. Consider two cases:
/// * This enum has no wild match. This case alone is enough to determine we can lint.
/// * This enum has a wild match and therefore all sub-patterns also have a wild match.
///
Expand Down Expand Up @@ -380,7 +379,11 @@ impl<'a> PatState<'a> {
self.add_pat(cx, pat)
},
PatKind::Tuple([sub_pat], pos)
if pos.as_opt_usize().is_none() || cx.typeck.pat_ty(pat).tuple_fields().len() == 1 =>
// `pat` looks like `(sub_pat)`, without a `..` -- has only one sub-pattern
if pos.as_opt_usize().is_none()
// `pat` looks like `(sub_pat, ..)` or `(.., sub_pat)`, but its type is a unary tuple,
// so it still only has one sub-pattern
|| cx.typeck.pat_ty(pat).tuple_fields().len() == 1 =>
{
self.add_pat(cx, sub_pat)
},
Expand Down
5 changes: 3 additions & 2 deletions tests/ui/single_match.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ fn main() {
};
}

fn issue_10808(bar: Option<i32>) {
fn issue10808(bar: Option<i32>) {
if let Some(v) = bar { unsafe {
let r = &v as *const i32;
println!("{}", *r);
Expand Down Expand Up @@ -330,6 +330,7 @@ pub struct Data([u8; 4]);
const DATA: Data = Data([1, 2, 3, 4]);
const CONST_I32: i32 = 1;

// https://github.com/rust-lang/rust-clippy/issues/13012
fn irrefutable_match() {
println!();
//~^^^^ single_match
Expand Down Expand Up @@ -367,7 +368,7 @@ fn irrefutable_match() {
//~| NOTE: you might want to preserve the comments from inside the `match`
}

fn issue_14493() {
fn issue14493() {
macro_rules! mac {
(some) => {
Some(42)
Expand Down
5 changes: 3 additions & 2 deletions tests/ui/single_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ fn main() {
};
}

fn issue_10808(bar: Option<i32>) {
fn issue10808(bar: Option<i32>) {
match bar {
Some(v) => unsafe {
let r = &v as *const i32;
Expand Down Expand Up @@ -397,6 +397,7 @@ pub struct Data([u8; 4]);
const DATA: Data = Data([1, 2, 3, 4]);
const CONST_I32: i32 = 1;

// https://github.com/rust-lang/rust-clippy/issues/13012
fn irrefutable_match() {
match DATA {
DATA => println!(),
Expand Down Expand Up @@ -462,7 +463,7 @@ fn irrefutable_match() {
//~| NOTE: you might want to preserve the comments from inside the `match`
}

fn issue_14493() {
fn issue14493() {
macro_rules! mac {
(some) => {
Some(42)
Expand Down
20 changes: 10 additions & 10 deletions tests/ui/single_match.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ LL | | }
| |_____^ help: try: `if &s[0..3] == b"foo" { println!() }`

error: this pattern is irrefutable, `match` is useless
--> tests/ui/single_match.rs:401:5
--> tests/ui/single_match.rs:402:5
|
LL | / match DATA {
LL | | DATA => println!(),
Expand All @@ -234,7 +234,7 @@ LL | | }
| |_____^ help: try: `println!();`

error: this pattern is irrefutable, `match` is useless
--> tests/ui/single_match.rs:407:5
--> tests/ui/single_match.rs:408:5
|
LL | / match CONST_I32 {
LL | | CONST_I32 => println!(),
Expand All @@ -243,7 +243,7 @@ LL | | }
| |_____^ help: try: `println!();`

error: this pattern is irrefutable, `match` is useless
--> tests/ui/single_match.rs:414:5
--> tests/ui/single_match.rs:415:5
|
LL | / match i {
LL | | i => {
Expand All @@ -263,7 +263,7 @@ LL + }
|

error: this pattern is irrefutable, `match` is useless
--> tests/ui/single_match.rs:423:5
--> tests/ui/single_match.rs:424:5
|
LL | / match i {
LL | | i => {},
Expand All @@ -272,7 +272,7 @@ LL | | }
| |_____^ help: `match` expression can be removed

error: this pattern is irrefutable, `match` is useless
--> tests/ui/single_match.rs:429:5
--> tests/ui/single_match.rs:430:5
|
LL | / match i {
LL | | i => (),
Expand All @@ -281,7 +281,7 @@ LL | | }
| |_____^ help: `match` expression can be removed

error: this pattern is irrefutable, `match` is useless
--> tests/ui/single_match.rs:435:5
--> tests/ui/single_match.rs:436:5
|
LL | / match CONST_I32 {
LL | | CONST_I32 => println!(),
Expand All @@ -290,7 +290,7 @@ LL | | }
| |_____^ help: try: `println!();`

error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
--> tests/ui/single_match.rs:443:5
--> tests/ui/single_match.rs:444:5
|
LL | / match x.pop() {
LL | | // bla
Expand All @@ -302,7 +302,7 @@ LL | | }
= note: you might want to preserve the comments from inside the `match`

error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
--> tests/ui/single_match.rs:452:5
--> tests/ui/single_match.rs:453:5
|
LL | / match x.pop() {
LL | | // bla
Expand All @@ -322,7 +322,7 @@ LL + }
|

error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
--> tests/ui/single_match.rs:478:5
--> tests/ui/single_match.rs:479:5
|
LL | / match mac!(some) {
LL | | Some(u) => println!("{u}"),
Expand All @@ -331,7 +331,7 @@ LL | | }
| |_____^ help: try: `if let Some(u) = mac!(some) { println!("{u}") }`

error: you seem to be trying to use `match` for an equality check. Consider using `if`
--> tests/ui/single_match.rs:486:5
--> tests/ui/single_match.rs:487:5
|
LL | / match mac!(str) {
LL | | "foo" => println!("eq"),
Expand Down