Skip to content

Commit 8c892eb

Browse files
committed
wip
1 parent 2903a7f commit 8c892eb

2 files changed

Lines changed: 73 additions & 30 deletions

File tree

‎rust/ql/lib/codeql/rust/internal/typeinference/FunctionOverloading.qll‎

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,9 @@ predicate traitTypeParameterOccurrence(
166166
}
167167

168168
pragma[nomagic]
169-
private predicate functionResolutionDependsOnArgumentCand(
170-
ImplItemNode impl, Function f, string functionName, TypeParameter traitTp, FunctionPosition pos,
171-
TypePath path
169+
predicate functionResolutionDependsOnArgumentCand(
170+
ImplItemNode impl, Function f, string functionName, TypeParamTypeParameter traitTp,
171+
FunctionPosition pos, TypePath path
172172
) {
173173
/*
174174
* As seen in the example below, when an implementation has a sibling for a
@@ -199,12 +199,14 @@ private predicate functionResolutionDependsOnArgumentCand(
199199
)
200200
}
201201

202-
private predicate functionResolutionDependsOnPositionalArgumentCand(
203-
ImplItemNode impl, Function f, string functionName, TypeParameter traitTp
202+
pragma[nomagic]
203+
predicate functionResolutionDependsOnPositionalArgumentCand(
204+
ImplItemNode impl, Function f, string functionName, TypeParamTypeParameter traitTp, int pos,
205+
TypePath path
204206
) {
205-
exists(FunctionPosition pos |
206-
functionResolutionDependsOnArgumentCand(impl, f, functionName, traitTp, pos, _) and
207-
pos.isPosition()
207+
exists(FunctionPosition pos0 |
208+
functionResolutionDependsOnArgumentCand(impl, f, functionName, traitTp, pos0, path) and
209+
pos = pos0.asPosition()
208210
)
209211
}
210212

@@ -223,7 +225,7 @@ private Type getAssocFunctionNonTypeParameterTypeAt(
223225
*/
224226
pragma[nomagic]
225227
private predicate hasEquivalentPositionalSibling(
226-
ImplItemNode impl, ImplItemNode sibling, Function f, TypeParameter traitTp
228+
ImplItemNode impl, ImplItemNode sibling, Function f, TypeParamTypeParameter traitTp
227229
) {
228230
exists(string functionName, FunctionPosition pos, TypePath path |
229231
functionResolutionDependsOnArgumentCand(impl, f, functionName, traitTp, pos, path) and
@@ -255,7 +257,7 @@ private predicate hasEquivalentPositionalSibling(
255257
*
256258
* `traitTp` is a type parameter of the trait being implemented by `impl`, and
257259
* we need to check that the type of `f` corresponding to `traitTp` is satisfied
258-
* at any one of the positions `pos` in which that type occurs in `f`.
260+
* at any one of the positions `pos` in which that type occurs at `path` in `f`.
259261
*
260262
* Type parameters that only occur in return positions are only included when
261263
* all other type parameters that occur in a positional position are insufficient
@@ -283,19 +285,20 @@ private predicate hasEquivalentPositionalSibling(
283285
*/
284286
pragma[nomagic]
285287
predicate functionResolutionDependsOnArgument(
286-
ImplItemNode impl, Function f, TypeParameter traitTp, FunctionPosition pos
288+
ImplItemNode impl, Function f, TypeParamTypeParameter traitTp, FunctionPosition pos, TypePath path
287289
) {
288290
exists(string functionName |
289-
functionResolutionDependsOnArgumentCand(impl, f, functionName, traitTp, pos, _)
291+
functionResolutionDependsOnArgumentCand(impl, f, functionName, traitTp, pos, path)
290292
|
291-
if functionResolutionDependsOnPositionalArgumentCand(impl, f, functionName, traitTp)
293+
if functionResolutionDependsOnPositionalArgumentCand(impl, f, functionName, traitTp, _, _)
292294
then any()
293295
else
294296
// `traitTp` only occurs in return position; check that it is indeed needed for disambiguation
295297
exists(ImplItemNode sibling |
296298
implSiblings(_, impl, sibling) and
297-
forall(TypeParameter otherTraitTp |
298-
functionResolutionDependsOnPositionalArgumentCand(impl, f, functionName, otherTraitTp)
299+
forall(TypeParamTypeParameter otherTraitTp |
300+
functionResolutionDependsOnPositionalArgumentCand(impl, f, functionName, otherTraitTp, _,
301+
_)
299302
|
300303
hasEquivalentPositionalSibling(impl, sibling, f, otherTraitTp)
301304
)

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

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,10 +1096,10 @@ private module AssocFunctionResolution {
10961096
}
10971097

10981098
pragma[nomagic]
1099-
predicate resolutionDependsOnReturnType() {
1099+
predicate resolutionDependsOnReturnType(TypePath path) {
11001100
exists(AssocFunctionCallCand afcc |
11011101
afcc = MkAssocFunctionCallCand(this, _, _, _) and
1102-
afcc.resolutionDependsOnReturnType()
1102+
afcc.resolutionDependsOnReturnType(path)
11031103
)
11041104
}
11051105

@@ -1578,23 +1578,65 @@ private module AssocFunctionResolution {
15781578
pragma[nomagic]
15791579
AssocFunctionDeclaration resolveCallTarget(ImplOrTraitItemNode i) {
15801580
result = this.resolveCallTargetCand(i) and
1581-
not FunctionOverloading::functionResolutionDependsOnArgument(i, result, _, _)
1581+
not FunctionOverloading::functionResolutionDependsOnArgument(i, result, _, _, _)
15821582
or
15831583
OverloadedCallArgsAreInstantiationsOf::argsAreInstantiationsOf(this, i, result)
15841584
}
15851585

15861586
pragma[nomagic]
1587-
predicate resolutionDependsOnReturnType() {
1588-
exists(
1589-
ImplOrTraitItemNode i, AssocFunctionDeclaration target, TypeParameter tp,
1590-
FunctionPosition pos
1591-
|
1587+
private predicate hasUnknownTypeAtPos(int pos, TypePath path) {
1588+
exists(FunctionPosition pos0 |
1589+
inferType(afc_.getNodeAt(pos0), path) = TUnknownType() and
1590+
pos = pos0.asPosition()
1591+
)
1592+
}
1593+
1594+
pragma[nomagic]
1595+
private predicate resolutionDependsOnReturnTypeCand(
1596+
ImplOrTraitItemNode i, AssocFunctionDeclaration target, TypeParameter traitTp, TypePath path
1597+
) {
1598+
exists(FunctionPosition pos |
15921599
target = this.resolveCallTargetCand(i) and
1593-
FunctionOverloading::functionResolutionDependsOnArgument(i, target, tp, pos) and
1600+
FunctionOverloading::functionResolutionDependsOnArgument(i, target, traitTp, pos, path) and
15941601
pos.isReturn()
15951602
)
15961603
}
15971604

1605+
pragma[nomagic]
1606+
private predicate resolutionDependsOnPositionalAndReturnTypeCand(
1607+
ImplOrTraitItemNode i, AssocFunctionDeclaration target, TypePath path, int pos0,
1608+
TypePath prefix
1609+
) {
1610+
exists(TypeParameter traitTp, TypePath path0 |
1611+
this.resolutionDependsOnReturnTypeCand(i, target, traitTp, path) and
1612+
FunctionOverloading::functionResolutionDependsOnPositionalArgumentCand(i, target, _,
1613+
traitTp, pos0, path0) and
1614+
prefix = path0.getAPrefix()
1615+
)
1616+
}
1617+
1618+
/**
1619+
* Holds if resolving this call requires contextual information about the
1620+
* return type at `path`.
1621+
*/
1622+
pragma[nomagic]
1623+
predicate resolutionDependsOnReturnType(TypePath path) {
1624+
exists(ImplOrTraitItemNode i, AssocFunctionDeclaration target |
1625+
exists(TypeParameter traitTp |
1626+
this.resolutionDependsOnReturnTypeCand(i, target, traitTp, path) and
1627+
not FunctionOverloading::functionResolutionDependsOnPositionalArgumentCand(i, target, _,
1628+
traitTp, _, _)
1629+
)
1630+
or
1631+
// when `traitTp` is also mentioned in a parameter, require that typing of the
1632+
// corresponding argument also needs contextual typing
1633+
exists(int pos0, TypePath prefix |
1634+
this.resolutionDependsOnPositionalAndReturnTypeCand(i, target, path, pos0, prefix) and
1635+
this.hasUnknownTypeAtPos(pos0, prefix)
1636+
)
1637+
)
1638+
}
1639+
15981640
string toString() {
15991641
result = afc_ + " at " + selfPos_ + " [" + derefChain.toString() + "; " + borrow + "]"
16001642
}
@@ -1819,7 +1861,7 @@ private module AssocFunctionResolution {
18191861
ArgsAreInstantiationsOfInputSig
18201862
{
18211863
predicate toCheck(ImplOrTraitItemNode i, Function f, TypeParameter traitTp, FunctionPosition pos) {
1822-
FunctionOverloading::functionResolutionDependsOnArgument(i, f, traitTp, pos)
1864+
FunctionOverloading::functionResolutionDependsOnArgument(i, f, traitTp, pos, _)
18231865
}
18241866

18251867
class Call extends AssocFunctionCallCand {
@@ -3043,12 +3085,10 @@ private module Input3 implements InputSig3 {
30433085
private Type inferUnknownType(AstNode n, TypePath path) {
30443086
result = TUnknownType() and
30453087
(
3088+
n.(AssocFunctionResolution::AssocFunctionCall).resolutionDependsOnReturnType(path)
3089+
or
30463090
path.isEmpty() and
3047-
(
3048-
n.(AssocFunctionResolution::AssocFunctionCall).resolutionDependsOnReturnType()
3049-
or
3050-
isPanicMacroCall(n)
3051-
)
3091+
isPanicMacroCall(n)
30523092
or
30533093
n.(ArrayListExpr).getNumberOfExprs() = 0 and
30543094
path = TypePath::singleton(getArrayTypeParameter())

0 commit comments

Comments
 (0)