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 { }
abstract class MatchArmScope extends VariableScope {
MatchArm arm;
bindingset[arm]
MatchArmScope() { exists(arm) }
Pat getPat() { result = arm.getPat() }
class MatchArmExprScope extends VariableScope {
MatchArmExprScope() { this = any(MatchArm arm).getExpr() }
}
class MatchArmExprScope extends MatchArmScope {
MatchArmExprScope() { this = arm.getExpr() }
}
class MatchArmGuardScope extends MatchArmScope {
MatchArmGuardScope() { this = arm.getGuard() }
class MatchArmGuardScope extends VariableScope {
MatchArmGuardScope() { this = any(MatchArm arm).getGuard() }
}
class ClosureBodyScope extends VariableScope {
@@ -41,7 +32,7 @@ module Impl {
*
* 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 body;
@@ -57,6 +48,12 @@ module Impl {
this = we.getCondition() and
body = we.getLoopBody()
)
or
parent =
any(MatchArm ma |
this = ma.getGuard() and
body = ma.getExpr()
)
}
/** Gets the parent of this condition. */
@@ -417,11 +414,14 @@ module Impl {
ord = getPreOrderNumbering(scope, scope)
or
exists(Pat pat | pat = getAVariablePatAncestor(v) |
scope =
any(MatchArmScope arm |
arm.getPat() = pat and
ord = getPreOrderNumbering(scope, arm)
)
exists(MatchArm arm |
pat = arm.getPat() and
ord = getPreOrderNumbering(scope, scope)
|
scope = arm.getGuard()
or
not arm.hasGuard() and scope = arm.getExpr()
)
or
exists(LetStmt let |
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: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: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: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 |
@@ -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: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: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: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 |
@@ -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: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: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: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 |
@@ -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: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: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: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 |

View File

@@ -375,7 +375,7 @@ fn match_pattern16() {
Some(y) // y1
if let Some(y) = // y2
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: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: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: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 |
@@ -470,7 +470,7 @@ variableReadAccess
| 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: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: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 |