about summary refs log tree commit diff
path: root/src/tools/clippy/clippy_utils
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-08-22 13:26:32 +0000
committerbors <bors@rust-lang.org>2021-08-22 13:26:32 +0000
commit7481e6d1a415853a96dcec11a052caaa02859b5a (patch)
tree63de73abacd8425bc7670c18c35f7e3acaba7bec /src/tools/clippy/clippy_utils
parent1eb187c16ec4f26fdeaff527e3ba2b1e609cabd2 (diff)
parentada92825c9f38a0c1e198b63e806687d2338340e (diff)
downloadrust-7481e6d1a415853a96dcec11a052caaa02859b5a.tar.gz
rust-7481e6d1a415853a96dcec11a052caaa02859b5a.zip
Auto merge of #88163 - camsteffen:collapsible-match-fix, r=Manishearth
Fix clippy::collapsible_match with let expressions

This fixes rust-lang/rust-clippy#7575 which is a regression from #80357. I am fixing the bug here instead of in the clippy repo (if that's okay) because a) the regression has not been synced yet and b) I would like to land the fix on nightly asap.

The fix is basically to re-generalize `match` and `if let` for the lint implementation (they were split because `if let` no longer desugars to `match` in the HIR).

Also fixes rust-lang/rust-clippy#7586 and fixes rust-lang/rust-clippy#7591
cc `@rust-lang/clippy`
`@xFrednet` do you want to review this?
Diffstat (limited to 'src/tools/clippy/clippy_utils')
-rw-r--r--src/tools/clippy/clippy_utils/src/higher.rs34
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs4
2 files changed, 13 insertions, 25 deletions
diff --git a/src/tools/clippy/clippy_utils/src/higher.rs b/src/tools/clippy/clippy_utils/src/higher.rs
index 29b698e56e3..957ec35be6f 100644
--- a/src/tools/clippy/clippy_utils/src/higher.rs
+++ b/src/tools/clippy/clippy_utils/src/higher.rs
@@ -79,15 +79,7 @@ pub struct IfLet<'hir> {
 }
 
 impl<'hir> IfLet<'hir> {
-    #[inline]
-    pub fn ast(cx: &LateContext<'tcx>, expr: &Expr<'hir>) -> Option<Self> {
-        let rslt = Self::hir(expr)?;
-        Self::is_not_within_while_context(cx, expr)?;
-        Some(rslt)
-    }
-
-    #[inline]
-    pub const fn hir(expr: &Expr<'hir>) -> Option<Self> {
+    pub fn hir(cx: &LateContext<'_>, expr: &Expr<'hir>) -> Option<Self> {
         if let ExprKind::If(
             Expr {
                 kind: ExprKind::Let(let_pat, let_expr, _),
@@ -97,6 +89,14 @@ impl<'hir> IfLet<'hir> {
             if_else,
         ) = expr.kind
         {
+            let hir = cx.tcx.hir();
+            let mut iter = hir.parent_iter(expr.hir_id);
+            if let Some((_, Node::Block(Block { stmts: [], .. }))) = iter.next() {
+                if let Some((_, Node::Expr(Expr { kind: ExprKind::Loop(_, _, LoopSource::While, _), .. }))) = iter.next() {
+                    // while loop desugar
+                    return None;
+                }
+            }
             return Some(Self {
                 let_pat,
                 let_expr,
@@ -106,22 +106,6 @@ impl<'hir> IfLet<'hir> {
         }
         None
     }
-
-    #[inline]
-    fn is_not_within_while_context(cx: &LateContext<'tcx>, expr: &Expr<'hir>) -> Option<()> {
-        let hir = cx.tcx.hir();
-        let parent = hir.get_parent_node(expr.hir_id);
-        let parent_parent = hir.get_parent_node(parent);
-        let parent_parent_node = hir.get(parent_parent);
-        if let Node::Expr(Expr {
-            kind: ExprKind::Loop(_, _, LoopSource::While, _),
-            ..
-        }) = parent_parent_node
-        {
-            return None;
-        }
-        Some(())
-    }
 }
 
 pub struct IfOrIfLet<'hir> {
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 82bfce8fe78..7d7c3b8846c 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -254,6 +254,10 @@ pub fn in_macro(span: Span) -> bool {
     }
 }
 
+pub fn is_unit_expr(expr: &Expr<'_>) -> bool {
+    matches!(expr.kind, ExprKind::Block(Block { stmts: [], expr: None, .. }, _) | ExprKind::Tup([]))
+}
+
 /// Checks if given pattern is a wildcard (`_`)
 pub fn is_wild(pat: &Pat<'_>) -> bool {
     matches!(pat.kind, PatKind::Wild)