summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/tests/ui/collapsible_match.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/tools/clippy/tests/ui/collapsible_match.rs
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/tools/clippy/tests/ui/collapsible_match.rs')
-rw-r--r--src/tools/clippy/tests/ui/collapsible_match.rs265
1 files changed, 265 insertions, 0 deletions
diff --git a/src/tools/clippy/tests/ui/collapsible_match.rs b/src/tools/clippy/tests/ui/collapsible_match.rs
new file mode 100644
index 000000000..603ae7dc9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/collapsible_match.rs
@@ -0,0 +1,265 @@
+#![warn(clippy::collapsible_match)]
+#![allow(
+ clippy::needless_return,
+ clippy::no_effect,
+ clippy::single_match,
+ clippy::equatable_if_let
+)]
+
+fn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>) {
+ // match without block
+ match res_opt {
+ Ok(val) => match val {
+ Some(n) => foo(n),
+ _ => return,
+ },
+ _ => return,
+ }
+
+ // match with block
+ match res_opt {
+ Ok(val) => match val {
+ Some(n) => foo(n),
+ _ => return,
+ },
+ _ => return,
+ }
+
+ // if let, if let
+ if let Ok(val) = res_opt {
+ if let Some(n) = val {
+ take(n);
+ }
+ }
+
+ // if let else, if let else
+ if let Ok(val) = res_opt {
+ if let Some(n) = val {
+ take(n);
+ } else {
+ return;
+ }
+ } else {
+ return;
+ }
+
+ // if let, match
+ if let Ok(val) = res_opt {
+ match val {
+ Some(n) => foo(n),
+ _ => (),
+ }
+ }
+
+ // match, if let
+ match res_opt {
+ Ok(val) => {
+ if let Some(n) = val {
+ take(n);
+ }
+ },
+ _ => {},
+ }
+
+ // if let else, match
+ if let Ok(val) = res_opt {
+ match val {
+ Some(n) => foo(n),
+ _ => return,
+ }
+ } else {
+ return;
+ }
+
+ // match, if let else
+ match res_opt {
+ Ok(val) => {
+ if let Some(n) = val {
+ take(n);
+ } else {
+ return;
+ }
+ },
+ _ => return,
+ }
+
+ // None in inner match same as outer wild branch
+ match res_opt {
+ Ok(val) => match val {
+ Some(n) => foo(n),
+ None => return,
+ },
+ _ => return,
+ }
+
+ // None in outer match same as inner wild branch
+ match opt_opt {
+ Some(val) => match val {
+ Some(n) => foo(n),
+ _ => return,
+ },
+ None => return,
+ }
+}
+
+fn negative_cases(res_opt: Result<Option<u32>, String>, res_res: Result<Result<u32, String>, String>) {
+ while let Some(x) = make() {
+ if let Some(1) = x {
+ todo!();
+ }
+ }
+ // no wild pattern in outer match
+ match res_opt {
+ Ok(val) => match val {
+ Some(n) => foo(n),
+ _ => return,
+ },
+ Err(_) => return,
+ }
+
+ // inner branch is not wild or None
+ match res_res {
+ Ok(val) => match val {
+ Ok(n) => foo(n),
+ Err(_) => return,
+ },
+ _ => return,
+ }
+
+ // statement before inner match
+ match res_opt {
+ Ok(val) => {
+ "hi buddy";
+ match val {
+ Some(n) => foo(n),
+ _ => return,
+ }
+ },
+ _ => return,
+ }
+
+ // statement after inner match
+ match res_opt {
+ Ok(val) => {
+ match val {
+ Some(n) => foo(n),
+ _ => return,
+ }
+ "hi buddy";
+ },
+ _ => return,
+ }
+
+ // wild branches do not match
+ match res_opt {
+ Ok(val) => match val {
+ Some(n) => foo(n),
+ _ => {
+ "sup";
+ return;
+ },
+ },
+ _ => return,
+ }
+
+ // binding used in if guard
+ match res_opt {
+ Ok(val) if val.is_some() => match val {
+ Some(n) => foo(n),
+ _ => return,
+ },
+ _ => return,
+ }
+
+ // binding used in inner match body
+ match res_opt {
+ Ok(val) => match val {
+ Some(_) => take(val),
+ _ => return,
+ },
+ _ => return,
+ }
+
+ // if guard on inner match
+ {
+ match res_opt {
+ Ok(val) => match val {
+ Some(n) if make() => foo(n),
+ _ => return,
+ },
+ _ => return,
+ }
+ match res_opt {
+ Ok(val) => match val {
+ _ => make(),
+ _ if make() => return,
+ },
+ _ => return,
+ }
+ }
+
+ // differing macro contexts
+ {
+ macro_rules! mac {
+ ($val:ident) => {
+ match $val {
+ Some(n) => foo(n),
+ _ => return,
+ }
+ };
+ }
+ match res_opt {
+ Ok(val) => mac!(val),
+ _ => return,
+ }
+ }
+
+ // OR pattern
+ enum E<T> {
+ A(T),
+ B(T),
+ C(T),
+ };
+ match make::<E<Option<u32>>>() {
+ E::A(val) | E::B(val) => match val {
+ Some(n) => foo(n),
+ _ => return,
+ },
+ _ => return,
+ }
+ match make::<Option<E<u32>>>() {
+ Some(val) => match val {
+ E::A(val) | E::B(val) => foo(val),
+ _ => return,
+ },
+ _ => return,
+ }
+ if let Ok(val) = res_opt {
+ if let Some(n) = val {
+ let _ = || {
+ // usage in closure
+ println!("{:?}", val);
+ };
+ }
+ }
+ let _: &dyn std::any::Any = match &Some(Some(1)) {
+ Some(e) => match e {
+ Some(e) => e,
+ e => e,
+ },
+ // else branch looks the same but the binding is different
+ e => e,
+ };
+}
+
+fn make<T>() -> T {
+ unimplemented!()
+}
+
+fn foo<T, U>(t: T) -> U {
+ unimplemented!()
+}
+
+fn take<T>(t: T) {}
+
+fn main() {}