Skip to content

Commit cdf5462

Browse files
committed
wip
1 parent 7f8cede commit cdf5462

File tree

1 file changed

+27
-15
lines changed

1 file changed

+27
-15
lines changed

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

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3255,19 +3255,28 @@ private predicate inferOperationType =
32553255
ContextTyping::CheckContextTyping<inferOperationType0/3>::check/2;
32563256

32573257
pragma[nomagic]
3258-
private Type getFieldExprLookupType(FieldExpr fe, string name, boolean isDereferenced) {
3258+
private Type getFieldExprLookupType(FieldExpr fe, string name, DerefChain derefChain) {
32593259
exists(TypePath path |
32603260
result = inferType(fe.getContainer(), path) and
32613261
name = fe.getIdentifier().getText() and
3262-
isComplexRootStripped(path, result) and
3263-
if path.isEmpty() then isDereferenced = false else isDereferenced = true
3262+
isComplexRootStripped(path, result)
3263+
|
3264+
// TODO: Support full derefence chains as for method calls
3265+
path.isEmpty() and
3266+
derefChain = DerefChain::nil()
3267+
or
3268+
exists(DerefImplItemNode impl, TypeParamTypeParameter tp |
3269+
tp.getTypeParam() = impl.resolveSelfTy().getTypeParam(0) and
3270+
path.getHead() = tp and
3271+
derefChain = DerefChain::singleton(impl)
3272+
)
32643273
)
32653274
}
32663275

32673276
pragma[nomagic]
3268-
private Type getTupleFieldExprLookupType(FieldExpr fe, int pos, boolean isDereferenced) {
3277+
private Type getTupleFieldExprLookupType(FieldExpr fe, int pos, DerefChain derefChain) {
32693278
exists(string name |
3270-
result = getFieldExprLookupType(fe, name, isDereferenced) and
3279+
result = getFieldExprLookupType(fe, name, derefChain) and
32713280
pos = name.toInt()
32723281
)
32733282
}
@@ -3927,12 +3936,15 @@ private module Cached {
39273936
predicate implicitDeref(AstNode n) {
39283937
any(MethodResolution::MethodCall mc).receiverHasImplicitDeref(n)
39293938
or
3930-
n =
3931-
any(FieldExpr fe |
3932-
exists(resolveStructFieldExpr(fe, true))
3933-
or
3934-
exists(resolveTupleFieldExpr(fe, true))
3935-
).getContainer()
3939+
exists(DerefChain derefChain |
3940+
n =
3941+
any(FieldExpr fe |
3942+
exists(resolveStructFieldExpr(fe, derefChain))
3943+
or
3944+
exists(resolveTupleFieldExpr(fe, derefChain))
3945+
).getContainer() and
3946+
not derefChain.isEmpty()
3947+
)
39363948
}
39373949

39383950
/** Holds if `n` is implicitly borrowed. */
@@ -3968,9 +3980,9 @@ private module Cached {
39683980
* Gets the struct field that the field expression `fe` resolves to, if any.
39693981
*/
39703982
cached
3971-
StructField resolveStructFieldExpr(FieldExpr fe, boolean isDereferenced) {
3983+
StructField resolveStructFieldExpr(FieldExpr fe, DerefChain derefChain) {
39723984
exists(string name, Type ty |
3973-
ty = getFieldExprLookupType(fe, pragma[only_bind_into](name), isDereferenced)
3985+
ty = getFieldExprLookupType(fe, pragma[only_bind_into](name), derefChain)
39743986
|
39753987
result = ty.(StructType).getStruct().getStructField(pragma[only_bind_into](name)) or
39763988
result = ty.(UnionType).getUnion().getStructField(pragma[only_bind_into](name))
@@ -3981,10 +3993,10 @@ private module Cached {
39813993
* Gets the tuple field that the field expression `fe` resolves to, if any.
39823994
*/
39833995
cached
3984-
TupleField resolveTupleFieldExpr(FieldExpr fe, boolean isDereferenced) {
3996+
TupleField resolveTupleFieldExpr(FieldExpr fe, DerefChain derefChain) {
39853997
exists(int i |
39863998
result =
3987-
getTupleFieldExprLookupType(fe, pragma[only_bind_into](i), isDereferenced)
3999+
getTupleFieldExprLookupType(fe, pragma[only_bind_into](i), derefChain)
39884000
.(StructType)
39894001
.getStruct()
39904002
.getTupleField(pragma[only_bind_into](i))

0 commit comments

Comments
 (0)