Skip to content

Commit deb0c8a

Browse files
committed
wip2
1 parent 32956eb commit deb0c8a

File tree

3 files changed

+109
-7
lines changed

3 files changed

+109
-7
lines changed

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

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,100 @@ private Type resolveMethodCallExprType(MethodCallExpr mce, TypePath path) {
10081008
)
10091009
}
10101010

1011+
private module FieldExprMatchingInput implements MatchingInputSig {
1012+
abstract class Decl extends AstNode {
1013+
TypeParameter getTypeParameter(int i) { none() }
1014+
1015+
abstract TypeRepr getTypeRepr();
1016+
}
1017+
1018+
private class RecordFieldDecl extends Decl instanceof RecordField {
1019+
override TypeRepr getTypeRepr() { result = RecordField.super.getTypeRepr() }
1020+
}
1021+
1022+
private class TupleFieldDecl extends Decl instanceof TupleField {
1023+
override TypeRepr getTypeRepr() { result = TupleField.super.getTypeRepr() }
1024+
}
1025+
1026+
class Access extends FieldExpr {
1027+
Type getTypeArgument(int i, TypePath path) { none() }
1028+
1029+
predicate noExplicitTypeArguments() { any() }
1030+
}
1031+
1032+
predicate target(Access a, Decl target) {
1033+
exists(Type t, Type lookupType, string name |
1034+
t = resolveType(a.getExpr()) and
1035+
name = a.getNameRef().getText() and
1036+
if t = TRefType()
1037+
then
1038+
// for reference types, lookup the field in the type being referenced
1039+
lookupType = resolveType(a.getExpr(), "0")
1040+
else lookupType = t
1041+
|
1042+
target = lookupType.getRecordField(name)
1043+
or
1044+
target = lookupType.getTupleField(name.toInt())
1045+
)
1046+
}
1047+
1048+
class Pos = int;
1049+
1050+
Pos getReturnPos() { result = -2 }
1051+
1052+
private AstNode getExplicitArgument(Access a, Pos pos) { result = a.getExpr() and pos = -1 }
1053+
1054+
private predicate explicitArgumentType(Access a, Pos pos, TypePath path, Type t) {
1055+
t = resolveType(getExplicitArgument(a, pos), path)
1056+
}
1057+
1058+
predicate argumentType(Access a, Pos pos, TypePath path, Type t) {
1059+
explicitArgumentType(a, pos, path, t)
1060+
// or
1061+
// implicitThis(a, pos, path, t)
1062+
}
1063+
1064+
pragma[nomagic]
1065+
predicate argumentIsTargetTyped(Access a, Pos pos) { isTargetTyped(getExplicitArgument(a, pos)) }
1066+
1067+
pragma[nomagic]
1068+
predicate argumentIsNotTargetTyped(Access a, Pos pos) {
1069+
exists(AstNode arg |
1070+
arg = getExplicitArgument(a, pos) and
1071+
not isTargetTyped(arg)
1072+
)
1073+
// or
1074+
// implicitThis(a, pos, _, _)
1075+
}
1076+
1077+
predicate parameterType(Decl decl, Pos pos, TypePath path, Type t) {
1078+
pos = -1 and
1079+
exists(Struct s | s.getRecordField(_) = decl or s.getTupleField(_) = decl |
1080+
t = TStruct(s) and
1081+
path.isEmpty()
1082+
or
1083+
exists(int i |
1084+
t = TTypeParameter(s.getGenericParamList().getTypeParam(i)) and
1085+
path = typePath(i)
1086+
)
1087+
)
1088+
}
1089+
1090+
pragma[nomagic]
1091+
predicate declType(Decl decl, TypePath path, Type t) {
1092+
t = decl.getTypeRepr().(TypeRepr_).resolveTypeAt(path)
1093+
}
1094+
}
1095+
1096+
private module FieldExprMatching = Matching<FieldExprMatchingInput>;
1097+
1098+
private Type resolveFieldExprType(FieldExpr fe, TypePath path) {
1099+
result = resolveFieldExprType0(fe, path)
1100+
or
1101+
// result = resolveFunctionReturnType(call.getStaticTarget(), path)
1102+
result = FieldExprMatching::resolveAccess(fe, -2, path)
1103+
}
1104+
10111105
pragma[nomagic]
10121106
RecordField resolveRecordFieldExpr(FieldExpr fe) {
10131107
exists(Type t, string name |
@@ -1035,7 +1129,7 @@ TupleField resolveTupleFieldExpr(FieldExpr fe) {
10351129
}
10361130

10371131
pragma[nomagic]
1038-
private Type resolveFieldExprType(FieldExpr fe, TypePath path) {
1132+
private Type resolveFieldExprType0(FieldExpr fe, TypePath path) {
10391133
exists(RecordField f |
10401134
f = resolveRecordFieldExpr(fe) and
10411135
result = f.getTypeRepr().(TypeRepr_).resolveTypeAt(path) and

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,19 @@ mod m2 {
3838

3939
impl MyThing<S1> {
4040
fn m1(self) -> S1 {
41-
self.a // `self.a` missing type
41+
self.a
4242
}
4343
}
4444

4545
impl MyThing<S2> {
4646
fn m1(self) -> Self {
47-
Self { a: self.a } // `self.a` missing type
47+
Self { a: self.a }
4848
}
4949
}
5050

5151
impl<T> MyThing<T> {
5252
fn m2(self) -> T {
53-
self.a // `self.a` missing type
53+
self.a
5454
}
5555
}
5656

@@ -97,13 +97,13 @@ mod m3 {
9797

9898
impl MyTrait<S1> for MyThing<S1> {
9999
fn m1(self) -> S1 {
100-
self.a // `self.a` missing type
100+
self.a
101101
}
102102
}
103103

104104
impl MyTrait<Self> for MyThing<S2> {
105105
fn m1(self) -> Self {
106-
Self { a: self.a } // `self.a` missing type, `Self` missing type at path 0
106+
Self { a: self.a }
107107
}
108108
}
109109

@@ -150,7 +150,7 @@ mod m4 {
150150

151151
impl<T> MyTrait<T> for MyThing<T> {
152152
fn m1(self) -> T {
153-
self.a // `self.a` missing type
153+
self.a
154154
}
155155
}
156156

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,19 @@
1717
| main.rs:40:15:40:18 | SelfParam | 0 | main.rs:34:5:35:14 | struct S1 |
1818
| main.rs:41:13:41:16 | self | | main.rs:29:5:32:5 | struct MyThing |
1919
| main.rs:41:13:41:16 | self | 0 | main.rs:34:5:35:14 | struct S1 |
20+
| main.rs:41:13:41:18 | self.a | | main.rs:34:5:35:14 | struct S1 |
2021
| main.rs:46:15:46:18 | SelfParam | | main.rs:29:5:32:5 | struct MyThing |
2122
| main.rs:46:15:46:18 | SelfParam | 0 | main.rs:36:5:37:14 | struct S2 |
2223
| main.rs:47:13:47:30 | Self {...} | | main.rs:29:5:32:5 | struct MyThing |
24+
| main.rs:47:13:47:30 | Self {...} | 0 | main.rs:36:5:37:14 | struct S2 |
2325
| main.rs:47:23:47:26 | self | | main.rs:29:5:32:5 | struct MyThing |
2426
| main.rs:47:23:47:26 | self | 0 | main.rs:36:5:37:14 | struct S2 |
27+
| main.rs:47:23:47:28 | self.a | | main.rs:36:5:37:14 | struct S2 |
2528
| main.rs:52:15:52:18 | SelfParam | | main.rs:29:5:32:5 | struct MyThing |
2629
| main.rs:52:15:52:18 | SelfParam | 0 | main.rs:51:10:51:10 | T |
2730
| main.rs:53:13:53:16 | self | | main.rs:29:5:32:5 | struct MyThing |
2831
| main.rs:53:13:53:16 | self | 0 | main.rs:51:10:51:10 | T |
32+
| main.rs:53:13:53:18 | self.a | | main.rs:51:10:51:10 | T |
2933
| main.rs:58:13:58:13 | x | | main.rs:29:5:32:5 | struct MyThing |
3034
| main.rs:58:13:58:13 | x | 0 | main.rs:34:5:35:14 | struct S1 |
3135
| main.rs:58:17:58:33 | MyThing {...} | | main.rs:29:5:32:5 | struct MyThing |
@@ -64,11 +68,14 @@
6468
| main.rs:99:15:99:18 | SelfParam | 0 | main.rs:78:5:79:14 | struct S1 |
6569
| main.rs:100:13:100:16 | self | | main.rs:73:5:76:5 | struct MyThing |
6670
| main.rs:100:13:100:16 | self | 0 | main.rs:78:5:79:14 | struct S1 |
71+
| main.rs:100:13:100:18 | self.a | | main.rs:78:5:79:14 | struct S1 |
6772
| main.rs:105:15:105:18 | SelfParam | | main.rs:73:5:76:5 | struct MyThing |
6873
| main.rs:105:15:105:18 | SelfParam | 0 | main.rs:80:5:81:14 | struct S2 |
6974
| main.rs:106:13:106:30 | Self {...} | | main.rs:73:5:76:5 | struct MyThing |
75+
| main.rs:106:13:106:30 | Self {...} | 0 | main.rs:80:5:81:14 | struct S2 |
7076
| main.rs:106:23:106:26 | self | | main.rs:73:5:76:5 | struct MyThing |
7177
| main.rs:106:23:106:26 | self | 0 | main.rs:80:5:81:14 | struct S2 |
78+
| main.rs:106:23:106:28 | self.a | | main.rs:80:5:81:14 | struct S2 |
7279
| main.rs:111:13:111:13 | x | | main.rs:73:5:76:5 | struct MyThing |
7380
| main.rs:111:13:111:13 | x | 0 | main.rs:78:5:79:14 | struct S1 |
7481
| main.rs:111:17:111:33 | MyThing {...} | | main.rs:73:5:76:5 | struct MyThing |
@@ -107,6 +114,7 @@
107114
| main.rs:152:15:152:18 | SelfParam | 0 | main.rs:151:10:151:10 | T |
108115
| main.rs:153:13:153:16 | self | | main.rs:126:5:129:5 | struct MyThing |
109116
| main.rs:153:13:153:16 | self | 0 | main.rs:151:10:151:10 | T |
117+
| main.rs:153:13:153:18 | self.a | | main.rs:151:10:151:10 | T |
110118
| main.rs:158:13:158:13 | x | | main.rs:126:5:129:5 | struct MyThing |
111119
| main.rs:158:13:158:13 | x | 0 | main.rs:131:5:132:14 | struct S1 |
112120
| main.rs:158:17:158:33 | MyThing {...} | | main.rs:126:5:129:5 | struct MyThing |

0 commit comments

Comments
 (0)