Skip to content

Commit be2ec0f

Browse files
committed
wip2
1 parent 67deeb5 commit be2ec0f

File tree

4 files changed

+124
-30
lines changed

4 files changed

+124
-30
lines changed

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,21 @@ module Impl {
2828
class CallExpr extends Generated::CallExpr {
2929
override string toString() { result = this.getFunction().toAbbreviatedString() + "(...)" }
3030

31+
pragma[nomagic]
32+
private PathResolution::ItemNode getResolvedFunction() {
33+
result = PathResolution::resolvePath(this.getFunction().(PathExpr).getPath())
34+
}
35+
3136
pragma[nomagic]
3237
private PathResolution::ItemNode getResolvedFunction(int pos) {
33-
result = PathResolution::resolvePath(this.getFunction().(PathExpr).getPath()) and
38+
result = this.getResolvedFunction() and
3439
exists(this.getArgList().getArg(pos))
3540
}
3641

42+
Struct getStruct() { result = this.getResolvedFunction() }
43+
44+
Variant getVariant() { result = this.getResolvedFunction() }
45+
3746
/**
3847
* Gets the tuple field that matches the `pos`th argument of this call, if any.
3948
*

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

Lines changed: 100 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,9 @@ private module RecordFieldMatchingInput implements MatchingInputSig {
874874
t = TStruct(decl) and
875875
path.isEmpty()
876876
or
877+
t = TEnum(decl.(VariantDecl).getEnum()) and
878+
path.isEmpty()
879+
or
877880
exists(int i |
878881
t = decl.getTypeParameter(i) and
879882
path = typePath(i)
@@ -886,6 +889,13 @@ private module RecordFieldMatching = Matching<RecordFieldMatchingInput>;
886889
private Type resolveRecordExprType(RecordExpr re, TypePath path) {
887890
result = re.getPath().(Path_).resolveTypeAt(path)
888891
or
892+
exists(Enum e, Variant v |
893+
v = resolvePath(re.getPath()) and
894+
v = e.getVariantList().getAVariant() and
895+
result = TEnum(e) and
896+
path.isEmpty()
897+
)
898+
or
889899
// result = resolveFunctionReturnType(call.getStaticTarget(), path)
890900
result = RecordFieldMatching::resolveAccess(re, "(return)", path)
891901
}
@@ -898,10 +908,88 @@ private module FunctionMatchingInput implements MatchingInputSig {
898908

899909
Pos getReturnPos() { result = -2 }
900910

901-
class Decl extends Function {
902-
TypeParameter getTypeParameter(int i) {
911+
// class Decl extends Function {
912+
// TypeParameter getTypeParameter(int i) {
913+
// result.getTypeParam() = this.getGenericParamList().getTypeParam(i)
914+
// }
915+
// }
916+
abstract class Decl extends AstNode {
917+
abstract TypeParameter getTypeParameter(int i);
918+
919+
abstract Type getParameterType(int pos, TypePath path);
920+
921+
abstract Type getReturnType(TypePath path);
922+
}
923+
924+
private class StructDecl extends Decl, Struct {
925+
override TypeParameter getTypeParameter(int i) {
926+
result.getTypeParam() = this.getGenericParamList().getTypeParam(i)
927+
}
928+
929+
override Type getParameterType(int pos, TypePath path) {
930+
result = this.getTupleField(pos).getTypeRepr().(TypeRepr_).resolveTypeAt(path)
931+
}
932+
933+
override Type getReturnType(TypePath path) {
934+
result = TStruct(this) and
935+
path.isEmpty()
936+
or
937+
exists(int i |
938+
result = TTypeParameter(this.getGenericParamList().getTypeParam(i)) and
939+
path = typePath(i)
940+
)
941+
}
942+
}
943+
944+
private class VariantDecl extends Decl, Variant {
945+
Enum getEnum() { result.getVariantList().getAVariant() = this }
946+
947+
override TypeParameter getTypeParameter(int i) {
948+
result.getTypeParam() = this.getEnum().getGenericParamList().getTypeParam(i)
949+
}
950+
951+
override Type getParameterType(int pos, TypePath path) {
952+
result = this.getTupleField(pos).getTypeRepr().(TypeRepr_).resolveTypeAt(path)
953+
}
954+
955+
override Type getReturnType(TypePath path) {
956+
exists(Enum enum | enum = this.getEnum() |
957+
result = TEnum(enum) and
958+
path.isEmpty()
959+
or
960+
exists(int i |
961+
result = TTypeParameter(enum.getGenericParamList().getTypeParam(i)) and
962+
path = typePath(i)
963+
)
964+
)
965+
}
966+
}
967+
968+
private class FunctionDecl extends Decl, Function {
969+
override TypeParameter getTypeParameter(int i) {
903970
result.getTypeParam() = this.getGenericParamList().getTypeParam(i)
904971
}
972+
973+
override Type getParameterType(int pos, TypePath path) {
974+
exists(TypeRepr_ tp |
975+
paramTyped(this.getParamList().getParam(pos), _, tp)
976+
or
977+
selfParamTyped(this.getParamList().getSelfParam(), tp) and
978+
pos = -1
979+
|
980+
result = tp.resolveTypeAt(path)
981+
)
982+
or
983+
exists(SelfParam self |
984+
self = this.getParamList().getSelfParam() and
985+
pos = -1 and
986+
result = resolveTargetTyped(self, path)
987+
)
988+
}
989+
990+
override Type getReturnType(TypePath path) {
991+
result = this.getRetType().getTypeRepr().(TypeRepr_).resolveTypeAt(path)
992+
}
905993
}
906994

907995
class Access extends CallExprBase {
@@ -923,14 +1011,20 @@ private module FunctionMatchingInput implements MatchingInputSig {
9231011
predicate noExplicitTypeArguments() { not exists(this.getTypeArg(_)) }
9241012
}
9251013

926-
predicate target(Access a, Decl target) { target = a.getStaticTarget() }
1014+
predicate target(Access a, Decl target) {
1015+
target = a.getStaticTarget()
1016+
or
1017+
target = a.(CallExpr).getStruct()
1018+
or
1019+
target = a.(CallExpr).getVariant()
1020+
}
9271021

9281022
private AstNode getExplicitArgument(Access a, int pos) {
9291023
exists(int offset, Decl target |
9301024
result = a.getArgList().getArg(pos + offset) and
9311025
target(a, target)
9321026
|
933-
if target.getParamList().hasSelfParam() and not a instanceof MethodCallExpr
1027+
if target.(Function).getParamList().hasSelfParam() and not a instanceof MethodCallExpr
9341028
then offset = 1
9351029
else offset = 0
9361030
)
@@ -974,26 +1068,11 @@ private module FunctionMatchingInput implements MatchingInputSig {
9741068
}
9751069

9761070
predicate parameterType(Decl decl, int pos, TypePath path, Type t) {
977-
exists(TypeRepr_ tp |
978-
paramTyped(decl.getParamList().getParam(pos), _, tp)
979-
or
980-
selfParamTyped(decl.getParamList().getSelfParam(), tp) and
981-
pos = -1
982-
|
983-
t = tp.resolveTypeAt(path)
984-
)
985-
or
986-
exists(SelfParam self |
987-
self = decl.getParamList().getSelfParam() and
988-
pos = -1 and
989-
t = resolveTargetTyped(self, path)
990-
)
1071+
t = decl.getParameterType(pos, path)
9911072
}
9921073

9931074
pragma[nomagic]
994-
predicate declType(Decl decl, TypePath path, Type t) {
995-
t = decl.getRetType().getTypeRepr().(TypeRepr_).resolveTypeAt(path)
996-
}
1075+
predicate declType(Decl decl, TypePath path, Type t) { t = decl.getReturnType(path) }
9971076
}
9981077

9991078
private module FunctionMatching = Matching<FunctionMatchingInput>;

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,11 @@ mod m6 {
226226
}
227227

228228
pub fn f() {
229-
let x = MyEnum::C1(S1); // `MyEnum::C1(S1)` missing type at path 0
230-
let y = MyEnum::C2 { a: S2 }; // `MyEnum::C2 { a: S2 }` missing type at ""
229+
let x = MyEnum::C1(S1);
230+
let y = MyEnum::C2 { a: S2 };
231231

232-
println!("{:?}", x.m1()); // `x.m1` missing type
233-
println!("{:?}", y.m1()); // `y`, `y.m1` missing type
232+
println!("{:?}", x.m1()); // missing
233+
println!("{:?}", y.m1()); // missing
234234
}
235235
}
236236

@@ -274,14 +274,14 @@ mod m7 {
274274
let x = MyThing { a: S1 };
275275
let y = MyThing { a: S2 };
276276

277-
println!("{:?}", x.m1()); // `x.m1` missing type
278-
println!("{:?}", y.m1()); // `y.m1` missing type
277+
println!("{:?}", x.m1()); // missing
278+
println!("{:?}", y.m1()); // missing
279279

280280
let x = MyThing { a: S1 };
281281
let y = MyThing { a: S2 };
282282

283-
println!("{:?}", x.m2()); // `x.m1` missing type
284-
println!("{:?}", y.m2()); // `y.m1` missing type
283+
println!("{:?}", x.m2()); // missing
284+
println!("{:?}", y.m2()); // missing
285285
}
286286
}
287287

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,19 @@
163163
| main.rs:221:19:221:22 | self | | main.rs:208:5:212:5 | enum MyEnum |
164164
| main.rs:221:19:221:22 | self | 0 | main.rs:219:10:219:10 | T |
165165
| main.rs:229:13:229:13 | x | | main.rs:208:5:212:5 | enum MyEnum |
166+
| main.rs:229:13:229:13 | x | 0 | main.rs:214:5:215:14 | struct S1 |
166167
| main.rs:229:17:229:26 | ...::C1 | | main.rs:208:5:212:5 | enum MyEnum |
167168
| main.rs:229:17:229:30 | ...::C1(...) | | main.rs:208:5:212:5 | enum MyEnum |
169+
| main.rs:229:17:229:30 | ...::C1(...) | 0 | main.rs:214:5:215:14 | struct S1 |
168170
| main.rs:229:28:229:29 | S1 | | main.rs:214:5:215:14 | struct S1 |
171+
| main.rs:230:13:230:13 | y | | main.rs:208:5:212:5 | enum MyEnum |
169172
| main.rs:230:13:230:13 | y | 0 | main.rs:216:5:217:14 | struct S2 |
173+
| main.rs:230:17:230:36 | ...::C2 {...} | | main.rs:208:5:212:5 | enum MyEnum |
170174
| main.rs:230:17:230:36 | ...::C2 {...} | 0 | main.rs:216:5:217:14 | struct S2 |
171175
| main.rs:230:33:230:34 | S2 | | main.rs:216:5:217:14 | struct S2 |
172176
| main.rs:232:26:232:26 | x | | main.rs:208:5:212:5 | enum MyEnum |
177+
| main.rs:232:26:232:26 | x | 0 | main.rs:214:5:215:14 | struct S1 |
178+
| main.rs:233:26:233:26 | y | | main.rs:208:5:212:5 | enum MyEnum |
173179
| main.rs:233:26:233:26 | y | 0 | main.rs:216:5:217:14 | struct S2 |
174180
| main.rs:249:15:249:18 | SelfParam | | main.rs:248:5:250:5 | trait MyTrait1 |
175181
| main.rs:249:15:249:18 | SelfParam | 0 | main.rs:248:20:248:20 | A |

0 commit comments

Comments
 (0)