Rust: Handle variables introduced in if-let guards

This commit is contained in:
Tom Hvitved
2025-11-05 19:46:54 +01:00
parent db7b187961
commit c80301d58a
4 changed files with 25 additions and 24 deletions

View File

@@ -15,21 +15,12 @@ module Impl {
class BlockExprScope extends VariableScope, BlockExpr { } class BlockExprScope extends VariableScope, BlockExpr { }
abstract class MatchArmScope extends VariableScope { class MatchArmExprScope extends VariableScope {
MatchArm arm; MatchArmExprScope() { this = any(MatchArm arm).getExpr() }
bindingset[arm]
MatchArmScope() { exists(arm) }
Pat getPat() { result = arm.getPat() }
} }
class MatchArmExprScope extends MatchArmScope { class MatchArmGuardScope extends VariableScope {
MatchArmExprScope() { this = arm.getExpr() } MatchArmGuardScope() { this = any(MatchArm arm).getGuard() }
}
class MatchArmGuardScope extends MatchArmScope {
MatchArmGuardScope() { this = arm.getGuard() }
} }
class ClosureBodyScope extends VariableScope { class ClosureBodyScope extends VariableScope {
@@ -41,7 +32,7 @@ module Impl {
* *
* Such variables are only available in the body guarded by the condition. * Such variables are only available in the body guarded by the condition.
*/ */
class ConditionScope extends VariableScope, Expr { class ConditionScope extends VariableScope {
private AstNode parent; private AstNode parent;
private AstNode body; private AstNode body;
@@ -57,6 +48,12 @@ module Impl {
this = we.getCondition() and this = we.getCondition() and
body = we.getLoopBody() body = we.getLoopBody()
) )
or
parent =
any(MatchArm ma |
this = ma.getGuard() and
body = ma.getExpr()
)
} }
/** Gets the parent of this condition. */ /** Gets the parent of this condition. */
@@ -417,11 +414,14 @@ module Impl {
ord = getPreOrderNumbering(scope, scope) ord = getPreOrderNumbering(scope, scope)
or or
exists(Pat pat | pat = getAVariablePatAncestor(v) | exists(Pat pat | pat = getAVariablePatAncestor(v) |
scope = exists(MatchArm arm |
any(MatchArmScope arm | pat = arm.getPat() and
arm.getPat() = pat and ord = getPreOrderNumbering(scope, scope)
ord = getPreOrderNumbering(scope, arm) |
) scope = arm.getGuard()
or
not arm.hasGuard() and scope = arm.getExpr()
)
or or
exists(LetStmt let | exists(LetStmt let |
let.getPat() = pat and let.getPat() = pat and

View File

@@ -96,6 +96,7 @@ definition
| main.rs:366:18:366:18 | x | main.rs:366:18:366:18 | x | | main.rs:366:18:366:18 | x | main.rs:366:18:366:18 | x |
| main.rs:373:9:373:9 | x | main.rs:373:9:373:9 | x | | main.rs:373:9:373:9 | x | main.rs:373:9:373:9 | x |
| main.rs:375:14:375:14 | y | main.rs:375:14:375:14 | y | | main.rs:375:14:375:14 | y | main.rs:375:14:375:14 | y |
| main.rs:376:25:376:25 | y | main.rs:376:25:376:25 | y |
| main.rs:384:5:384:6 | a8 | main.rs:384:5:384:6 | a8 | | main.rs:384:5:384:6 | a8 | main.rs:384:5:384:6 | a8 |
| main.rs:386:9:386:10 | b3 | main.rs:386:9:386:10 | b3 | | main.rs:386:9:386:10 | b3 | main.rs:386:9:386:10 | b3 |
| main.rs:387:9:387:10 | c1 | main.rs:387:9:387:10 | c1 | | main.rs:387:9:387:10 | c1 | main.rs:387:9:387:10 | c1 |
@@ -288,7 +289,7 @@ read
| main.rs:366:18:366:18 | x | main.rs:366:18:366:18 | x | main.rs:367:20:367:20 | x | | main.rs:366:18:366:18 | x | main.rs:366:18:366:18 | x | main.rs:367:20:367:20 | x |
| main.rs:373:9:373:9 | x | main.rs:373:9:373:9 | x | main.rs:374:11:374:11 | x | | main.rs:373:9:373:9 | x | main.rs:373:9:373:9 | x | main.rs:374:11:374:11 | x |
| main.rs:375:14:375:14 | y | main.rs:375:14:375:14 | y | main.rs:377:22:377:22 | y | | main.rs:375:14:375:14 | y | main.rs:375:14:375:14 | y | main.rs:377:22:377:22 | y |
| main.rs:375:14:375:14 | y | main.rs:375:14:375:14 | y | main.rs:378:26:378:26 | y | | main.rs:376:25:376:25 | y | main.rs:376:25:376:25 | y | main.rs:378:26:378:26 | y |
| main.rs:384:5:384:6 | a8 | main.rs:384:5:384:6 | a8 | main.rs:390:15:390:16 | a8 | | main.rs:384:5:384:6 | a8 | main.rs:384:5:384:6 | a8 | main.rs:390:15:390:16 | a8 |
| main.rs:386:9:386:10 | b3 | main.rs:386:9:386:10 | b3 | main.rs:391:15:391:16 | b3 | | main.rs:386:9:386:10 | b3 | main.rs:386:9:386:10 | b3 | main.rs:391:15:391:16 | b3 |
| main.rs:387:9:387:10 | c1 | main.rs:387:9:387:10 | c1 | main.rs:392:15:392:16 | c1 | | main.rs:387:9:387:10 | c1 | main.rs:387:9:387:10 | c1 | main.rs:392:15:392:16 | c1 |
@@ -479,6 +480,7 @@ firstRead
| main.rs:366:18:366:18 | x | main.rs:366:18:366:18 | x | main.rs:367:20:367:20 | x | | main.rs:366:18:366:18 | x | main.rs:366:18:366:18 | x | main.rs:367:20:367:20 | x |
| main.rs:373:9:373:9 | x | main.rs:373:9:373:9 | x | main.rs:374:11:374:11 | x | | main.rs:373:9:373:9 | x | main.rs:373:9:373:9 | x | main.rs:374:11:374:11 | x |
| main.rs:375:14:375:14 | y | main.rs:375:14:375:14 | y | main.rs:377:22:377:22 | y | | main.rs:375:14:375:14 | y | main.rs:375:14:375:14 | y | main.rs:377:22:377:22 | y |
| main.rs:376:25:376:25 | y | main.rs:376:25:376:25 | y | main.rs:378:26:378:26 | y |
| main.rs:384:5:384:6 | a8 | main.rs:384:5:384:6 | a8 | main.rs:390:15:390:16 | a8 | | main.rs:384:5:384:6 | a8 | main.rs:384:5:384:6 | a8 | main.rs:390:15:390:16 | a8 |
| main.rs:386:9:386:10 | b3 | main.rs:386:9:386:10 | b3 | main.rs:391:15:391:16 | b3 | | main.rs:386:9:386:10 | b3 | main.rs:386:9:386:10 | b3 | main.rs:391:15:391:16 | b3 |
| main.rs:387:9:387:10 | c1 | main.rs:387:9:387:10 | c1 | main.rs:392:15:392:16 | c1 | | main.rs:387:9:387:10 | c1 | main.rs:387:9:387:10 | c1 | main.rs:392:15:392:16 | c1 |
@@ -587,7 +589,6 @@ adjacentReads
| main.rs:334:9:334:9 | x | main.rs:334:9:334:9 | x | main.rs:335:11:335:11 | x | main.rs:343:15:343:15 | x | | main.rs:334:9:334:9 | x | main.rs:334:9:334:9 | x | main.rs:335:11:335:11 | x | main.rs:343:15:343:15 | x |
| main.rs:348:9:348:9 | x | main.rs:348:9:348:9 | x | main.rs:350:7:350:7 | x | main.rs:355:7:355:7 | x | | main.rs:348:9:348:9 | x | main.rs:348:9:348:9 | x | main.rs:350:7:350:7 | x | main.rs:355:7:355:7 | x |
| main.rs:348:9:348:9 | x | main.rs:348:9:348:9 | x | main.rs:355:7:355:7 | x | main.rs:359:19:359:19 | x | | main.rs:348:9:348:9 | x | main.rs:348:9:348:9 | x | main.rs:355:7:355:7 | x | main.rs:359:19:359:19 | x |
| main.rs:375:14:375:14 | y | main.rs:375:14:375:14 | y | main.rs:377:22:377:22 | y | main.rs:378:26:378:26 | y |
| main.rs:402:13:402:15 | a10 | main.rs:402:13:402:15 | a10 | main.rs:406:15:406:17 | a10 | main.rs:415:9:415:11 | a10 | | main.rs:402:13:402:15 | a10 | main.rs:402:13:402:15 | a10 | main.rs:406:15:406:17 | a10 | main.rs:415:9:415:11 | a10 |
| main.rs:403:13:403:14 | b4 | main.rs:403:13:403:14 | b4 | main.rs:407:15:407:16 | b4 | main.rs:416:9:416:10 | b4 | | main.rs:403:13:403:14 | b4 | main.rs:403:13:403:14 | b4 | main.rs:407:15:407:16 | b4 | main.rs:416:9:416:10 | b4 |
| main.rs:404:13:404:14 | c2 | main.rs:404:13:404:14 | c2 | main.rs:408:15:408:16 | c2 | main.rs:417:9:417:10 | c2 | | main.rs:404:13:404:14 | c2 | main.rs:404:13:404:14 | c2 | main.rs:408:15:408:16 | c2 | main.rs:417:9:417:10 | c2 |

View File

@@ -375,7 +375,7 @@ fn match_pattern16() {
Some(y) // y1 Some(y) // y1
if let Some(y) = // y2 if let Some(y) = // y2
Some(y) // $ read_access=y1 Some(y) // $ read_access=y1
=> print_i64(y), // $ MISSING: read_access=y2 $ SPURIOUS: read_access=y1 => print_i64(y), // $ read_access=y2
_ => {}, _ => {},
} }
} }

View File

@@ -238,7 +238,7 @@ variableAccess
| main.rs:367:20:367:20 | x | main.rs:366:18:366:18 | x | | main.rs:367:20:367:20 | x | main.rs:366:18:366:18 | x |
| main.rs:374:11:374:11 | x | main.rs:373:9:373:9 | x | | main.rs:374:11:374:11 | x | main.rs:373:9:373:9 | x |
| main.rs:377:22:377:22 | y | main.rs:375:14:375:14 | y | | main.rs:377:22:377:22 | y | main.rs:375:14:375:14 | y |
| main.rs:378:26:378:26 | y | main.rs:375:14:375:14 | y | | main.rs:378:26:378:26 | y | main.rs:376:25:376:25 | y |
| main.rs:390:15:390:16 | a8 | main.rs:384:5:384:6 | a8 | | main.rs:390:15:390:16 | a8 | main.rs:384:5:384:6 | a8 |
| main.rs:391:15:391:16 | b3 | main.rs:386:9:386:10 | b3 | | main.rs:391:15:391:16 | b3 | main.rs:386:9:386:10 | b3 |
| main.rs:392:15:392:16 | c1 | main.rs:387:9:387:10 | c1 | | main.rs:392:15:392:16 | c1 | main.rs:387:9:387:10 | c1 |
@@ -470,7 +470,7 @@ variableReadAccess
| main.rs:367:20:367:20 | x | main.rs:366:18:366:18 | x | | main.rs:367:20:367:20 | x | main.rs:366:18:366:18 | x |
| main.rs:374:11:374:11 | x | main.rs:373:9:373:9 | x | | main.rs:374:11:374:11 | x | main.rs:373:9:373:9 | x |
| main.rs:377:22:377:22 | y | main.rs:375:14:375:14 | y | | main.rs:377:22:377:22 | y | main.rs:375:14:375:14 | y |
| main.rs:378:26:378:26 | y | main.rs:375:14:375:14 | y | | main.rs:378:26:378:26 | y | main.rs:376:25:376:25 | y |
| main.rs:390:15:390:16 | a8 | main.rs:384:5:384:6 | a8 | | main.rs:390:15:390:16 | a8 | main.rs:384:5:384:6 | a8 |
| main.rs:391:15:391:16 | b3 | main.rs:386:9:386:10 | b3 | | main.rs:391:15:391:16 | b3 | main.rs:386:9:386:10 | b3 |
| main.rs:392:15:392:16 | c1 | main.rs:387:9:387:10 | c1 | | main.rs:392:15:392:16 | c1 | main.rs:387:9:387:10 | c1 |