Skip to content

Commit d7035c2

Browse files
committed
fix(linter): support let-chains in codegen node type detection
1 parent 86546c5 commit d7035c2

File tree

1 file changed

+39
-7
lines changed

1 file changed

+39
-7
lines changed

tasks/linter_codegen/src/if_else_detector.rs

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,46 @@ impl IfElseKindDetector {
4949
}
5050
}
5151

52-
/// Extracts AstKind variants from an `if let` condition like `if let AstKind::Xxx(..) = node.kind()`.
52+
/// Extracts AstKind variants from an `if let` condition like `if let AstKind::Xxx(..) = node.kind()`
53+
/// or `if let AstKind::Xxx(..) = node.kind() && other_condition`.
5354
fn extract_variants_from_if_let_condition(&mut self, cond: &Expr) -> CollectionResult {
54-
let Expr::Let(let_expr) = cond else { return CollectionResult::Incomplete };
55-
// RHS must be `node.kind()`
56-
if is_node_kind_call(&let_expr.expr) {
57-
self.extract_variants_from_pat(&let_expr.pat)
58-
} else {
59-
CollectionResult::Incomplete
55+
match cond {
56+
// Simple `if let` pattern
57+
Expr::Let(let_expr) => {
58+
// RHS must be `node.kind()`
59+
if is_node_kind_call(&let_expr.expr) {
60+
self.extract_variants_from_pat(&let_expr.pat)
61+
} else {
62+
CollectionResult::Incomplete
63+
}
64+
}
65+
// `if let ... && ...` pattern (from MSRV 1.88.0)
66+
// The entire condition might be a chain of binary && operations
67+
Expr::Binary(binary) if matches!(binary.op, syn::BinOp::And(_)) => {
68+
// Try to find the let expression in the leftmost part of the chain
69+
self.extract_from_binary_and_chain(binary)
70+
}
71+
_ => CollectionResult::Incomplete,
72+
}
73+
}
74+
75+
/// Recursively extract from a binary && chain to find the let expression
76+
fn extract_from_binary_and_chain(&mut self, binary: &syn::ExprBinary) -> CollectionResult {
77+
// Check if the left side is another binary expression (nested &&)
78+
match &*binary.left {
79+
Expr::Binary(left_binary) if matches!(left_binary.op, syn::BinOp::And(_)) => {
80+
// Recursively check the left side
81+
self.extract_from_binary_and_chain(left_binary)
82+
}
83+
Expr::Let(let_expr) => {
84+
// Found the let expression
85+
if is_node_kind_call(&let_expr.expr) {
86+
self.extract_variants_from_pat(&let_expr.pat)
87+
} else {
88+
CollectionResult::Incomplete
89+
}
90+
}
91+
_ => CollectionResult::Incomplete,
6092
}
6193
}
6294

0 commit comments

Comments
 (0)