Skip to content

Commit 37e2526

Browse files
committed
wip
1 parent bb834a9 commit 37e2526

File tree

1 file changed

+29
-205
lines changed

1 file changed

+29
-205
lines changed

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

Lines changed: 29 additions & 205 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,7 +1331,7 @@ private class BorrowKind extends TBorrowKind {
13311331
}
13321332

13331333
/**
1334-
* Provides logic for resolving calls to methods.
1334+
* Provides logic for resolving calls to associated functions.
13351335
*
13361336
* When resolving a method call, a list of [candidate receiver types][1] is constructed
13371337
*
@@ -1365,67 +1365,30 @@ private class BorrowKind extends TBorrowKind {
13651365
*
13661366
* [1]: https://doc.rust-lang.org/reference/expressions/method-call-expr.html#r-expr.method.candidate-receivers
13671367
*/
1368-
private module MethodResolution {
1369-
pragma[nomagic]
1370-
private predicate functionResolutionDependsOnArgument(
1371-
ImplItemNode impl, Function f, TypeParameter tp, FunctionPosition pos
1372-
) {
1373-
FunctionOverloading::functionResolutionDependsOnArgument(impl, f, tp, pos)
1374-
// or
1375-
// // For inherent implementations of generic types, we also need to check the type being
1376-
// // implemented. We arbitrarily choose the first type parameter of the type being implemented
1377-
// // to represent this case.
1378-
// f = impl.getAnAssocItem() and
1379-
// not impl.(Impl).hasTrait() and
1380-
// tp = TTypeParamTypeParameter(impl.resolveSelfTy().getTypeParam(0)) and
1381-
// pos.isSelf()
1382-
}
1383-
1368+
private module AssocFunctionResolution {
1369+
/**
1370+
* Holds if the non-method trait function `f` mentions the implicit `Self` type
1371+
* parameter at `pos`.
1372+
*/
13841373
pragma[nomagic]
1385-
private predicate traitFunctionResolutionDependsOnArgument0(
1386-
// todo: copied
1387-
TraitItemNode trait, NonMethodFunction traitFunction, FunctionPosition pos, ImplItemNode impl,
1388-
NonMethodFunction implFunction, TypePath path, TypeParameter traitTp
1374+
private predicate traitSelfTypeParameterOccurrence(
1375+
TraitItemNode trait, NonMethodFunction f, FunctionPosition pos
13891376
) {
1390-
implFunction = impl.getAnAssocItem() and
1391-
implFunction.implements(traitFunction) and
1392-
FunctionOverloading::traitTypeParameterOccurrence(trait, traitFunction, _, pos, path, traitTp) and
1393-
(
1394-
traitTp = TSelfTypeParameter(trait)
1395-
or
1396-
functionResolutionDependsOnArgument(impl, implFunction, traitTp, pos)
1397-
)
1377+
FunctionOverloading::traitTypeParameterOccurrence(trait, f, _, pos, _, TSelfTypeParameter(trait))
13981378
}
13991379

14001380
/**
1401-
* Holds if resolving the function `implFunction` in `impl` requires inspecting
1402-
* the type of applied _arguments_ or possibly knowing the return type.
1403-
*
1404-
* `traitTp` is a type parameter of the trait being implemented by `impl`, and
1405-
* we need to check that the type of `f` corresponding to `traitTp` is satisfied
1406-
* at any one of the positions `pos` in which that type occurs in `f` (at `path`).
1407-
*
1408-
* As for method resolution, we always check the type being implemented (corresponding
1409-
* to `traitTp` being the special `Self` type parameter).
1381+
* Holds if the non-method function `f` implements a trait function that mentions
1382+
* the implicit `Self` type parameter at `pos`.
14101383
*/
14111384
pragma[nomagic]
1412-
private predicate traitFunctionResolutionDependsOnArgument(
1413-
TraitItemNode trait, NonMethodFunction traitFunction, FunctionPosition pos, ImplItemNode impl,
1414-
NonMethodFunction implFunction, TypePath path, TypeParameter traitTp
1385+
private predicate traitImplSelfTypeParameterOccurrence(
1386+
ImplItemNode impl, NonMethodFunction f, FunctionPosition pos
14151387
) {
1416-
traitFunctionResolutionDependsOnArgument0(trait, traitFunction, pos, impl, implFunction, path,
1417-
traitTp) and
1418-
// Exclude functions where we cannot resolve all relevant type mentions; this allows
1419-
// for blanket implementations to be applied in those cases
1420-
forall(TypeParameter traitTp0 |
1421-
traitFunctionResolutionDependsOnArgument0(trait, traitFunction, _, impl, implFunction, _,
1422-
traitTp0)
1423-
|
1424-
exists(FunctionPosition pos0, TypePath path0 |
1425-
traitFunctionResolutionDependsOnArgument0(trait, traitFunction, pos0, impl, implFunction,
1426-
path0, traitTp0) and
1427-
exists(getAssocFunctionTypeAt(implFunction, impl, pos0, path0))
1428-
)
1388+
exists(NonMethodFunction traitFunction |
1389+
f = impl.getAnAssocItem() and
1390+
f.implements(traitFunction) and
1391+
traitSelfTypeParameterOccurrence(_, traitFunction, pos)
14291392
)
14301393
}
14311394

@@ -1454,48 +1417,10 @@ private module MethodResolution {
14541417
(
14551418
selfPos.isSelfOrTypeQualifier()
14561419
or
1457-
exists(TraitItemNode trait |
1458-
traitFunctionResolutionDependsOnArgument0(_, f, selfPos, _, _, _, TSelfTypeParameter(trait))
1459-
or
1460-
traitFunctionResolutionDependsOnArgument0(_, _, selfPos, _, f, _, TSelfTypeParameter(trait))
1461-
)
1462-
) and
1463-
// Exclude functions where we cannot resolve all relevant type mentions; this allows
1464-
// for blanket implementations to be applied in those cases
1465-
forall(TraitItemNode trait, NonMethodFunction traitFunction, TypeParameter traitTp0 |
1466-
traitFunctionResolutionDependsOnArgument0(trait, traitFunction, _, i, f, _, traitTp0)
1467-
|
1468-
exists(FunctionPosition pos0, TypePath path0 |
1469-
traitFunctionResolutionDependsOnArgument0(trait, traitFunction, pos0, i, f, path0, traitTp0) and
1470-
exists(getAssocFunctionTypeAt(f, i, pos0, path0))
1471-
)
1472-
)
1473-
}
1474-
1475-
pragma[nomagic]
1476-
private predicate testassocFunctionInfo(
1477-
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition posAdj,
1478-
ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, Type strippedType
1479-
) {
1480-
assocFunctionInfo(f, name, arity, i, selfPos, selfType) and
1481-
strippedType = selfType.getTypeAt(strippedTypePath) and
1482-
(
1483-
isComplexRootStripped(strippedTypePath, strippedType)
1484-
or
1485-
selfPos.isTypeQualifier() and strippedTypePath.isEmpty()
1486-
) and
1487-
posAdj = selfPos.getFunctionCallAdjusted(f) and
1488-
(
1489-
selfPos.isSelfOrTypeQualifier()
1420+
traitSelfTypeParameterOccurrence(i, f, selfPos)
14901421
or
1491-
exists(TraitItemNode trait |
1492-
traitFunctionResolutionDependsOnArgument0(_, f, selfPos, _, _, _, TSelfTypeParameter(trait))
1493-
or
1494-
traitFunctionResolutionDependsOnArgument0(_, _, selfPos, _, f, _, TSelfTypeParameter(trait))
1495-
)
1496-
) and
1497-
not assocFunctionInfo(f, name, arity, selfPos, posAdj, i, selfType, strippedTypePath,
1498-
strippedType)
1422+
traitImplSelfTypeParameterOccurrence(i, f, selfPos)
1423+
)
14991424
}
15001425

15011426
pragma[nomagic]
@@ -1544,9 +1469,7 @@ private module MethodResolution {
15441469
(
15451470
selfPos.isSelfOrTypeQualifier()
15461471
or
1547-
traitFunctionResolutionDependsOnArgument0(_, f, selfPos, _, _, _, TSelfTypeParameter(trait))
1548-
or
1549-
traitFunctionResolutionDependsOnArgument0(_, _, selfPos, _, f, _, TSelfTypeParameter(trait))
1472+
traitImplSelfTypeParameterOccurrence(impl, f, selfPos)
15501473
)
15511474
}
15521475

@@ -1852,24 +1775,6 @@ private module MethodResolution {
18521775
)
18531776
}
18541777

1855-
private predicate foo2(
1856-
FunctionPosition selfPos, DerefChain derefChain, TypePath strippedTypePath, Type strippedType
1857-
) {
1858-
//ImplOrTraitItemNode i
1859-
this = Debug::getRelevantLocatable() and
1860-
derefChain.isEmpty() and
1861-
strippedType =
1862-
this.getComplexStrippedType(selfPos, derefChain, TNoBorrowKind(), strippedTypePath) and
1863-
this.hasNoCompatibleTargetCheck(selfPos, derefChain, TNoBorrowKind(), strippedTypePath,
1864-
getNthLookupType(strippedType, _))
1865-
// exists(Type t | t = getNthLookupType(strippedType, n) |
1866-
// this.hasNoCompatibleNonBlanketLikeTargetCheck(selfPos, derefChain, TSomeBorrowKind(false),
1867-
// strippedTypePath, t)
1868-
// ) and
1869-
// methodCallNonBlanketCandidate(this, _, selfPos, _, i, _, strippedTypePath, strippedType) //and
1870-
// not this.hasIncompatibleTarget(i, selfPos, derefChain, TSomeBorrowKind(false), strippedType)
1871-
}
1872-
18731778
/**
18741779
* Holds if the candidate receiver type represented by `derefChain` does not
18751780
* have a matching method target.
@@ -1882,16 +1787,6 @@ private module MethodResolution {
18821787
)
18831788
}
18841789

1885-
private predicate testhasNoCompatibleTargetNoBorrow(
1886-
FunctionPosition selfPos, DerefChain derefChain
1887-
) {
1888-
exists(Type strippedType |
1889-
this.hasNoCompatibleTargetNoBorrowToIndex(selfPos, derefChain, _, strippedType,
1890-
getLastLookupTypeIndex(strippedType))
1891-
) and
1892-
this = Debug::getRelevantLocatable()
1893-
}
1894-
18951790
// forex using recursion
18961791
pragma[nomagic]
18971792
private predicate hasNoCompatibleNonBlanketTargetNoBorrowToIndex(
@@ -1918,29 +1813,6 @@ private module MethodResolution {
19181813
)
19191814
}
19201815

1921-
private predicate sdf(
1922-
FunctionPosition selfPos, DerefChain derefChain, TypePath strippedTypePath, Type strippedType,
1923-
int n, ImplOrTraitItemNode i
1924-
) {
1925-
(
1926-
this.supportsAutoDerefAndBorrow() and
1927-
selfPos.isSelf()
1928-
or
1929-
// needed for the `hasNoCompatibleTarget` check in
1930-
// `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate`
1931-
derefChain.isEmpty()
1932-
) and
1933-
strippedType =
1934-
this.getComplexStrippedType(selfPos, derefChain, TNoBorrowKind(), strippedTypePath) and
1935-
this = Debug::getRelevantLocatable() and
1936-
exists(Type t | t = getNthLookupType(strippedType, n) |
1937-
// this.hasNoCompatibleNonBlanketTargetCheck(selfPos, derefChain, TNoBorrowKind(),
1938-
// strippedTypePath, t)
1939-
methodCallNonBlanketCandidate(this, _, selfPos, _, i, _, strippedTypePath, strippedType) and
1940-
not this.hasIncompatibleTarget(i, selfPos, derefChain, TNoBorrowKind(), strippedType)
1941-
)
1942-
}
1943-
19441816
/**
19451817
* Holds if the candidate receiver type represented by `derefChain` does not have
19461818
* a matching non-blanket method target.
@@ -1974,22 +1846,6 @@ private module MethodResolution {
19741846
)
19751847
}
19761848

1977-
private predicate foo(
1978-
FunctionPosition selfPos, DerefChain derefChain, TypePath strippedTypePath, Type strippedType
1979-
) {
1980-
//ImplOrTraitItemNode i
1981-
this = Debug::getRelevantLocatable() and
1982-
this.hasNoCompatibleTargetNoBorrow(selfPos, derefChain) and
1983-
strippedType =
1984-
this.getComplexStrippedType(selfPos, derefChain, TSomeBorrowKind(false), strippedTypePath) //and
1985-
// exists(Type t | t = getNthLookupType(strippedType, n) |
1986-
// this.hasNoCompatibleNonBlanketLikeTargetCheck(selfPos, derefChain, TSomeBorrowKind(false),
1987-
// strippedTypePath, t)
1988-
// ) and
1989-
// methodCallNonBlanketCandidate(this, _, selfPos, _, i, _, strippedTypePath, strippedType) //and
1990-
// not this.hasIncompatibleTarget(i, selfPos, derefChain, TSomeBorrowKind(false), strippedType)
1991-
}
1992-
19931849
/**
19941850
* Holds if the candidate receiver type represented by `derefChain`, followed
19951851
* by a shared borrow, does not have a matching method target.
@@ -2425,7 +2281,7 @@ private module MethodResolution {
24252281
pragma[nomagic]
24262282
Function resolveCallTarget(ImplOrTraitItemNode i) {
24272283
result = this.resolveCallTargetCand(i) and
2428-
not functionResolutionDependsOnArgument(i, result, _, _)
2284+
not FunctionOverloading::functionResolutionDependsOnArgument(i, result, _, _)
24292285
or
24302286
MethodArgsAreInstantiationsOf::argsAreInstantiationsOf(mc_, i, result)
24312287
}
@@ -2526,28 +2382,6 @@ private module MethodResolution {
25262382
blanketPath.getHead() = borrow.getRefType().getPositionalTypeParameter(0)
25272383
)
25282384
}
2529-
2530-
pragma[nomagic]
2531-
predicate testhasBlanketCandidate(
2532-
MethodCallCand mcc, ImplItemNode impl, TypePath blanketPath, TypeParam blanketTypeParam
2533-
) {
2534-
exists(MethodCall mc, FunctionPosition pos, BorrowKind borrow |
2535-
mcc = MkMethodCallCand(mc, _, pos, _, borrow) and
2536-
blanketPath.isEmpty() and
2537-
mc = Debug::getRelevantLocatable() and
2538-
methodCallBlanketLikeCandidate(mc, _, _, pos, impl, _, blanketPath, blanketTypeParam) and
2539-
impl.isBlanketImplementation() and
2540-
// Only apply blanket implementations when no other implementations are possible;
2541-
// this is to account for codebases that use the (unstable) specialization feature
2542-
// (https://rust-lang.github.io/rfcs/1210-impl-specialization.html), as well as
2543-
// cases where our blanket implementation filtering is not precise enough.
2544-
mcc.hasNoCompatibleNonBlanketTarget()
2545-
|
2546-
borrow.isNoBorrow()
2547-
or
2548-
blanketPath.getHead() = borrow.getRefType().getPositionalTypeParameter(0)
2549-
)
2550-
}
25512385
}
25522386

25532387
private module ReceiverSatisfiesBlanketLikeConstraint =
@@ -2578,17 +2412,6 @@ private module MethodResolution {
25782412
)
25792413
}
25802414

2581-
pragma[nomagic]
2582-
private predicate testpotentialInstantiationOf0(
2583-
MethodCallCand mcc, ImplOrTraitItemNode i, AssocFunctionType selfType, MethodCall mc,
2584-
FunctionPosition selfPos, FunctionPosition pos, Function f, string name, int arity,
2585-
TypePath strippedTypePath, Type strippedType
2586-
) {
2587-
mc = Debug::getRelevantLocatable() and
2588-
mcc.hasSignature(mc, pos, strippedTypePath, strippedType, name, arity) and
2589-
methodCallNonBlanketCandidate(mc, f, selfPos, pos, i, selfType, strippedTypePath, strippedType)
2590-
}
2591-
25922415
pragma[nomagic]
25932416
predicate potentialInstantiationOf(
25942417
MethodCallCand mcc, TypeAbstraction abs, AssocFunctionType constraint
@@ -2666,7 +2489,7 @@ private module MethodResolution {
26662489
*/
26672490
private module MethodArgsAreInstantiationsOfInput implements ArgsAreInstantiationsOfInputSig {
26682491
predicate toCheck(ImplOrTraitItemNode i, Function f, TypeParameter traitTp, FunctionPosition pos) {
2669-
functionResolutionDependsOnArgument(i, f, traitTp, pos)
2492+
FunctionOverloading::functionResolutionDependsOnArgument(i, f, traitTp, pos)
26702493
}
26712494

26722495
final private class MethodCallFinal = MethodCall;
@@ -2751,7 +2574,7 @@ private module MethodCallMatchingInput implements MatchingWithEnvironmentInputSi
27512574
)
27522575
}
27532576

2754-
final private class MethodCallFinal = MethodResolution::MethodCall;
2577+
final private class MethodCallFinal = AssocFunctionResolution::MethodCall;
27552578

27562579
class Access extends MethodCallFinal, ContextTyping::ContextTypedCallCand {
27572580
Access() {
@@ -3152,7 +2975,7 @@ private module NonMethodCallMatchingInput implements MatchingInputSig {
31522975
exists(ImplOrTraitItemNodeOption i, NonMethodFunctionDeclaration f |
31532976
result = TNonMethodFunctionDeclaration(i, f)
31542977
|
3155-
f = this.(MethodResolution::MethodCall).resolveCallTarget(i.asSome(), _, _, _) // mutual recursion; resolving some associated function calls requires resolving types
2978+
f = this.(AssocFunctionResolution::MethodCall).resolveCallTarget(i.asSome(), _, _, _) // mutual recursion; resolving some associated function calls requires resolving types
31562979
or
31572980
f = this.resolveCallTargetViaPathResolution() and
31582981
f.isDirectlyFor(i)
@@ -3249,7 +3072,7 @@ private module OperationMatchingInput implements MatchingInputSig {
32493072
}
32503073
}
32513074

3252-
class Access extends MethodResolution::MethodCallOperation {
3075+
class Access extends AssocFunctionResolution::MethodCallOperation {
32533076
Type getTypeArgument(TypeArgumentPosition apos, TypePath path) { none() }
32543077

32553078
pragma[nomagic]
@@ -3970,7 +3793,8 @@ private module Cached {
39703793
cached
39713794
predicate implicitDerefChainBorrow(Expr e, DerefChain derefChain, boolean borrow) {
39723795
exists(BorrowKind bk |
3973-
any(MethodResolution::MethodCall mc).argumentHasImplicitDerefChainBorrow(e, derefChain, bk) and
3796+
any(AssocFunctionResolution::MethodCall mc)
3797+
.argumentHasImplicitDerefChainBorrow(e, derefChain, bk) and
39743798
if bk.isNoBorrow() then borrow = false else borrow = true
39753799
)
39763800
or
@@ -4002,7 +3826,7 @@ private module Cached {
40023826
or
40033827
i instanceof ImplItemNode and dispatch = false
40043828
|
4005-
result = call.(MethodResolution::MethodCall).resolveCallTarget(i, _, _, _)
3829+
result = call.(AssocFunctionResolution::MethodCall).resolveCallTarget(i, _, _, _)
40063830
)
40073831
}
40083832

0 commit comments

Comments
 (0)