Skip to content

Commit c17c045

Browse files
committed
Rust: Handle type equality for a few more expression types
1 parent 8230483 commit c17c045

File tree

7 files changed

+56
-10
lines changed

7 files changed

+56
-10
lines changed

rust/ql/lib/codeql/rust/controlflow/internal/Completion.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ class BooleanCompletion extends ConditionalCompletion, TBooleanCompletion {
9090
or
9191
e = parent.(BinaryLogicalOperation).getRhs()
9292
or
93-
parent = any(IfExpr ie | e = [ie.getThen(), ie.getElse()])
93+
e = parent.(IfExpr).getABranch()
9494
or
9595
e = parent.(MatchExpr).getAnArm().getExpr()
9696
or

rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ module ExprTrees {
336336
override predicate first(AstNode node) { first(super.getCondition(), node) }
337337

338338
override predicate propagatesAbnormal(AstNode child) {
339-
child = [super.getCondition(), super.getThen(), super.getElse()]
339+
child = [super.getCondition(), super.getABranch()]
340340
}
341341

342342
private ConditionalCompletion conditionCompletion(Completion c) {

rust/ql/lib/codeql/rust/controlflow/internal/Splitting.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ module ConditionalCompletionSplitting {
8181
(
8282
child = parent.(BinaryLogicalOperation).getAnOperand()
8383
or
84-
parent = any(IfExpr ie | child = [ie.getThen(), ie.getElse()])
84+
child = parent.(IfExpr).getABranch()
8585
or
8686
child = parent.(MatchExpr).getAnArm().getExpr()
8787
or

rust/ql/lib/codeql/rust/elements/internal/IfExprImpl.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,8 @@ module Impl {
3939
or
4040
index = 3 and this.hasElse() and result = "else {...}"
4141
}
42+
43+
/** Gets any of the branches of this if expression. */
44+
Expr getABranch() { result = [this.getThen(), this.getElse()] }
4245
}
4346
}

rust/ql/lib/codeql/rust/internal/TypeInference.qll

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,18 @@ private predicate typeEquality(AstNode n1, TypePath path1, AstNode n2, TypePath
158158
or
159159
n1 = n2.(BlockExpr).getStmtList().getTailExpr() and
160160
path1 = path2
161+
or
162+
n1 = n2.(IfExpr).getABranch() and
163+
path1 = path2
164+
or
165+
n1 = n2.(MatchExpr).getAnArm().getExpr() and
166+
path1 = path2
167+
or
168+
exists(BreakExpr break |
169+
break.getExpr() = n1 and
170+
break.getTarget() = n2.(LoopExpr) and
171+
path1 = path2
172+
)
161173
}
162174

163175
pragma[nomagic]

rust/ql/test/library-tests/type-inference/main.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,8 @@ mod m6 {
225225
impl<T> MyEnum<T> {
226226
fn m1(self) -> T {
227227
match self {
228-
MyEnum::C1(a) => a, // missing
229-
MyEnum::C2 { a } => a, // missing
228+
MyEnum::C1(a) => a,
229+
MyEnum::C2 { a } => a,
230230
}
231231
}
232232
}
@@ -402,8 +402,8 @@ mod m9 {
402402
impl<T> MyOption<MyOption<T>> {
403403
fn flatten(self) -> MyOption<T> {
404404
match self {
405-
MyOption::MyNone() => MyOption::MyNone(), // missing inner type `Option<T>`
406-
MyOption::MySome(x) => x, // missing
405+
MyOption::MyNone() => MyOption::MyNone(),
406+
MyOption::MySome(x) => x,
407407
}
408408
}
409409
}
@@ -434,21 +434,21 @@ mod m9 {
434434
println!("{:?}", MyOption::<MyOption<S>>::flatten(x6));
435435

436436
let from_if = if 1 + 1 > 2 {
437-
MyOption::MyNone() // missing type `S` at `T``
437+
MyOption::MyNone()
438438
} else {
439439
MyOption::MySome(S)
440440
};
441441
println!("{:?}", from_if);
442442

443443
let from_match = match 1 + 1 > 2 {
444-
true => MyOption::MyNone(), // missing type `S` at `T``
444+
true => MyOption::MyNone(),
445445
false => MyOption::MySome(S),
446446
};
447447
println!("{:?}", from_match);
448448

449449
let from_loop = loop {
450450
if 1 + 1 > 2 {
451-
break MyOption::MyNone(); // missing type `S` at `T``
451+
break MyOption::MyNone();
452452
}
453453
break MyOption::MySome(S);
454454
};

rust/ql/test/library-tests/type-inference/type-inference.expected

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,10 @@ inferType
229229
| main.rs:227:13:230:13 | match self { ... } | | main.rs:225:10:225:10 | T |
230230
| main.rs:227:19:227:22 | self | | main.rs:214:5:218:5 | enum MyEnum |
231231
| main.rs:227:19:227:22 | self | A | main.rs:225:10:225:10 | T |
232+
| main.rs:228:28:228:28 | a | | main.rs:225:10:225:10 | T |
233+
| main.rs:228:34:228:34 | a | | main.rs:225:10:225:10 | T |
234+
| main.rs:229:30:229:30 | a | | main.rs:225:10:225:10 | T |
235+
| main.rs:229:37:229:37 | a | | main.rs:225:10:225:10 | T |
232236
| main.rs:235:13:235:13 | x | | main.rs:214:5:218:5 | enum MyEnum |
233237
| main.rs:235:13:235:13 | x | A | main.rs:220:5:221:14 | struct S1 |
234238
| main.rs:235:17:235:30 | ...::C1(...) | | main.rs:214:5:218:5 | enum MyEnum |
@@ -451,6 +455,11 @@ inferType
451455
| main.rs:404:19:404:22 | self | T | main.rs:378:5:382:5 | enum MyOption |
452456
| main.rs:404:19:404:22 | self | T.T | main.rs:402:10:402:10 | T |
453457
| main.rs:405:39:405:56 | ...::MyNone(...) | | main.rs:378:5:382:5 | enum MyOption |
458+
| main.rs:405:39:405:56 | ...::MyNone(...) | T | main.rs:402:10:402:10 | T |
459+
| main.rs:406:34:406:34 | x | | main.rs:378:5:382:5 | enum MyOption |
460+
| main.rs:406:34:406:34 | x | T | main.rs:402:10:402:10 | T |
461+
| main.rs:406:40:406:40 | x | | main.rs:378:5:382:5 | enum MyOption |
462+
| main.rs:406:40:406:40 | x | T | main.rs:402:10:402:10 | T |
454463
| main.rs:415:13:415:14 | x1 | | main.rs:378:5:382:5 | enum MyOption |
455464
| main.rs:415:18:415:37 | ...::new(...) | | main.rs:378:5:382:5 | enum MyOption |
456465
| main.rs:416:26:416:27 | x1 | | main.rs:378:5:382:5 | enum MyOption |
@@ -512,21 +521,43 @@ inferType
512521
| main.rs:434:59:434:60 | x6 | | main.rs:378:5:382:5 | enum MyOption |
513522
| main.rs:434:59:434:60 | x6 | T | main.rs:378:5:382:5 | enum MyOption |
514523
| main.rs:434:59:434:60 | x6 | T.T | main.rs:411:5:412:13 | struct S |
524+
| main.rs:436:13:436:19 | from_if | | main.rs:378:5:382:5 | enum MyOption |
525+
| main.rs:436:13:436:19 | from_if | T | main.rs:411:5:412:13 | struct S |
526+
| main.rs:436:23:440:9 | if ... {...} else {...} | | main.rs:378:5:382:5 | enum MyOption |
527+
| main.rs:436:23:440:9 | if ... {...} else {...} | T | main.rs:411:5:412:13 | struct S |
515528
| main.rs:436:36:438:9 | { ... } | | main.rs:378:5:382:5 | enum MyOption |
529+
| main.rs:436:36:438:9 | { ... } | T | main.rs:411:5:412:13 | struct S |
516530
| main.rs:437:13:437:30 | ...::MyNone(...) | | main.rs:378:5:382:5 | enum MyOption |
531+
| main.rs:437:13:437:30 | ...::MyNone(...) | T | main.rs:411:5:412:13 | struct S |
517532
| main.rs:438:16:440:9 | { ... } | | main.rs:378:5:382:5 | enum MyOption |
518533
| main.rs:438:16:440:9 | { ... } | T | main.rs:411:5:412:13 | struct S |
519534
| main.rs:439:13:439:31 | ...::MySome(...) | | main.rs:378:5:382:5 | enum MyOption |
520535
| main.rs:439:13:439:31 | ...::MySome(...) | T | main.rs:411:5:412:13 | struct S |
521536
| main.rs:439:30:439:30 | S | | main.rs:411:5:412:13 | struct S |
537+
| main.rs:441:26:441:32 | from_if | | main.rs:378:5:382:5 | enum MyOption |
538+
| main.rs:441:26:441:32 | from_if | T | main.rs:411:5:412:13 | struct S |
539+
| main.rs:443:13:443:22 | from_match | | main.rs:378:5:382:5 | enum MyOption |
540+
| main.rs:443:13:443:22 | from_match | T | main.rs:411:5:412:13 | struct S |
541+
| main.rs:443:26:446:9 | match ... { ... } | | main.rs:378:5:382:5 | enum MyOption |
542+
| main.rs:443:26:446:9 | match ... { ... } | T | main.rs:411:5:412:13 | struct S |
522543
| main.rs:444:21:444:38 | ...::MyNone(...) | | main.rs:378:5:382:5 | enum MyOption |
544+
| main.rs:444:21:444:38 | ...::MyNone(...) | T | main.rs:411:5:412:13 | struct S |
523545
| main.rs:445:22:445:40 | ...::MySome(...) | | main.rs:378:5:382:5 | enum MyOption |
524546
| main.rs:445:22:445:40 | ...::MySome(...) | T | main.rs:411:5:412:13 | struct S |
525547
| main.rs:445:39:445:39 | S | | main.rs:411:5:412:13 | struct S |
548+
| main.rs:447:26:447:35 | from_match | | main.rs:378:5:382:5 | enum MyOption |
549+
| main.rs:447:26:447:35 | from_match | T | main.rs:411:5:412:13 | struct S |
550+
| main.rs:449:13:449:21 | from_loop | | main.rs:378:5:382:5 | enum MyOption |
551+
| main.rs:449:13:449:21 | from_loop | T | main.rs:411:5:412:13 | struct S |
552+
| main.rs:449:25:454:9 | loop { ... } | | main.rs:378:5:382:5 | enum MyOption |
553+
| main.rs:449:25:454:9 | loop { ... } | T | main.rs:411:5:412:13 | struct S |
526554
| main.rs:451:23:451:40 | ...::MyNone(...) | | main.rs:378:5:382:5 | enum MyOption |
555+
| main.rs:451:23:451:40 | ...::MyNone(...) | T | main.rs:411:5:412:13 | struct S |
527556
| main.rs:453:19:453:37 | ...::MySome(...) | | main.rs:378:5:382:5 | enum MyOption |
528557
| main.rs:453:19:453:37 | ...::MySome(...) | T | main.rs:411:5:412:13 | struct S |
529558
| main.rs:453:36:453:36 | S | | main.rs:411:5:412:13 | struct S |
559+
| main.rs:455:26:455:34 | from_loop | | main.rs:378:5:382:5 | enum MyOption |
560+
| main.rs:455:26:455:34 | from_loop | T | main.rs:411:5:412:13 | struct S |
530561
| main.rs:468:15:468:18 | SelfParam | | main.rs:461:5:462:19 | struct S |
531562
| main.rs:468:15:468:18 | SelfParam | T | main.rs:467:10:467:10 | T |
532563
| main.rs:468:26:470:9 | { ... } | | main.rs:467:10:467:10 | T |

0 commit comments

Comments
 (0)