Skip to content

Commit 2354422

Browse files
committed
wip
1 parent 2ad72fd commit 2354422

File tree

2 files changed

+68
-32
lines changed

2 files changed

+68
-32
lines changed

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,7 @@ class AssocFunctionType extends MkAssocFunctionType {
199199
exists(Function f, ImplOrTraitItemNode i, FunctionPosition pos | this.appliesTo(f, i, pos) |
200200
result = pos.getTypeMention(f)
201201
or
202-
pos.isSelfOrTypeQualifier() and
203-
not f.hasSelfParam() and
202+
pos.isTypeQualifier() and
204203
result = [i.(Impl).getSelfTy().(AstNode), i.(Trait).getName()]
205204
)
206205
}
@@ -315,7 +314,7 @@ signature module ArgsAreInstantiationsOfInputSig {
315314
* If `i` is an inherent implementation, `tp` is a type parameter of the type being
316315
* implemented, otherwise `tp` is a type parameter of the trait (being implemented).
317316
*
318-
* `posAdj` is one of the positions in `f` in which the relevant type occurs.
317+
* `posAdj` is one of the adjusted positions in `f` in which the relevant type occurs.
319318
*/
320319
predicate toCheck(ImplOrTraitItemNode i, Function f, TypeParameter tp, FunctionPosition posAdj);
321320

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

Lines changed: 66 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,7 +1353,7 @@ private class BorrowKind extends TBorrowKind {
13531353
private module AssocFunctionResolution {
13541354
/**
13551355
* Holds if function `f` with the name `name` and the arity `arity` exists in
1356-
* `i`, and the type at position `posAdj` is `t`.
1356+
* `i`, and the type at adjusted position `posAdj` is `t`.
13571357
*/
13581358
pragma[nomagic]
13591359
private predicate assocFunctionInfo(
@@ -1370,29 +1370,29 @@ private module AssocFunctionResolution {
13701370

13711371
/**
13721372
* Holds if function `f` with the name `name` and the arity `arity` exists in
1373-
* blanket (like) implementation `impl` of `trait`, and the type at position
1374-
* `posAdj` is `t`.
1373+
* blanket (like) implementation `impl` of `trait`, and the type at adjusted
1374+
* position `posAdj` is `t`.
13751375
*
13761376
* `blanketPath` points to the type `blanketTypeParam` inside `t`, which
13771377
* is the type parameter used in the blanket implementation.
13781378
*/
13791379
pragma[nomagic]
13801380
private predicate assocFunctionInfoBlanketLike(
1381-
Function f, string name, int arity, ImplItemNode impl, Trait trait, FunctionPosition posAdj,
1382-
AssocFunctionType t, TypePath blanketPath, TypeParam blanketTypeParam
1381+
Function f, string name, int arity, ImplItemNode impl, TypeOption implType, TypeOption trait,
1382+
FunctionPosition posAdj, AssocFunctionType t, TypePath blanketPath, TypeParam blanketTypeParam,
1383+
boolean isMethod
13831384
) {
13841385
exists(TypePath blanketSelfPath |
1385-
assocFunctionInfo(f, name, arity, impl, posAdj, t) and
1386+
assocFunctionInfo(f, name, arity, posAdj, impl, t, _, _, implType, trait, isMethod) and
13861387
TTypeParamTypeParameter(blanketTypeParam) = t.getTypeAt(blanketPath) and
13871388
blanketPath = any(string s) + blanketSelfPath and
1388-
BlanketImplementation::isBlanketLike(impl, blanketSelfPath, blanketTypeParam) and
1389-
trait = impl.resolveTraitTy()
1389+
BlanketImplementation::isBlanketLike(impl, blanketSelfPath, blanketTypeParam)
13901390
)
13911391
}
13921392

13931393
/**
13941394
* Holds if the non-method trait function `f` mentions the implicit `Self` type
1395-
* parameter at `posAdj`.
1395+
* parameter at adjusted position `posAdj`.
13961396
*/
13971397
pragma[nomagic]
13981398
private predicate traitSelfTypeParameterOccurrence(
@@ -1407,7 +1407,7 @@ private module AssocFunctionResolution {
14071407

14081408
/**
14091409
* Holds if the non-method function `f` implements a trait function that mentions
1410-
* the implicit `Self` type parameter at `posAdj`.
1410+
* the implicit `Self` type parameter at adjusted position `posAdj`.
14111411
*/
14121412
pragma[nomagic]
14131413
private predicate traitImplSelfTypeParameterOccurrence(
@@ -1428,6 +1428,11 @@ private module AssocFunctionResolution {
14281428
* Holds if function `f` with the name `name` and the arity `arity` exists in
14291429
* `i`, and the type at `selfPosAdj` is `selfType`.
14301430
*
1431+
* `selfPosAdj` is an adjusted position relevant for call resolution: either a position
1432+
* corresponding to the `self` parameter of `f` (if present); a type qualifier position;
1433+
* or a position where the implicit `Self` type parameter of some trait is mentioned in
1434+
* some non-method function `f_trait`, and either `f = f_trait` or `f` implements `f_trait`.
1435+
*
14311436
* `strippedTypePath` points to the type `strippedType` inside `selfType`,
14321437
* which is the (possibly complex-stripped) root type of `selfType`. For example,
14331438
* if `f` has a `&self` parameter, then `strippedTypePath` is `getRefSharedTypeParameter()`
@@ -1511,19 +1516,32 @@ private module AssocFunctionResolution {
15111516
AssocFunctionTraitIsVisible::traitIsVisible(afc, impl.resolveTraitTy())
15121517
}
15131518

1514-
pragma[inline]
1515-
private predicate callMatching(
1516-
TypeOption implType, TypeOption trait, Boolean isMethod, TypeOption typeQualifier,
1517-
TypeOption traitQualifier, boolean hasReceiver
1518-
) {
1519+
bindingset[implType]
1520+
private predicate callTypeQualifierFilter(TypeOption implType, TypeOption typeQualifier) {
15191521
// when present, explicit type qualifier must match the type being implemented
1520-
typeQualifier = [implType, any(TypeOption non | non.isNone())] and
1522+
typeQualifier = [implType, any(TypeOption non | non.isNone())]
1523+
}
1524+
1525+
bindingset[trait, isMethod]
1526+
pragma[inline_late]
1527+
private predicate callTraitQualifierAndReceiverFilter(
1528+
TypeOption trait, Boolean isMethod, TypeOption traitQualifier, boolean hasReceiver
1529+
) {
15211530
// when present, explicit trait qualifier must match the trait being implemented or the trait itself
15221531
traitQualifier = [trait, any(TypeOption non | non.isNone())] and
15231532
// when a receiver is present, the target must be a method
15241533
hasReceiver = [isMethod, false]
15251534
}
15261535

1536+
bindingset[implType, trait, isMethod]
1537+
private predicate callFilter(
1538+
TypeOption implType, TypeOption trait, Boolean isMethod, TypeOption typeQualifier,
1539+
TypeOption traitQualifier, boolean hasReceiver
1540+
) {
1541+
callTypeQualifierFilter(implType, typeQualifier) and
1542+
callTraitQualifierAndReceiverFilter(trait, isMethod, traitQualifier, hasReceiver)
1543+
}
1544+
15271545
pragma[nomagic]
15281546
private predicate assocFunctionInfoNonBlanketLikeCand(
15291547
Function f, string name, int arity, FunctionPosition selfPosAdj, ImplOrTraitItemNode i,
@@ -1534,7 +1552,7 @@ private module AssocFunctionResolution {
15341552
assocFunctionInfo(f, name, arity, selfPosAdj, i, selfType, strippedTypePath, strippedType,
15351553
implType, trait, isMethod) and
15361554
not BlanketImplementation::isBlanketLike(i, _, _) and
1537-
callMatching(implType, trait, isMethod, typeQualifier, traitQualifier, hasReceiver)
1555+
callFilter(implType, trait, isMethod, typeQualifier, traitQualifier, hasReceiver)
15381556
)
15391557
}
15401558

@@ -1548,7 +1566,7 @@ private module AssocFunctionResolution {
15481566
assocFunctionInfo(f, name, arity, selfPosAdj, i, selfType, strippedTypePath,
15491567
TTypeParamTypeParameter(_), implType, trait, isMethod) and
15501568
not BlanketImplementation::isBlanketLike(i, _, _) and
1551-
callMatching(implType, trait, isMethod, typeQualifier, traitQualifier, hasReceiver)
1569+
callFilter(implType, trait, isMethod, typeQualifier, traitQualifier, hasReceiver)
15521570
)
15531571
}
15541572

@@ -1586,17 +1604,14 @@ private module AssocFunctionResolution {
15861604
}
15871605

15881606
pragma[nomagic]
1589-
private predicate assocFunctionSelfInfoBlanketLikeCand(
1607+
private predicate assocFunctionSelfInfoBlanketLikeCand0(
15901608
Function f, string name, int arity, FunctionPosition selfPosAdj, ImplItemNode impl,
15911609
AssocFunctionType selfType, TypePath blanketPath, TypeParam blanketTypeParam,
1592-
TypeOption traitQualifier, boolean hasReceiver
1610+
TypeOption implType, TypeOption trait, boolean isMethod
15931611
) {
1594-
exists(Trait trait, boolean isMethod |
1595-
assocFunctionInfoBlanketLike(f, name, arity, impl, trait, selfPosAdj, selfType, blanketPath,
1596-
blanketTypeParam) and
1597-
(if f instanceof Method then isMethod = true else isMethod = false) and
1598-
callMatching(_, TypeOption::some(TTrait(trait)), isMethod, _, traitQualifier, hasReceiver)
1599-
|
1612+
assocFunctionInfoBlanketLike(f, name, arity, impl, implType, trait, selfPosAdj, selfType,
1613+
blanketPath, blanketTypeParam, isMethod) and
1614+
(
16001615
isMethod = true and
16011616
selfPosAdj.asPosition() = 0
16021617
or
@@ -1606,6 +1621,25 @@ private module AssocFunctionResolution {
16061621
)
16071622
}
16081623

1624+
bindingset[name, arity, typeQualifier, traitQualifier, hasReceiver]
1625+
pragma[inline_late]
1626+
private predicate assocFunctionSelfInfoBlanketLikeCand(
1627+
Function f, string name, int arity, FunctionPosition selfPosAdj, ImplItemNode impl,
1628+
AssocFunctionType selfType, TypePath blanketPath, TypeParam blanketTypeParam,
1629+
TypeOption typeQualifier, TypeOption traitQualifier, boolean hasReceiver
1630+
) {
1631+
exists(TypeOption implType, TypeOption trait, boolean isMethod |
1632+
assocFunctionSelfInfoBlanketLikeCand0(f, name, arity, selfPosAdj, impl, selfType, blanketPath,
1633+
blanketTypeParam, implType, trait, isMethod) and
1634+
(
1635+
if impl.isBlanketImplementation()
1636+
then any()
1637+
else callTypeQualifierFilter(implType, typeQualifier)
1638+
) and
1639+
callTraitQualifierAndReceiverFilter(trait, isMethod, traitQualifier, hasReceiver)
1640+
)
1641+
}
1642+
16091643
/**
16101644
* Holds if call `afc` may target function `f` in blanket (like) implementation
16111645
* `impl` with type `selfType` at `selfPosAdj`.
@@ -1623,10 +1657,13 @@ private module AssocFunctionResolution {
16231657
AssocFunctionCall afc, Function f, FunctionPosition selfPosAdj, ImplItemNode impl,
16241658
AssocFunctionType self, TypePath blanketPath, TypeParam blanketTypeParam
16251659
) {
1626-
exists(string name, int arity, TypeOption traitQualifier, boolean hasReceiver |
1627-
afc.hasSyntacticInfo(name, arity, _, traitQualifier, hasReceiver) and
1660+
exists(
1661+
string name, int arity, TypeOption typeQualifier, TypeOption traitQualifier,
1662+
boolean hasReceiver
1663+
|
1664+
afc.hasSyntacticInfo(name, arity, typeQualifier, traitQualifier, hasReceiver) and
16281665
assocFunctionSelfInfoBlanketLikeCand(f, name, arity, selfPosAdj, impl, self, blanketPath,
1629-
blanketTypeParam, traitQualifier, hasReceiver)
1666+
blanketTypeParam, typeQualifier, traitQualifier, hasReceiver)
16301667
|
16311668
if not afc.hasATrait() then callVisibleImplTraitCandidate(afc, impl) else any()
16321669
)

0 commit comments

Comments
 (0)