Skip to content

Commit 0db81c2

Browse files
committed
wip
1 parent c9d2a49 commit 0db81c2

File tree

2 files changed

+95
-77
lines changed

2 files changed

+95
-77
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ class AssocFunctionType extends MkAssocFunctionType {
211211
}
212212

213213
pragma[nomagic]
214-
private Trait getALookupTrait(Type t) {
214+
Trait getALookupTrait(Type t) {
215215
result = t.(TypeParamTypeParameter).getTypeParam().(TypeParamItemNode).resolveABound()
216216
or
217217
result = t.(SelfTypeParameter).getTrait()

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

Lines changed: 94 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,6 +1392,10 @@ private module AssocFunctionResolution {
13921392
)
13931393
}
13941394

1395+
private module TypeOption = Option<Type>;
1396+
1397+
private class TypeOption = TypeOption::Option;
1398+
13951399
/**
13961400
* Holds if function `f` with the name `name` and the arity `arity` exists in
13971401
* `i`, and the type at `selfPos` is `selfType`.
@@ -1402,12 +1406,16 @@ private module AssocFunctionResolution {
14021406
* and `strippedType` is the type inside the reference.
14031407
*
14041408
* `selfPosAdj` is the function-call adjusted version of `selfPos`.
1409+
*
1410+
* `implType` is the type being implemented (`None` when `i` is a trait).
1411+
*
1412+
* `isMethod` indicates whether `f` is a method.
14051413
*/
14061414
pragma[nomagic]
14071415
private predicate assocFunctionInfo(
14081416
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition selfPosAdj,
14091417
ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, Type strippedType,
1410-
TypeOption implType, boolean isMethod
1418+
TypeOption implType, TypeOption trait, boolean isMethod
14111419
) {
14121420
assocFunctionInfo(f, name, arity, i, selfPos, selfType) and
14131421
strippedType = selfType.getTypeAt(strippedTypePath) and
@@ -1425,10 +1433,19 @@ private module AssocFunctionResolution {
14251433
traitImplSelfTypeParameterOccurrence(i, f, selfPos)
14261434
) and
14271435
(
1428-
not i instanceof Impl and
1436+
implType.asSome() = resolveImplSelfTypeAt(i, TypePath::nil())
1437+
or
1438+
i instanceof Trait and
14291439
implType.isNone()
1440+
) and
1441+
(
1442+
trait.asSome() =
1443+
[
1444+
TTrait(i).(Type),
1445+
TTrait(i.(ImplItemNode).resolveTraitTy()).(Type)
1446+
]
14301447
or
1431-
implType.asSome() = resolveImplSelfTypeAt(i, TypePath::nil())
1448+
i.(Impl).isInherent() and trait.isNone()
14321449
) and
14331450
if f instanceof Method then isMethod = true else isMethod = false
14341451
}
@@ -1437,21 +1454,21 @@ private module AssocFunctionResolution {
14371454
private predicate assocFunctionInfoNonBlanketLike0(
14381455
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition selfPosAdj,
14391456
ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, Type strippedType,
1440-
TypeOption implType, boolean isMethod
1457+
TypeOption implType, TypeOption trait, boolean isMethod
14411458
) {
14421459
assocFunctionInfo(f, name, arity, selfPos, selfPosAdj, i, selfType, strippedTypePath,
1443-
strippedType, implType, isMethod) and
1460+
strippedType, implType, trait, isMethod) and
14441461
not BlanketImplementation::isBlanketLike(i, _, _)
14451462
}
14461463

14471464
pragma[nomagic]
14481465
private predicate assocFunctionInfoNonBlanketLikeTypeParam(
14491466
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition selfPosAdj,
14501467
ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, TypeParam tp,
1451-
TypeOption implType, boolean isMethod
1468+
TypeOption implType, TypeOption trait, boolean isMethod
14521469
) {
14531470
assocFunctionInfo(f, name, arity, selfPos, selfPosAdj, i, selfType, strippedTypePath,
1454-
TTypeParamTypeParameter(tp), implType, isMethod) and
1471+
TTypeParamTypeParameter(tp), implType, trait, isMethod) and
14551472
not BlanketImplementation::isBlanketLike(i, _, _)
14561473
}
14571474

@@ -1464,12 +1481,12 @@ private module AssocFunctionResolution {
14641481
private predicate assocFunctionInfoNonBlanketLike(
14651482
Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition selfPosAdj,
14661483
ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, Type strippedType,
1467-
TypeOption implType, boolean isMethod
1484+
TypeOption implType, TypeOption trait, boolean isMethod
14681485
) {
14691486
assocFunctionInfoNonBlanketLike0(f, name, arity, selfPos, selfPosAdj, i, selfType,
1470-
strippedTypePath, strippedType, implType, isMethod) or
1487+
strippedTypePath, strippedType, implType, trait, isMethod) or
14711488
assocFunctionInfoNonBlanketLikeTypeParam(f, name, arity, selfPos, selfPosAdj, i, selfType,
1472-
strippedTypePath, _, implType, isMethod)
1489+
strippedTypePath, _, implType, trait, isMethod)
14731490
}
14741491

14751492
/**
@@ -1500,33 +1517,58 @@ private module AssocFunctionResolution {
15001517
pragma[nomagic]
15011518
private predicate assocFunctionTraitInfo(string name, int arity, Trait trait) {
15021519
exists(ImplItemNode i |
1503-
assocFunctionInfo(_, name, arity, _, _, i, _, _, _, _, _) and
1520+
assocFunctionInfo(_, name, arity, _, _, i, _, _, _, _, _, _) and
15041521
trait = i.resolveTraitTy()
15051522
)
15061523
or
1507-
assocFunctionInfo(_, name, arity, _, _, trait, _, _, _, _, _)
1524+
assocFunctionInfo(_, name, arity, _, _, trait, _, _, _, _, _, _)
15081525
}
15091526

15101527
pragma[nomagic]
15111528
private predicate assocFunctionCallTraitCandidate(Element afc, Trait trait) {
15121529
afc =
15131530
any(AssocFunctionCall afc0 |
15141531
exists(string name, int arity |
1515-
afc0.hasNameAndArity(name, arity, _, _) and
1532+
afc0.hasNameAndArity(name, arity) and
15161533
assocFunctionTraitInfo(name, arity, trait) and
1517-
not afc0.hasTrait()
1534+
not afc0.hasATrait()
15181535
)
15191536
)
15201537
}
15211538

15221539
private module AssocFunctionTraitIsVisible = TraitIsVisible<assocFunctionCallTraitCandidate/2>;
15231540

1524-
predicate callVisibleTraitCandidate = AssocFunctionTraitIsVisible::traitIsVisible/2;
1525-
1541+
// private predicate callVisibleTraitCandidate = AssocFunctionTraitIsVisible::traitIsVisible/2;
15261542
bindingset[afc, impl]
15271543
pragma[inline_late]
15281544
private predicate callVisibleImplTraitCandidate(AssocFunctionCall afc, ImplItemNode impl) {
1529-
callVisibleTraitCandidate(afc, impl.resolveTraitTy())
1545+
AssocFunctionTraitIsVisible::traitIsVisible(afc, impl.resolveTraitTy())
1546+
}
1547+
1548+
private Type getNonTypeParameterTypeQualifier(AssocFunctionCall afc) {
1549+
result = getCallExprTypeQualifier(afc, TypePath::nil(), _) and
1550+
not result instanceof TypeParameter
1551+
}
1552+
1553+
pragma[nomagic]
1554+
private predicate callInfo(
1555+
AssocFunctionCall afc, string name, int arity, TypeOption typeQualifier,
1556+
TypeOption traitQualifier, boolean hasReceiver
1557+
) {
1558+
afc.hasNameAndArity(name, arity) and
1559+
(if afc.hasReceiver() then hasReceiver = true else hasReceiver = false) and
1560+
(
1561+
typeQualifier.asSome() = getNonTypeParameterTypeQualifier(afc)
1562+
or
1563+
not exists(getNonTypeParameterTypeQualifier(afc)) and
1564+
typeQualifier.isNone()
1565+
) and
1566+
(
1567+
traitQualifier.asSome() = TTrait(afc.getATrait())
1568+
or
1569+
not afc.hasATrait() and
1570+
traitQualifier.isNone()
1571+
)
15301572
}
15311573

15321574
/**
@@ -1546,23 +1588,15 @@ private module AssocFunctionResolution {
15461588
AssocFunctionCall afc, Function f, FunctionPosition selfPos, FunctionPosition selfPosAdj,
15471589
ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, Type strippedType
15481590
) {
1549-
exists(string name, int arity, TypeOption implType, boolean isMethod |
1550-
afc.hasNameAndArity(name, arity, [implType, any(TypeOption non | non.isNone())], isMethod) and
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
15511594
assocFunctionInfoNonBlanketLike(f, name, arity, selfPos, selfPosAdj, i, selfType,
1552-
strippedTypePath, strippedType, implType, isMethod)
1595+
strippedTypePath, strippedType, implType, trait, isMethod)
15531596
|
1554-
i.(Impl).isInherent() and
1555-
not afc.hasTrait()
1556-
or
1557-
callVisibleImplTraitCandidate(afc, i)
1558-
or
1559-
callVisibleTraitCandidate(afc, i)
1560-
or
1561-
exists(Trait trait | trait = afc.getTrait() |
1562-
i.(ImplItemNode).resolveTraitTy() = trait
1563-
or
1564-
i = trait
1565-
)
1597+
if not afc.hasATrait() and i.(Impl).hasTrait()
1598+
then callVisibleImplTraitCandidate(afc, i)
1599+
else any()
15661600
)
15671601
}
15681602

@@ -1583,21 +1617,16 @@ private module AssocFunctionResolution {
15831617
AssocFunctionCall afc, Function f, FunctionPosition selfPos, FunctionPosition selfPosAdj,
15841618
ImplItemNode impl, AssocFunctionType self, TypePath blanketPath, TypeParam blanketTypeParam
15851619
) {
1586-
exists(string name, int arity, boolean isMethod |
1587-
afc.hasNameAndArity(name, arity, _, isMethod) and
1588-
assocFunctionSelfInfoBlanketLike(f, name, arity, selfPos, selfPosAdj, impl, _, self,
1620+
exists(string name, int arity, Trait trait, boolean isMethod |
1621+
callInfo(afc, name, arity, _,
1622+
[TypeOption::some(TTrait(trait)), any(TypeOption non | non.isNone())], [false, isMethod]) and
1623+
assocFunctionSelfInfoBlanketLike(f, name, arity, selfPos, selfPosAdj, impl, trait, self,
15891624
blanketPath, blanketTypeParam, isMethod)
15901625
|
1591-
callVisibleImplTraitCandidate(afc, impl)
1592-
or
1593-
impl.resolveTraitTy() = afc.getTrait()
1626+
if not afc.hasATrait() then callVisibleImplTraitCandidate(afc, impl) else any()
15941627
)
15951628
}
15961629

1597-
private module TypeOption = Option<Type>;
1598-
1599-
private class TypeOption = TypeOption::Option;
1600-
16011630
/**
16021631
* A (potential) call to an associated function.
16031632
*
@@ -1619,7 +1648,7 @@ private module AssocFunctionResolution {
16191648
* [1]: https://doc.rust-lang.org/std/ops/trait.Index.html
16201649
*/
16211650
abstract class AssocFunctionCall extends Expr {
1622-
abstract predicate hasNameAndArity(string name, int arity, TypeOption implType, boolean isMethod);
1651+
abstract predicate hasNameAndArity(string name, int arity);
16231652

16241653
abstract Expr getNonReturnNodeAt(FunctionPosition apos);
16251654

@@ -1639,6 +1668,14 @@ private module AssocFunctionResolution {
16391668
/** Holds if this call targets a trait. */
16401669
predicate hasTrait() { exists(this.getTrait()) }
16411670

1671+
Trait getATrait() {
1672+
result = this.getTrait()
1673+
or
1674+
result = getALookupTrait(getCallExprTypeQualifier(this, TypePath::nil(), _))
1675+
}
1676+
1677+
predicate hasATrait() { exists(this.getATrait()) }
1678+
16421679
Type getTypeAt(FunctionPosition pos, TypePath path) {
16431680
result = inferType(this.getNodeAt(pos), path)
16441681
}
@@ -2077,11 +2114,9 @@ private module AssocFunctionResolution {
20772114

20782115
private class AssocFunctionCallMethodCallExpr extends AssocFunctionCall instanceof MethodCallExpr {
20792116
pragma[nomagic]
2080-
override predicate hasNameAndArity(string name, int arity, TypeOption implType, boolean isMethod) {
2117+
override predicate hasNameAndArity(string name, int arity) {
20812118
name = super.getIdentifier().getText() and
2082-
arity = super.getArgList().getNumberOfArgs() + 1 and
2083-
implType.isNone() and
2084-
isMethod = true
2119+
arity = super.getArgList().getNumberOfArgs() + 1
20852120
}
20862121

20872122
override Expr getNonReturnNodeAt(FunctionPosition pos) {
@@ -2100,11 +2135,9 @@ private module AssocFunctionResolution {
21002135
}
21012136

21022137
pragma[nomagic]
2103-
override predicate hasNameAndArity(string name, int arity, TypeOption implType, boolean isMethod) {
2138+
override predicate hasNameAndArity(string name, int arity) {
21042139
(if this.isInMutableContext() then name = "index_mut" else name = "index") and
2105-
arity = 2 and
2106-
implType.isNone() and
2107-
isMethod = true
2140+
arity = 2
21082141
}
21092142

21102143
override Expr getNonReturnNodeAt(FunctionPosition pos) {
@@ -2133,22 +2166,9 @@ private module AssocFunctionResolution {
21332166
}
21342167

21352168
pragma[nomagic]
2136-
private Type getNonTypeParameterTypeQualifier() {
2137-
result = getCallExprTypeQualifier(this, TypePath::nil(), _) and
2138-
not result instanceof TypeParameter
2139-
}
2140-
2141-
pragma[nomagic]
2142-
override predicate hasNameAndArity(string name, int arity, TypeOption implType, boolean isMethod) {
2169+
override predicate hasNameAndArity(string name, int arity) {
21432170
name = CallExprImpl::getFunctionPath(this).getText() and
2144-
arity = super.getArgList().getNumberOfArgs() and
2145-
(
2146-
not exists(this.getNonTypeParameterTypeQualifier()) and
2147-
implType.isNone()
2148-
or
2149-
implType.asSome() = this.getNonTypeParameterTypeQualifier()
2150-
) and
2151-
isMethod = [false, true]
2171+
arity = super.getArgList().getNumberOfArgs()
21522172
}
21532173

21542174
override Expr getNonReturnNodeAt(FunctionPosition pos) {
@@ -2169,11 +2189,9 @@ private module AssocFunctionResolution {
21692189

21702190
final class AssocFunctionCallOperation extends AssocFunctionCall instanceof Operation {
21712191
pragma[nomagic]
2172-
override predicate hasNameAndArity(string name, int arity, TypeOption implType, boolean isMethod) {
2192+
override predicate hasNameAndArity(string name, int arity) {
21732193
super.isOverloaded(_, name, _) and
2174-
arity = super.getNumberOfOperands() and
2175-
implType.isNone() and
2176-
isMethod = true
2194+
arity = super.getNumberOfOperands()
21772195
}
21782196

21792197
override Expr getNonReturnNodeAt(FunctionPosition pos) {
@@ -2289,7 +2307,7 @@ private module AssocFunctionResolution {
22892307
selfPos.isTypeQualifier() and strippedTypePath.isEmpty()
22902308
) and
22912309
afc = afc_ and
2292-
afc.hasNameAndArity(name, arity, _, _) and
2310+
afc.hasNameAndArity(name, arity) and
22932311
pos = selfPosAdj
22942312
}
22952313

@@ -2316,7 +2334,7 @@ private module AssocFunctionResolution {
23162334
this.hasSignature(_, selfPosAdj, strippedTypePath, strippedType, name, arity) and
23172335
forall(Impl i |
23182336
assocFunctionInfoNonBlanketLike(_, name, arity, _, selfPosAdj, i, _, strippedTypePath,
2319-
strippedType, _, _) and
2337+
strippedType, _, _, _) and
23202338
i.isInherent()
23212339
|
23222340
this.hasIncompatibleInherentTarget(i)
@@ -2327,7 +2345,7 @@ private module AssocFunctionResolution {
23272345
pragma[nomagic]
23282346
private predicate argIsInstantiationOf(ImplOrTraitItemNode i, string name, int arity) {
23292347
ArgIsInstantiationOfSelfParam::argIsInstantiationOf(this, i, _) and
2330-
afc_.hasNameAndArity(name, arity, _, _)
2348+
afc_.hasNameAndArity(name, arity)
23312349
}
23322350

23332351
pragma[nomagic]
@@ -2487,7 +2505,7 @@ private module AssocFunctionResolution {
24872505
}
24882506

24892507
predicate relevantConstraint(AssocFunctionType constraint) {
2490-
assocFunctionInfo(_, _, _, _, _, _, constraint, _, _, _, _)
2508+
assocFunctionInfo(_, _, _, _, _, _, constraint, _, _, _, _, _)
24912509
}
24922510
}
24932511

@@ -4007,8 +4025,8 @@ private module Debug {
40074025
Locatable getRelevantLocatable() {
40084026
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
40094027
result.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
4010-
filepath.matches("%/main.rs") and
4011-
startline = 50
4028+
filepath.matches("%/overloading.rs") and
4029+
startline = 57
40124030
)
40134031
}
40144032

0 commit comments

Comments
 (0)