Fix false positive with if let and ranges

This commit is contained in:
yukang 2024-02-14 15:15:22 +08:00
parent b381d3ab27
commit 2fe73cea5e
2 changed files with 28 additions and 4 deletions

View File

@ -651,9 +651,11 @@ trait UnusedDelimLint {
fn is_expr_delims_necessary( fn is_expr_delims_necessary(
inner: &ast::Expr, inner: &ast::Expr,
ctx: UnusedDelimsCtx,
followed_by_block: bool, followed_by_block: bool,
followed_by_else: bool,
) -> bool { ) -> bool {
let followed_by_else = ctx == UnusedDelimsCtx::AssignedValueLetElse;
if followed_by_else { if followed_by_else {
match inner.kind { match inner.kind {
ast::ExprKind::Binary(op, ..) if op.node.is_lazy() => return true, 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) }`. // Check if LHS needs parens to prevent false-positives in cases like `fn x() -> u8 { ({ 0 } + 1) }`.
{ {
let mut innermost = inner; let mut innermost = inner;
@ -1007,8 +1016,7 @@ impl UnusedDelimLint for UnusedParens {
) { ) {
match value.kind { match value.kind {
ast::ExprKind::Paren(ref inner) => { ast::ExprKind::Paren(ref inner) => {
let followed_by_else = ctx == UnusedDelimsCtx::AssignedValueLetElse; if !Self::is_expr_delims_necessary(inner, ctx, followed_by_block)
if !Self::is_expr_delims_necessary(inner, followed_by_block, followed_by_else)
&& value.attrs.is_empty() && value.attrs.is_empty()
&& !value.span.from_expansion() && !value.span.from_expansion()
&& (ctx != UnusedDelimsCtx::LetScrutineeExpr && (ctx != UnusedDelimsCtx::LetScrutineeExpr
@ -1334,7 +1342,7 @@ impl UnusedDelimLint for UnusedBraces {
// FIXME(const_generics): handle paths when #67075 is fixed. // FIXME(const_generics): handle paths when #67075 is fixed.
if let [stmt] = inner.stmts.as_slice() { if let [stmt] = inner.stmts.as_slice() {
if let ast::StmtKind::Expr(ref expr) = stmt.kind { 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 && (ctx != UnusedDelimsCtx::AnonConst
|| (matches!(expr.kind, ast::ExprKind::Lit(_)) || (matches!(expr.kind, ast::ExprKind::Lit(_))
&& !expr.span.from_expansion())) && !expr.span.from_expansion()))

View File

@ -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);
}
}