diff options
| author | est31 <MTest31@outlook.com> | 2022-02-18 05:43:48 +0100 |
|---|---|---|
| committer | est31 <MTest31@outlook.com> | 2022-10-24 22:05:39 +0200 |
| commit | c5a7696231ef60e77fdeb5068c729d63c0393547 (patch) | |
| tree | 7f4407fa76a3894ca37cd80e2c3dc8c9e9a7e906 | |
| parent | 2e01e6b4c2d5a84723738575df788823c608dce7 (diff) | |
| download | rust-c5a7696231ef60e77fdeb5068c729d63c0393547.tar.gz rust-c5a7696231ef60e77fdeb5068c729d63c0393547.zip | |
Support tuples
| -rw-r--r-- | clippy_lints/src/manual_let_else.rs | 38 | ||||
| -rw-r--r-- | tests/ui/manual_let_else.rs | 7 | ||||
| -rw-r--r-- | tests/ui/manual_let_else.stderr | 14 |
3 files changed, 45 insertions, 14 deletions
diff --git a/clippy_lints/src/manual_let_else.rs b/clippy_lints/src/manual_let_else.rs index 98510ee9acd..5e46abee42d 100644 --- a/clippy_lints/src/manual_let_else.rs +++ b/clippy_lints/src/manual_let_else.rs @@ -3,6 +3,7 @@ use clippy_utils::higher::IfLetOrMatch; use clippy_utils::visitors::{for_each_expr, Descend}; use clippy_utils::{meets_msrv, msrvs, peel_blocks}; use if_chain::if_chain; +use rustc_data_structures::fx::FxHashSet; use rustc_hir::{Expr, ExprKind, MatchSource, Pat, QPath, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; @@ -201,20 +202,33 @@ fn pat_has_no_bindings(pat: &'_ Pat<'_>) -> bool { /// Checks if the passed block is a simple identity referring to bindings created by the pattern fn expr_is_simple_identity(pat: &'_ Pat<'_>, expr: &'_ Expr<'_>) -> bool { - // TODO support patterns with multiple bindings and tuples, like: + // We support patterns with multiple bindings and tuples, like: // let ... = if let (Some(foo), bar) = g() { (foo, bar) } else { ... } - if_chain! { - if let ExprKind::Path(QPath::Resolved(_ty, path)) = &peel_blocks(expr).kind; - if let [path_seg] = path.segments; - then { - let mut pat_bindings = Vec::new(); - pat.each_binding_or_first(&mut |_ann, _hir_id, _sp, ident| { - pat_bindings.push(ident); - }); - if let [binding] = &pat_bindings[..] { - return path_seg.ident == *binding; + let peeled = peel_blocks(expr); + let paths = match peeled.kind { + ExprKind::Tup(exprs) | ExprKind::Array(exprs) => exprs, + ExprKind::Path(_) => std::slice::from_ref(peeled), + _ => return false, + }; + let mut pat_bindings = FxHashSet::default(); + pat.each_binding_or_first(&mut |_ann, _hir_id, _sp, ident| { + pat_bindings.insert(ident); + }); + if pat_bindings.len() < paths.len() { + return false; + } + for path in paths { + if_chain! { + if let ExprKind::Path(QPath::Resolved(_ty, path)) = path.kind; + if let [path_seg] = path.segments; + then { + if !pat_bindings.remove(&path_seg.ident) { + return false; + } + } else { + return false; } } } - false + true } diff --git a/tests/ui/manual_let_else.rs b/tests/ui/manual_let_else.rs index 782f9f394fe..d69e580ff8f 100644 --- a/tests/ui/manual_let_else.rs +++ b/tests/ui/manual_let_else.rs @@ -88,6 +88,13 @@ fn fire() { return; }; + // Tuples supported for the identity block and pattern + let v = if let (Some(v_some), w_some) = (g(), 0) { + (w_some, v_some) + } else { + return; + }; + // entirely inside macro lints macro_rules! create_binding_if_some { ($n:ident, $e:expr) => { diff --git a/tests/ui/manual_let_else.stderr b/tests/ui/manual_let_else.stderr index 9a2c548c5aa..97e6420d705 100644 --- a/tests/ui/manual_let_else.stderr +++ b/tests/ui/manual_let_else.stderr @@ -101,7 +101,17 @@ LL | | }; | |______^ error: this could be rewritten as `let else` - --> $DIR/manual_let_else.rs:94:13 + --> $DIR/manual_let_else.rs:92:5 + | +LL | / let v = if let (Some(v_some), w_some) = (g(), 0) { +LL | | (w_some, v_some) +LL | | } else { +LL | | return; +LL | | }; + | |______^ + +error: this could be rewritten as `let else` + --> $DIR/manual_let_else.rs:101:13 | LL | let $n = if let Some(v) = $e { v } else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -111,5 +121,5 @@ LL | create_binding_if_some!(w, g()); | = note: this error originates in the macro `create_binding_if_some` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 12 previous errors +error: aborting due to 13 previous errors |
