Skip to content

Commit 249f7c3

Browse files
committed
wip9
1 parent 2f0570f commit 249f7c3

4 files changed

Lines changed: 203 additions & 145 deletions

File tree

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

Lines changed: 57 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ private module Input3 implements InputSig3 {
312312

313313
class Expr = Rust::Expr;
314314

315-
class SwitchExpr extends Rust::MatchExpr {
315+
class Switch extends Rust::MatchExpr {
316316
Expr getExpr() { result = this.getScrutinee() }
317317

318318
Case getCase(int index) { result = this.getArm(index) }
@@ -321,7 +321,7 @@ private module Input3 implements InputSig3 {
321321
class Case extends Rust::MatchArm {
322322
AstNode getAPattern() { result = this.getPat() }
323323

324-
Expr getBody() { result = this.getExpr() }
324+
AstNode getBody() { result = this.getExpr() }
325325
}
326326

327327
class ConditionalExpr extends IfExpr {
@@ -430,7 +430,7 @@ private module Input3 implements InputSig3 {
430430
)
431431
}
432432

433-
predicate certainTypeEqualityInput(AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2) {
433+
predicate inferStepSymmetricCertain(AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2) {
434434
n1 =
435435
any(IdentPat ip |
436436
n2 = ip.getName() and
@@ -459,7 +459,7 @@ private module Input3 implements InputSig3 {
459459
)
460460
}
461461

462-
Type inferCertainTypeInput(AstNode n, TypePath path) {
462+
Type inferTypeCertainInput(AstNode n, TypePath path) {
463463
result = inferFunctionBodyType(n, path)
464464
or
465465
result = inferLiteralType(n, path, true)
@@ -500,15 +500,10 @@ private module Input3 implements InputSig3 {
500500
result = closureRootType()
501501
}
502502

503-
predicate typeEqualityInput(AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2) {
503+
predicate inferStepSymmetric(AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2) {
504504
prefix1.isEmpty() and
505505
prefix2.isEmpty() and
506506
(
507-
exists(MatchExpr me |
508-
n1 = me.getScrutinee() and
509-
n2 = me.getAnArm().getPat()
510-
)
511-
or
512507
n1 = n2.(OrPat).getAPat()
513508
or
514509
n1 = n2.(ParenPat).getPat()
@@ -572,7 +567,7 @@ private module Input3 implements InputSig3 {
572567
prefix2.isEmpty()
573568
}
574569

575-
predicate typeEqualityAsymmetricInput(AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2) {
570+
predicate inferStep(AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2) {
576571
// When `n2` is `*n1` propagate type information from a raw pointer type
577572
// parameter at `n1`. The other direction is handled in
578573
// `inferDereferencedExprPtrType`.
@@ -596,23 +591,21 @@ private module Input3 implements InputSig3 {
596591
*
597592
* [1]: https://doc.rust-lang.org/reference/type-coercions.html#r-coerce.least-upper-bound
598593
*/
599-
predicate parentChildType(AstNode parent, AstNode child, TypePath prefix) {
600-
child = parent.(IfExpr).getABranch() and
601-
prefix.isEmpty()
602-
or
603-
parent = any(MatchExpr me | child = me.getAnArm().getExpr()) and
604-
prefix.isEmpty()
605-
or
606-
parent = any(ArrayListExpr ale | child = ale.getAnExpr()) and
607-
prefix = TypePath::singleton(getArrayTypeParameter())
608-
or
609-
bodyReturns(parent, child) and
610-
prefix.isEmpty()
611-
or
612-
exists(Struct s |
613-
child = [parent.(RangeExpr).getStart(), parent.(RangeExpr).getEnd()] and
614-
prefix = TypePath::singleton(TTypeParamTypeParameter(s.getGenericParamList().getATypeParam())) and
615-
s = getRangeType(parent)
594+
predicate inferLubStep(AstNode child, TypePath path1, AstNode parent, TypePath prefix) {
595+
path1.isEmpty() and
596+
(
597+
parent = any(ArrayListExpr ale | child = ale.getAnExpr()) and
598+
prefix = TypePath::singleton(getArrayTypeParameter())
599+
or
600+
bodyReturns(parent, child) and
601+
prefix.isEmpty()
602+
or
603+
exists(Struct s |
604+
child = [parent.(RangeExpr).getStart(), parent.(RangeExpr).getEnd()] and
605+
prefix =
606+
TypePath::singleton(TTypeParamTypeParameter(s.getGenericParamList().getATypeParam())) and
607+
s = getRangeType(parent)
608+
)
616609
)
617610
}
618611

@@ -652,14 +645,14 @@ import M3
652645
module Consistency {
653646
import M2::Consistency
654647

655-
private Type inferCertainTypeAdj(AstNode n, TypePath path) {
656-
result = CertainTypeInference::inferCertainType(n, path) and
648+
private Type inferTypeCertainAdj(AstNode n, TypePath path) {
649+
result = inferTypeCertain(n, path) and
657650
not result = TNeverType()
658651
}
659652

660653
predicate nonUniqueCertainType(AstNode n, TypePath path, Type t) {
661-
strictcount(inferCertainTypeAdj(n, path)) > 1 and
662-
t = inferCertainTypeAdj(n, path) and
654+
strictcount(inferTypeCertainAdj(n, path)) > 1 and
655+
t = inferTypeCertainAdj(n, path) and
663656
// Suppress the inconsistency if `n` is a self parameter and the type
664657
// mention for the self type has multiple types for a path.
665658
not exists(ImplItemNode impl, TypePath selfTypePath |
@@ -922,8 +915,8 @@ private predicate bodyReturns(Expr body, Expr e) {
922915
)
923916
}
924917

925-
private Type inferUnknownTypeFromAnnotation(AstNode n, TypePath path) {
926-
inferType(n, path) = TUnknownType() and
918+
pragma[nomagic]
919+
private Type inferUnknownTypeFromAnnotationCand(AstNode n, TypePath path, TypePath prefix) {
927920
// Normally, these are coercion sites, but in case a type is unknown we
928921
// allow for type information to flow from the type annotation.
929922
exists(TypeMention tm | result = tm.getTypeAt(path) |
@@ -932,6 +925,14 @@ private Type inferUnknownTypeFromAnnotation(AstNode n, TypePath path) {
932925
tm = any(ClosureExpr ce | n = ce.getBody()).getRetType().getTypeRepr()
933926
or
934927
tm = getReturnTypeMention(any(Function f | n = f.getBody()))
928+
) and
929+
prefix = path.getAPrefix()
930+
}
931+
932+
private Type inferUnknownTypeFromAnnotation(AstNode n, TypePath path) {
933+
exists(TypePath prefix |
934+
result = inferUnknownTypeFromAnnotationCand(n, path, prefix) and
935+
hasUnknownTypeAt(n, prefix)
935936
)
936937
}
937938

@@ -3019,7 +3020,7 @@ private module ConstructionMatchingInput implements MatchingInputSig {
30193020
or
30203021
exists(TypePath suffix |
30213022
suffix.isCons(TTypeParamTypeParameter(apos.asTypeParam()), path) and
3022-
result = CertainTypeInference::inferCertainType(this, suffix)
3023+
result = inferTypeCertain(this, suffix)
30233024
)
30243025
}
30253026

@@ -3628,6 +3629,15 @@ private Type inferForLoopExprType(AstNode n, TypePath path) {
36283629
)
36293630
}
36303631

3632+
pragma[nomagic]
3633+
private Type inferClosureExprBodyTypeCand(AstNode n, TypePath path, TypePath prefix) {
3634+
exists(ClosureExpr ce |
3635+
n = ce.getClosureBody() and
3636+
result = inferType(ce, closureReturnPath().appendInverse(path)) and
3637+
prefix = path.getAPrefix()
3638+
)
3639+
}
3640+
36313641
pragma[nomagic]
36323642
private Type inferClosureExprType(AstNode n, TypePath path) {
36333643
exists(ClosureExpr ce |
@@ -3650,6 +3660,11 @@ private Type inferClosureExprType(AstNode n, TypePath path) {
36503660
path.isEmpty()
36513661
)
36523662
)
3663+
or
3664+
exists(TypePath prefix |
3665+
result = inferClosureExprBodyTypeCand(n, path, prefix) and
3666+
hasUnknownTypeAt(n, prefix)
3667+
)
36533668
}
36543669

36553670
pragma[nomagic]
@@ -3716,7 +3731,7 @@ private module Debug {
37163731
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
37173732
result.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
37183733
filepath.matches("%/main.rs") and
3719-
startline = 103
3734+
startline = 1102
37203735
)
37213736
}
37223737

@@ -3756,11 +3771,10 @@ private module Debug {
37563771
tm.getTypeAt(path) = type
37573772
}
37583773

3759-
Type debugInferAnnotatedType(AstNode n, TypePath path) {
3760-
n = getRelevantLocatable() and
3761-
result = CertainTypeInference::inferAnnotatedType(n, path)
3762-
}
3763-
3774+
// Type debugInferAnnotatedType(AstNode n, TypePath path) {
3775+
// n = getRelevantLocatable() and
3776+
// result = inferAnnotatedType(n, path)
3777+
// }
37643778
pragma[nomagic]
37653779
private int countTypesAtPath(AstNode n, TypePath path, Type t) {
37663780
t = inferType(n, path) and
@@ -3809,9 +3823,9 @@ private module Debug {
38093823
c = max(countTypePaths(_, _, _))
38103824
}
38113825

3812-
Type debugInferCertainType(AstNode n, TypePath path) {
3826+
Type debuginferTypeCertain(AstNode n, TypePath path) {
38133827
n = getRelevantLocatable() and
3814-
result = CertainTypeInference::inferCertainType(n, path)
3828+
result = inferTypeCertain(n, path)
38153829
}
38163830

38173831
Type debugInferCertainNonUniqueType(AstNode n, TypePath path) {

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

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8961,10 +8961,8 @@ inferType
89618961
| main.rs:826:16:826:16 | 3 | | {EXTERNAL LOCATION} | i32 |
89628962
| main.rs:826:16:826:20 | ... > ... | | {EXTERNAL LOCATION} | bool |
89638963
| main.rs:826:20:826:20 | 2 | | {EXTERNAL LOCATION} | i32 |
8964-
| main.rs:826:22:828:13 | { ... } | | main.rs:820:20:820:22 | Tr2 |
89658964
| main.rs:827:17:827:20 | self | | {EXTERNAL LOCATION} | & |
89668965
| main.rs:827:17:827:20 | self | TRef | main.rs:820:5:832:5 | Self [trait MyTrait2] |
8967-
| main.rs:827:17:827:25 | self.m1() | | main.rs:820:20:820:22 | Tr2 |
89688966
| main.rs:828:20:830:13 | { ... } | | main.rs:820:20:820:22 | Tr2 |
89698967
| main.rs:829:17:829:31 | ...::m1(...) | | main.rs:820:20:820:22 | Tr2 |
89708968
| main.rs:829:26:829:30 | * ... | | main.rs:820:5:832:5 | Self [trait MyTrait2] |
@@ -11482,13 +11480,9 @@ inferType
1148211480
| main.rs:2099:13:2103:13 | if value {...} else {...} | | {EXTERNAL LOCATION} | i64 |
1148311481
| main.rs:2099:16:2099:20 | value | | {EXTERNAL LOCATION} | bool |
1148411482
| main.rs:2099:22:2101:13 | { ... } | | {EXTERNAL LOCATION} | i32 |
11485-
| main.rs:2099:22:2101:13 | { ... } | | {EXTERNAL LOCATION} | i64 |
1148611483
| main.rs:2100:17:2100:17 | 1 | | {EXTERNAL LOCATION} | i32 |
11487-
| main.rs:2100:17:2100:17 | 1 | | {EXTERNAL LOCATION} | i64 |
1148811484
| main.rs:2101:20:2103:13 | { ... } | | {EXTERNAL LOCATION} | i32 |
11489-
| main.rs:2101:20:2103:13 | { ... } | | {EXTERNAL LOCATION} | i64 |
1149011485
| main.rs:2102:17:2102:17 | 0 | | {EXTERNAL LOCATION} | i32 |
11491-
| main.rs:2102:17:2102:17 | 0 | | {EXTERNAL LOCATION} | i64 |
1149211486
| main.rs:2113:19:2113:22 | SelfParam | | main.rs:2107:5:2107:19 | S |
1149311487
| main.rs:2113:19:2113:22 | SelfParam | T | main.rs:2109:10:2109:17 | T |
1149411488
| main.rs:2113:25:2113:29 | other | | main.rs:2107:5:2107:19 | S |
@@ -11543,13 +11537,9 @@ inferType
1154311537
| main.rs:2154:13:2158:13 | if value {...} else {...} | | {EXTERNAL LOCATION} | i64 |
1154411538
| main.rs:2154:16:2154:20 | value | | {EXTERNAL LOCATION} | bool |
1154511539
| main.rs:2154:22:2156:13 | { ... } | | {EXTERNAL LOCATION} | i32 |
11546-
| main.rs:2154:22:2156:13 | { ... } | | {EXTERNAL LOCATION} | i64 |
1154711540
| main.rs:2155:17:2155:17 | 1 | | {EXTERNAL LOCATION} | i32 |
11548-
| main.rs:2155:17:2155:17 | 1 | | {EXTERNAL LOCATION} | i64 |
1154911541
| main.rs:2156:20:2158:13 | { ... } | | {EXTERNAL LOCATION} | i32 |
11550-
| main.rs:2156:20:2158:13 | { ... } | | {EXTERNAL LOCATION} | i64 |
1155111542
| main.rs:2157:17:2157:17 | 0 | | {EXTERNAL LOCATION} | i32 |
11552-
| main.rs:2157:17:2157:17 | 0 | | {EXTERNAL LOCATION} | i64 |
1155311543
| main.rs:2164:21:2164:25 | value | | main.rs:2162:19:2162:19 | T |
1155411544
| main.rs:2164:31:2164:31 | x | | main.rs:2162:5:2165:5 | Self [trait MyFrom2] |
1155511545
| main.rs:2169:21:2169:25 | value | | {EXTERNAL LOCATION} | i64 |
@@ -11715,9 +11705,7 @@ inferType
1171511705
| main.rs:2265:21:2265:31 | [...] | TArray | {EXTERNAL LOCATION} | u8 |
1171611706
| main.rs:2265:22:2265:24 | 1u8 | | {EXTERNAL LOCATION} | u8 |
1171711707
| main.rs:2265:27:2265:27 | 2 | | {EXTERNAL LOCATION} | i32 |
11718-
| main.rs:2265:27:2265:27 | 2 | | {EXTERNAL LOCATION} | u8 |
1171911708
| main.rs:2265:30:2265:30 | 3 | | {EXTERNAL LOCATION} | i32 |
11720-
| main.rs:2265:30:2265:30 | 3 | | {EXTERNAL LOCATION} | u8 |
1172111709
| main.rs:2266:9:2266:25 | for ... in ... { ... } | | {EXTERNAL LOCATION} | () |
1172211710
| main.rs:2266:13:2266:13 | u | | {EXTERNAL LOCATION} | i32 |
1172311711
| main.rs:2266:13:2266:13 | u | | {EXTERNAL LOCATION} | u8 |
@@ -11743,11 +11731,8 @@ inferType
1174311731
| main.rs:2271:31:2271:39 | [...] | TArray | {EXTERNAL LOCATION} | i32 |
1174411732
| main.rs:2271:31:2271:39 | [...] | TArray | {EXTERNAL LOCATION} | u32 |
1174511733
| main.rs:2271:32:2271:32 | 1 | | {EXTERNAL LOCATION} | i32 |
11746-
| main.rs:2271:32:2271:32 | 1 | | {EXTERNAL LOCATION} | u32 |
1174711734
| main.rs:2271:35:2271:35 | 2 | | {EXTERNAL LOCATION} | i32 |
11748-
| main.rs:2271:35:2271:35 | 2 | | {EXTERNAL LOCATION} | u32 |
1174911735
| main.rs:2271:38:2271:38 | 3 | | {EXTERNAL LOCATION} | i32 |
11750-
| main.rs:2271:38:2271:38 | 3 | | {EXTERNAL LOCATION} | u32 |
1175111736
| main.rs:2272:9:2272:25 | for ... in ... { ... } | | {EXTERNAL LOCATION} | () |
1175211737
| main.rs:2272:13:2272:13 | u | | {EXTERNAL LOCATION} | u32 |
1175311738
| main.rs:2272:18:2272:22 | vals3 | | {EXTERNAL LOCATION} | [;] |
@@ -11888,7 +11873,6 @@ inferType
1188811873
| main.rs:2308:19:2308:25 | 0u8..10 | Idx | {EXTERNAL LOCATION} | i32 |
1188911874
| main.rs:2308:19:2308:25 | 0u8..10 | Idx | {EXTERNAL LOCATION} | u8 |
1189011875
| main.rs:2308:24:2308:25 | 10 | | {EXTERNAL LOCATION} | i32 |
11891-
| main.rs:2308:24:2308:25 | 10 | | {EXTERNAL LOCATION} | u8 |
1189211876
| main.rs:2308:28:2308:29 | { ... } | | {EXTERNAL LOCATION} | () |
1189311877
| main.rs:2309:13:2309:17 | range | | {EXTERNAL LOCATION} | Range |
1189411878
| main.rs:2309:13:2309:17 | range | Idx | {EXTERNAL LOCATION} | i32 |
@@ -12641,11 +12625,9 @@ inferType
1264112625
| main.rs:2583:12:2583:12 | b | | {EXTERNAL LOCATION} | bool |
1264212626
| main.rs:2583:14:2586:9 | { ... } | | {EXTERNAL LOCATION} | Box |
1264312627
| main.rs:2583:14:2586:9 | { ... } | A | {EXTERNAL LOCATION} | Global |
12644-
| main.rs:2583:14:2586:9 | { ... } | T | main.rs:2547:5:2549:5 | dyn MyTrait |
1264512628
| main.rs:2583:14:2586:9 | { ... } | T | main.rs:2551:5:2552:19 | S |
1264612629
| main.rs:2583:14:2586:9 | { ... } | T.T | main.rs:2551:5:2552:19 | S |
1264712630
| main.rs:2583:14:2586:9 | { ... } | T.T.T | {EXTERNAL LOCATION} | i32 |
12648-
| main.rs:2583:14:2586:9 | { ... } | T.dyn(T) | {EXTERNAL LOCATION} | i32 |
1264912631
| main.rs:2584:17:2584:17 | x | | main.rs:2551:5:2552:19 | S |
1265012632
| main.rs:2584:17:2584:17 | x | T | main.rs:2551:5:2552:19 | S |
1265112633
| main.rs:2584:17:2584:17 | x | T.T | {EXTERNAL LOCATION} | i32 |
@@ -12656,26 +12638,20 @@ inferType
1265612638
| main.rs:2584:21:2584:26 | x.m2() | T.T | {EXTERNAL LOCATION} | i32 |
1265712639
| main.rs:2585:13:2585:23 | ...::new(...) | | {EXTERNAL LOCATION} | Box |
1265812640
| main.rs:2585:13:2585:23 | ...::new(...) | A | {EXTERNAL LOCATION} | Global |
12659-
| main.rs:2585:13:2585:23 | ...::new(...) | T | main.rs:2547:5:2549:5 | dyn MyTrait |
1266012641
| main.rs:2585:13:2585:23 | ...::new(...) | T | main.rs:2551:5:2552:19 | S |
1266112642
| main.rs:2585:13:2585:23 | ...::new(...) | T.T | main.rs:2551:5:2552:19 | S |
1266212643
| main.rs:2585:13:2585:23 | ...::new(...) | T.T.T | {EXTERNAL LOCATION} | i32 |
12663-
| main.rs:2585:13:2585:23 | ...::new(...) | T.dyn(T) | {EXTERNAL LOCATION} | i32 |
1266412644
| main.rs:2585:22:2585:22 | x | | main.rs:2551:5:2552:19 | S |
1266512645
| main.rs:2585:22:2585:22 | x | T | main.rs:2551:5:2552:19 | S |
1266612646
| main.rs:2585:22:2585:22 | x | T.T | {EXTERNAL LOCATION} | i32 |
1266712647
| main.rs:2586:16:2588:9 | { ... } | | {EXTERNAL LOCATION} | Box |
1266812648
| main.rs:2586:16:2588:9 | { ... } | A | {EXTERNAL LOCATION} | Global |
12669-
| main.rs:2586:16:2588:9 | { ... } | T | main.rs:2547:5:2549:5 | dyn MyTrait |
1267012649
| main.rs:2586:16:2588:9 | { ... } | T | main.rs:2551:5:2552:19 | S |
1267112650
| main.rs:2586:16:2588:9 | { ... } | T.T | {EXTERNAL LOCATION} | i32 |
12672-
| main.rs:2586:16:2588:9 | { ... } | T.dyn(T) | {EXTERNAL LOCATION} | i32 |
1267312651
| main.rs:2587:13:2587:23 | ...::new(...) | | {EXTERNAL LOCATION} | Box |
1267412652
| main.rs:2587:13:2587:23 | ...::new(...) | A | {EXTERNAL LOCATION} | Global |
12675-
| main.rs:2587:13:2587:23 | ...::new(...) | T | main.rs:2547:5:2549:5 | dyn MyTrait |
1267612653
| main.rs:2587:13:2587:23 | ...::new(...) | T | main.rs:2551:5:2552:19 | S |
1267712654
| main.rs:2587:13:2587:23 | ...::new(...) | T.T | {EXTERNAL LOCATION} | i32 |
12678-
| main.rs:2587:13:2587:23 | ...::new(...) | T.dyn(T) | {EXTERNAL LOCATION} | i32 |
1267912655
| main.rs:2587:22:2587:22 | x | | main.rs:2551:5:2552:19 | S |
1268012656
| main.rs:2587:22:2587:22 | x | T | {EXTERNAL LOCATION} | i32 |
1268112657
| main.rs:2593:22:2597:5 | { ... } | | {EXTERNAL LOCATION} | () |

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ private predicate relevantNode(AstNode n) {
1212
}
1313

1414
query predicate inferCertainType(AstNode n, TypePath path, Type t) {
15-
t = TypeInference::CertainTypeInference::inferCertainType(n, path) and
15+
t = TypeInference::inferTypeCertain(n, path) and
1616
t != TUnknownType() and
1717
relevantNode(n)
1818
}
@@ -72,7 +72,7 @@ module TypeTest implements TestSig {
7272
(
7373
tag = "type"
7474
or
75-
t = TypeInference::CertainTypeInference::inferCertainType(n, path) and
75+
t = TypeInference::inferTypeCertain(n, path) and
7676
tag = "certainType"
7777
) and
7878
location = n.getLocation() and

0 commit comments

Comments
 (0)