From 1b4e2ef3d797b902a8d9870e5cc33795951ee619 Mon Sep 17 00:00:00 2001 From: y21 <30553356+y21@users.noreply.github.com> Date: Wed, 15 Nov 2023 21:10:03 +0100 Subject: [PATCH] fix empty needle corner case and add tests --- clippy_lints/src/matches/redundant_guards.rs | 5 +- tests/ui/redundant_guards.fixed | 57 +++++++++++++ tests/ui/redundant_guards.rs | 57 +++++++++++++ tests/ui/redundant_guards.stderr | 86 +++++++++++++++++++- 4 files changed, 203 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/matches/redundant_guards.rs b/clippy_lints/src/matches/redundant_guards.rs index 8d5907d6faf..365d178f548 100644 --- a/clippy_lints/src/matches/redundant_guards.rs +++ b/clippy_lints/src/matches/redundant_guards.rs @@ -127,10 +127,13 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) { { // `arr if arr.starts_with(&[123])` becomes [123, ..] // `arr if arr.ends_with(&[123])` becomes [.., 123] + // `arr if arr.starts_with(&[])` becomes [..] (why would anyone write this?) let mut sugg = snippet(cx, needle.span, "").into_owned(); - if path.ident.name == sym!(starts_with) { + if needles.is_empty() { + sugg.insert_str(1, ".."); + } else if path.ident.name == sym!(starts_with) { sugg.insert_str(sugg.len() - 1, ", .."); } else if path.ident.name == sym!(ends_with) { sugg.insert_str(1, ".., "); diff --git a/tests/ui/redundant_guards.fixed b/tests/ui/redundant_guards.fixed index f8af9092725..aef26ef225c 100644 --- a/tests/ui/redundant_guards.fixed +++ b/tests/ui/redundant_guards.fixed @@ -193,3 +193,60 @@ mod issue11465 { } } } + +fn issue11807() { + #![allow(clippy::single_match)] + + match Some(Some("")) { + Some(Some("")) => {}, + _ => {}, + } + + match Some(Some(String::new())) { + // Do not lint: String deref-coerces to &str + Some(Some(x)) if x.is_empty() => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some([])) => {}, + _ => {}, + } + + match Some(Some([] as [i32; 0])) { + Some(Some([])) => {}, + _ => {}, + } + + match Some(Some(Vec::<()>::new())) { + // Do not lint: Vec deref-coerces to &[T] + Some(Some(x)) if x.is_empty() => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some([..])) => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some([1, ..])) => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some([1, 2, ..])) => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some([.., 1, 2])) => {}, + _ => {}, + } + + match Some(Some(Vec::::new())) { + // Do not lint: deref coercion + Some(Some(x)) if x.starts_with(&[1, 2]) => {}, + _ => {}, + } +} diff --git a/tests/ui/redundant_guards.rs b/tests/ui/redundant_guards.rs index b46f8a6207e..5d476f5b040 100644 --- a/tests/ui/redundant_guards.rs +++ b/tests/ui/redundant_guards.rs @@ -193,3 +193,60 @@ fn issue11465() { } } } + +fn issue11807() { + #![allow(clippy::single_match)] + + match Some(Some("")) { + Some(Some(x)) if x.is_empty() => {}, + _ => {}, + } + + match Some(Some(String::new())) { + // Do not lint: String deref-coerces to &str + Some(Some(x)) if x.is_empty() => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some(x)) if x.is_empty() => {}, + _ => {}, + } + + match Some(Some([] as [i32; 0])) { + Some(Some(x)) if x.is_empty() => {}, + _ => {}, + } + + match Some(Some(Vec::<()>::new())) { + // Do not lint: Vec deref-coerces to &[T] + Some(Some(x)) if x.is_empty() => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some(x)) if x.starts_with(&[]) => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some(x)) if x.starts_with(&[1]) => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some(x)) if x.starts_with(&[1, 2]) => {}, + _ => {}, + } + + match Some(Some(&[] as &[i32])) { + Some(Some(x)) if x.ends_with(&[1, 2]) => {}, + _ => {}, + } + + match Some(Some(Vec::::new())) { + // Do not lint: deref coercion + Some(Some(x)) if x.starts_with(&[1, 2]) => {}, + _ => {}, + } +} diff --git a/tests/ui/redundant_guards.stderr b/tests/ui/redundant_guards.stderr index b8d7834e358..f78d2a814f9 100644 --- a/tests/ui/redundant_guards.stderr +++ b/tests/ui/redundant_guards.stderr @@ -203,5 +203,89 @@ LL - B { ref c, .. } if matches!(c, &1) => {}, LL + B { c: 1, .. } => {}, | -error: aborting due to 17 previous errors +error: redundant guard + --> $DIR/redundant_guards.rs:201:26 + | +LL | Some(Some(x)) if x.is_empty() => {}, + | ^^^^^^^^^^^^ + | +help: try + | +LL - Some(Some(x)) if x.is_empty() => {}, +LL + Some(Some("")) => {}, + | + +error: redundant guard + --> $DIR/redundant_guards.rs:212:26 + | +LL | Some(Some(x)) if x.is_empty() => {}, + | ^^^^^^^^^^^^ + | +help: try + | +LL - Some(Some(x)) if x.is_empty() => {}, +LL + Some(Some([])) => {}, + | + +error: redundant guard + --> $DIR/redundant_guards.rs:217:26 + | +LL | Some(Some(x)) if x.is_empty() => {}, + | ^^^^^^^^^^^^ + | +help: try + | +LL - Some(Some(x)) if x.is_empty() => {}, +LL + Some(Some([])) => {}, + | + +error: redundant guard + --> $DIR/redundant_guards.rs:228:26 + | +LL | Some(Some(x)) if x.starts_with(&[]) => {}, + | ^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - Some(Some(x)) if x.starts_with(&[]) => {}, +LL + Some(Some([..])) => {}, + | + +error: redundant guard + --> $DIR/redundant_guards.rs:233:26 + | +LL | Some(Some(x)) if x.starts_with(&[1]) => {}, + | ^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - Some(Some(x)) if x.starts_with(&[1]) => {}, +LL + Some(Some([1, ..])) => {}, + | + +error: redundant guard + --> $DIR/redundant_guards.rs:238:26 + | +LL | Some(Some(x)) if x.starts_with(&[1, 2]) => {}, + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - Some(Some(x)) if x.starts_with(&[1, 2]) => {}, +LL + Some(Some([1, 2, ..])) => {}, + | + +error: redundant guard + --> $DIR/redundant_guards.rs:243:26 + | +LL | Some(Some(x)) if x.ends_with(&[1, 2]) => {}, + | ^^^^^^^^^^^^^^^^^^^^ + | +help: try + | +LL - Some(Some(x)) if x.ends_with(&[1, 2]) => {}, +LL + Some(Some([.., 1, 2])) => {}, + | + +error: aborting due to 24 previous errors