From 2fe73cea5ef8e381e47161468167c90ed3fb724a Mon Sep 17 00:00:00 2001 From: yukang Date: Wed, 14 Feb 2024 15:15:22 +0800 Subject: [PATCH] Fix false positive with if let and ranges --- compiler/rustc_lint/src/unused.rs | 16 ++++++++++++---- tests/ui/lint/issue-121070-let-range.rs | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 tests/ui/lint/issue-121070-let-range.rs diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 9f670893b270d..35ee0c530463b 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 0000000000000..84598dcd2581d --- /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); + } +}