about summary refs log tree commit diff
diff options
context:
space:
mode:
authoryukang <moorekang@gmail.com>2024-02-14 15:15:22 +0800
committeryukang <moorekang@gmail.com>2024-02-14 15:15:22 +0800
commit2fe73cea5ef8e381e47161468167c90ed3fb724a (patch)
treedc59312b1eb2c2b7b0a3b195c0df41a212def7a5
parentb381d3ab27f788f990551100c4425bb782d26d76 (diff)
downloadrust-2fe73cea5ef8e381e47161468167c90ed3fb724a.tar.gz
rust-2fe73cea5ef8e381e47161468167c90ed3fb724a.zip
Fix false positive with if let and ranges
-rw-r--r--compiler/rustc_lint/src/unused.rs16
-rw-r--r--tests/ui/lint/issue-121070-let-range.rs16
2 files changed, 28 insertions, 4 deletions
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 9f670893b27..35ee0c53046 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -651,9 +651,11 @@ trait UnusedDelimLint {
 
     fn is_expr_delims_necessary(
         inner: &ast::Expr,
+        ctx: UnusedDelimsCtx,
         followed_by_block: bool,
-        followed_by_else: bool,
     ) -> bool {
+        let followed_by_else = ctx == UnusedDelimsCtx::AssignedValueLetElse;
+
         if followed_by_else {
             match inner.kind {
                 ast::ExprKind::Binary(op, ..) if op.node.is_lazy() => return true,
@@ -662,6 +664,13 @@ trait UnusedDelimLint {
             }
         }
 
+        // Check it's range in LetScrutineeExpr
+        if let ast::ExprKind::Range(..) = inner.kind
+            && matches!(ctx, UnusedDelimsCtx::LetScrutineeExpr)
+        {
+            return true;
+        }
+
         // Check if LHS needs parens to prevent false-positives in cases like `fn x() -> u8 { ({ 0 } + 1) }`.
         {
             let mut innermost = inner;
@@ -1007,8 +1016,7 @@ impl UnusedDelimLint for UnusedParens {
     ) {
         match value.kind {
             ast::ExprKind::Paren(ref inner) => {
-                let followed_by_else = ctx == UnusedDelimsCtx::AssignedValueLetElse;
-                if !Self::is_expr_delims_necessary(inner, followed_by_block, followed_by_else)
+                if !Self::is_expr_delims_necessary(inner, ctx, followed_by_block)
                     && value.attrs.is_empty()
                     && !value.span.from_expansion()
                     && (ctx != UnusedDelimsCtx::LetScrutineeExpr
@@ -1334,7 +1342,7 @@ impl UnusedDelimLint for UnusedBraces {
                 // FIXME(const_generics): handle paths when #67075 is fixed.
                 if let [stmt] = inner.stmts.as_slice() {
                     if let ast::StmtKind::Expr(ref expr) = stmt.kind {
-                        if !Self::is_expr_delims_necessary(expr, followed_by_block, false)
+                        if !Self::is_expr_delims_necessary(expr, ctx, followed_by_block)
                             && (ctx != UnusedDelimsCtx::AnonConst
                                 || (matches!(expr.kind, ast::ExprKind::Lit(_))
                                     && !expr.span.from_expansion()))
diff --git a/tests/ui/lint/issue-121070-let-range.rs b/tests/ui/lint/issue-121070-let-range.rs
new file mode 100644
index 00000000000..84598dcd258
--- /dev/null
+++ b/tests/ui/lint/issue-121070-let-range.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+#![feature(let_chains)]
+#![allow(irrefutable_let_patterns)]
+fn main() {
+    let _a = 0..1;
+
+    if let x = (0..1) {
+        eprintln!("x: {:?}", x);
+    }
+    if let x = (0..1) &&
+        let _y = (0..2)
+    {
+        eprintln!("x: {:?}", x);
+    }
+}