Skip to content

Commit 60f96ee

Browse files
authored
Merge pull request #19026 from paldepind/rust-expr-type-eq
Rust: Handle type equality for a few more expression types
2 parents 9a8cb1a + c17c045 commit 60f96ee

File tree

7 files changed

+329
-247
lines changed

7 files changed

+329
-247
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: 25 additions & 4 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
}
@@ -432,6 +432,27 @@ mod m9 {
432432

433433
let x6 = MyOption::MySome(MyOption::<S>::MyNone());
434434
println!("{:?}", MyOption::<MyOption<S>>::flatten(x6));
435+
436+
let from_if = if 1 + 1 > 2 {
437+
MyOption::MyNone()
438+
} else {
439+
MyOption::MySome(S)
440+
};
441+
println!("{:?}", from_if);
442+
443+
let from_match = match 1 + 1 > 2 {
444+
true => MyOption::MyNone(),
445+
false => MyOption::MySome(S),
446+
};
447+
println!("{:?}", from_match);
448+
449+
let from_loop = loop {
450+
if 1 + 1 > 2 {
451+
break MyOption::MyNone();
452+
}
453+
break MyOption::MySome(S);
454+
};
455+
println!("{:?}", from_loop);
435456
}
436457
}
437458

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

Lines changed: 286 additions & 240 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)