Skip to content

Commit 0562a15

Browse files
committed
wip2
1 parent 0db81c2 commit 0562a15

File tree

1 file changed

+65
-31
lines changed

1 file changed

+65
-31
lines changed

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

Lines changed: 65 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,7 +1407,9 @@ private module AssocFunctionResolution {
14071407
*
14081408
* `selfPosAdj` is the function-call adjusted version of `selfPos`.
14091409
*
1410-
* `implType` is the type being implemented (`None` when `i` is a trait).
1410+
* `implType` is the type being implemented by `i` (`None` when `i` is a trait).
1411+
*
1412+
* `trait` is the trait being implemented by `i` or `i` itself (`None` when `i` is inherent).
14111413
*
14121414
* `isMethod` indicates whether `f` is a method.
14131415
*/
@@ -1451,7 +1453,7 @@ private module AssocFunctionResolution {
14511453
}
14521454

14531455
pragma[nomagic]
1454-
private predicate assocFunctionInfoNonBlanketLike0(
1456+
private predicate assocFunctionInfoNonBlanketLike(
14551457
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition selfPosAdj,
14561458
ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, Type strippedType,
14571459
TypeOption implType, TypeOption trait, boolean isMethod
@@ -1464,29 +1466,11 @@ private module AssocFunctionResolution {
14641466
pragma[nomagic]
14651467
private predicate assocFunctionInfoNonBlanketLikeTypeParam(
14661468
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition selfPosAdj,
1467-
ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, TypeParam tp,
1468-
TypeOption implType, TypeOption trait, boolean isMethod
1469-
) {
1470-
assocFunctionInfo(f, name, arity, selfPos, selfPosAdj, i, selfType, strippedTypePath,
1471-
TTypeParamTypeParameter(tp), implType, trait, isMethod) and
1472-
not BlanketImplementation::isBlanketLike(i, _, _)
1473-
}
1474-
1475-
/**
1476-
* Same as `assocFunctionInfo`, but restricted to non-blanket-like implementations, and
1477-
* allowing for any `strippedType` when the corresponding type inside `f` is
1478-
* a type parameter.
1479-
*/
1480-
pragma[inline]
1481-
private predicate assocFunctionInfoNonBlanketLike(
1482-
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition selfPosAdj,
1483-
ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, Type strippedType,
1469+
ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath,
14841470
TypeOption implType, TypeOption trait, boolean isMethod
14851471
) {
1486-
assocFunctionInfoNonBlanketLike0(f, name, arity, selfPos, selfPosAdj, i, selfType,
1487-
strippedTypePath, strippedType, implType, trait, isMethod) or
1488-
assocFunctionInfoNonBlanketLikeTypeParam(f, name, arity, selfPos, selfPosAdj, i, selfType,
1489-
strippedTypePath, _, implType, trait, isMethod)
1472+
assocFunctionInfoNonBlanketLike(f, name, arity, selfPos, selfPosAdj, i, selfType,
1473+
strippedTypePath, TTypeParamTypeParameter(_), implType, trait, isMethod)
14901474
}
14911475

14921476
/**
@@ -1496,6 +1480,8 @@ private module AssocFunctionResolution {
14961480
*
14971481
* `blanketPath` points to the type `blanketTypeParam` inside `selfType`, which
14981482
* is the type parameter used in the blanket implementation.
1483+
*
1484+
* `isMethod` indicates whether `f` is a method.
14991485
*/
15001486
pragma[nomagic]
15011487
private predicate assocFunctionSelfInfoBlanketLike(
@@ -1531,14 +1517,14 @@ private module AssocFunctionResolution {
15311517
exists(string name, int arity |
15321518
afc0.hasNameAndArity(name, arity) and
15331519
assocFunctionTraitInfo(name, arity, trait) and
1520+
// we only need to check visibility of traits that are not mentioned explicitly
15341521
not afc0.hasATrait()
15351522
)
15361523
)
15371524
}
15381525

15391526
private module AssocFunctionTraitIsVisible = TraitIsVisible<assocFunctionCallTraitCandidate/2>;
15401527

1541-
// private predicate callVisibleTraitCandidate = AssocFunctionTraitIsVisible::traitIsVisible/2;
15421528
bindingset[afc, impl]
15431529
pragma[inline_late]
15441530
private predicate callVisibleImplTraitCandidate(AssocFunctionCall afc, ImplItemNode impl) {
@@ -1571,6 +1557,45 @@ private module AssocFunctionResolution {
15711557
)
15721558
}
15731559

1560+
bindingset[implType, trait, isMethod]
1561+
private predicate callMatching(
1562+
TypeOption implType, TypeOption trait, boolean isMethod, TypeOption typeQualifier,
1563+
TypeOption traitQualifier, boolean hasReceiver
1564+
) {
1565+
// when present, explicit type qualifier must match the type being implemented
1566+
typeQualifier = [implType, any(TypeOption non | non.isNone())] and
1567+
// when present, explicit trait qualifier must match the trait being implemented or the trait itself
1568+
traitQualifier = [trait, any(TypeOption non | non.isNone())] and
1569+
// when a receiver is present, the target must be a method
1570+
hasReceiver = [isMethod, false]
1571+
}
1572+
1573+
pragma[nomagic]
1574+
private predicate assocFunctionInfoNonBlanketLikeCand(
1575+
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition selfPosAdj,
1576+
ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, Type strippedType,
1577+
TypeOption typeQualifier, TypeOption traitQualifier, boolean hasReceiver
1578+
) {
1579+
exists(TypeOption implType, TypeOption trait, boolean isMethod |
1580+
assocFunctionInfoNonBlanketLike(f, name, arity, selfPos, selfPosAdj, i, selfType,
1581+
strippedTypePath, strippedType, implType, trait, isMethod) and
1582+
callMatching(implType, trait, isMethod, typeQualifier, traitQualifier, hasReceiver)
1583+
)
1584+
}
1585+
1586+
pragma[nomagic]
1587+
private predicate assocFunctionInfoNonBlanketLikeTypeParamCand(
1588+
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition selfPosAdj,
1589+
ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath,
1590+
TypeOption typeQualifier, TypeOption traitQualifier, boolean hasReceiver
1591+
) {
1592+
exists(TypeOption implType, TypeOption trait, boolean isMethod |
1593+
assocFunctionInfoNonBlanketLikeTypeParam(f, name, arity, selfPos, selfPosAdj, i, selfType,
1594+
strippedTypePath, implType, trait, isMethod) and
1595+
callMatching(implType, trait, isMethod, typeQualifier, traitQualifier, hasReceiver)
1596+
)
1597+
}
1598+
15741599
/**
15751600
* Holds if call `afc` may target function `f` in `i` with type `selfType` at
15761601
* `selfPos`.
@@ -1588,15 +1613,20 @@ private module AssocFunctionResolution {
15881613
AssocFunctionCall afc, Function f, FunctionPosition selfPos, FunctionPosition selfPosAdj,
15891614
ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, Type strippedType
15901615
) {
1591-
exists(string name, int arity, TypeOption implType, TypeOption trait, boolean isMethod |
1592-
callInfo(afc, name, arity, [implType, any(TypeOption non | non.isNone())],
1593-
[trait, any(TypeOption non | non.isNone())], [false, isMethod]) and
1594-
assocFunctionInfoNonBlanketLike(f, name, arity, selfPos, selfPosAdj, i, selfType,
1595-
strippedTypePath, strippedType, implType, trait, isMethod)
1616+
exists(
1617+
string name, int arity, TypeOption typeQualifier, TypeOption traitQualifier,
1618+
boolean hasReceiver
15961619
|
1620+
callInfo(afc, name, arity, typeQualifier, traitQualifier, hasReceiver) and
15971621
if not afc.hasATrait() and i.(Impl).hasTrait()
15981622
then callVisibleImplTraitCandidate(afc, i)
15991623
else any()
1624+
|
1625+
assocFunctionInfoNonBlanketLikeCand(f, name, arity, selfPos, selfPosAdj, i, selfType,
1626+
strippedTypePath, strippedType, typeQualifier, traitQualifier, hasReceiver)
1627+
or
1628+
assocFunctionInfoNonBlanketLikeTypeParamCand(f, name, arity, selfPos, selfPosAdj, i, selfType,
1629+
strippedTypePath, typeQualifier, traitQualifier, hasReceiver)
16001630
)
16011631
}
16021632

@@ -2333,8 +2363,12 @@ private module AssocFunctionResolution {
23332363
|
23342364
this.hasSignature(_, selfPosAdj, strippedTypePath, strippedType, name, arity) and
23352365
forall(Impl i |
2336-
assocFunctionInfoNonBlanketLike(_, name, arity, _, selfPosAdj, i, _, strippedTypePath,
2337-
strippedType, _, _, _) and
2366+
(
2367+
assocFunctionInfoNonBlanketLike(_, name, arity, _, selfPosAdj, i, _, strippedTypePath,
2368+
strippedType, _, _, _) or
2369+
assocFunctionInfoNonBlanketLikeTypeParam(_, name, arity, _, selfPosAdj, i, _,
2370+
strippedTypePath, _, _, _)
2371+
) and
23382372
i.isInherent()
23392373
|
23402374
this.hasIncompatibleInherentTarget(i)

0 commit comments

Comments
 (0)