Skip to content

Commit 5183918

Browse files
committed
wip
1 parent adfced0 commit 5183918

File tree

3 files changed

+80
-33
lines changed

3 files changed

+80
-33
lines changed

rust/ql/lib/codeql/rust/elements/internal/FunctionImpl.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,8 @@ module Impl {
6969
this.getLocation().getStartLine() <= result.getLocation().getStartLine() and
7070
result.getLocation().getStartLine() <= this.getName().getLocation().getStartLine()
7171
}
72+
73+
pragma[nomagic]
74+
predicate hasSelfParam() { this.getParamList().hasSelfParam() }
7275
}
7376
}

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

Lines changed: 76 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ class FunctionPosition extends TFunctionPosition {
773773
this.isReturn() and
774774
result = this
775775
or
776-
if f.getParamList().hasSelfParam()
776+
if f.hasSelfParam()
777777
then
778778
this.isSelf() and result.asPositional() = 0
779779
or
@@ -951,7 +951,7 @@ private newtype TFunctionPositionType =
951951
MkFunctionPositionType(Function f, FunctionPosition pos, ImplOrTraitItemNode i) {
952952
f = i.getAnAssocItem() and
953953
(
954-
f.getParamList().hasSelfParam() and
954+
f.hasSelfParam() and
955955
pos.asArgumentPosition().isSelf()
956956
or
957957
exists(f.getParam(pos.asPositional()))
@@ -1107,7 +1107,8 @@ private module MethodCallResolution {
11071107
*/
11081108
pragma[nomagic]
11091109
predicate methodCandidate(
1110-
Type type, string name, int arity, ImplOrTraitItemNode i, FunctionPositionType self
1110+
Type type, string name, int arity, ImplOrTraitItemNode i, FunctionPositionType self,
1111+
Type selfType
11111112
) {
11121113
exists(Function f, FunctionPosition pos |
11131114
f = i.getASuccessor(name) and
@@ -1116,13 +1117,17 @@ private module MethodCallResolution {
11161117
self.appliesTo(f, pos, i) and
11171118
pos.isSelf() and
11181119
not i.(ImplItemNode).isBlanket()
1120+
|
1121+
selfType = i.(Impl).getSelfTy().(TypeMention).resolveType()
1122+
or
1123+
selfType = TTrait(i)
11191124
)
11201125
}
11211126

11221127
pragma[nomagic]
11231128
private predicate methodCandidateImplTrait(string name, int arity, Trait trait) {
11241129
exists(ImplItemNode i |
1125-
methodCandidate(_, name, arity, i, _) and
1130+
methodCandidate(_, name, arity, i, _, _) and
11261131
trait = i.resolveTraitTy()
11271132
)
11281133
}
@@ -1151,7 +1156,7 @@ private module MethodCallResolution {
11511156
) {
11521157
exists(string name, int arity |
11531158
mc.isMethodCall(name, arity) and
1154-
methodCandidate(type, name, arity, i, self) //and
1159+
methodCandidate(type, name, arity, i, self, _) //and
11551160
|
11561161
// not CertainTypeInference::inferCertainType(mc.getReceiver(), TypePath::nil()) != type
11571162
not exists(i.(ImplItemNode).resolveTraitTy())
@@ -1389,7 +1394,7 @@ private module MethodCallResolution {
13891394
exists(Type type, string name, int arity |
13901395
this.isMethodCall(_, type, name, arity) and
13911396
forall(Impl impl |
1392-
methodCandidate(type, name, arity, impl, _) and
1397+
methodCandidate(type, name, arity, impl, _, _) and
13931398
not impl.hasTrait()
13941399
|
13951400
this.isNotInherentTarget(impl)
@@ -1656,22 +1661,39 @@ private module FunctionCallResolution {
16561661

16571662
/** A function call, `f(x)`. */
16581663
final class FunctionCall extends CallExpr {
1659-
// FunctionCall() { this = Debug::getRelevantLocatable() }
1660-
private ItemNode getResolvedFunction() { result = CallExprImpl::getResolvedFunction(this) }
1664+
private ItemNode getPathResolutionResolvedFunction() {
1665+
result = CallExprImpl::getResolvedFunction(this)
1666+
}
1667+
1668+
// The `Self` type is supplied explicitly as a type qualifier, e.g. `Foo::<Bar>::baz()`
1669+
pragma[nomagic]
1670+
Type getQualifierType(TypePath path) {
1671+
exists(PathExpr pe, TypeMention tm |
1672+
pe = this.getFunction() and
1673+
tm = pe.getPath().getQualifier() and
1674+
result = tm.resolveTypeAt(path) and
1675+
not resolvePath(tm) instanceof Trait
1676+
)
1677+
}
16611678

16621679
/**
16631680
* Holds if the target of this call is ambigous, and type information is required
16641681
* to disambiguate.
16651682
*/
1666-
predicate isAmbigous() {
1683+
private predicate isAmbigous() {
16671684
this.(Call).hasTrait()
16681685
or
1669-
functionResolutionDependsOnArgument(_, _, this.getResolvedFunction(), _, _, _)
1686+
functionResolutionDependsOnArgument(_, _, this.getPathResolutionResolvedFunction(), _, _, _)
1687+
// or
1688+
// // always check the `self` type in method calls
1689+
// this.getPathResolutionResolvedFunction().(Function).hasSelfParam()
16701690
}
16711691

16721692
pragma[nomagic]
1673-
Function getAnAmbigousCandidate0(ImplItemNode impl, FunctionPosition pos, Function resolved) {
1674-
resolved = this.getResolvedFunction() and
1693+
Function getAnAmbigousCandidate0(
1694+
ImplOrTraitItemNode impl, FunctionPosition pos, Function resolved
1695+
) {
1696+
resolved = this.getPathResolutionResolvedFunction() and
16751697
(
16761698
exists(TraitItemNode trait |
16771699
trait = this.(Call).getTrait() and
@@ -1680,18 +1702,32 @@ private module FunctionCallResolution {
16801702
|
16811703
functionResolutionDependsOnArgument(impl, _, result, pos, _, _)
16821704
or
1705+
// todo: remove tp
16831706
exists(TypeParameter tp | traitTypeParameterOccurrence(trait, resolved, _, pos, _, tp) |
16841707
not pos.isReturn()
16851708
or
16861709
// We only check that the context of the call provides relevant type information
16871710
// when no argument can
1688-
not traitTypeParameterOccurrence(trait, resolved, _,
1689-
any(FunctionPosition pos0 | not pos0.isReturn()), _, _)
1711+
not exists(FunctionPosition pos0 |
1712+
traitTypeParameterOccurrence(trait, resolved, _, pos0, _, _) and
1713+
not pos0.isReturn()
1714+
)
16901715
)
1716+
or
1717+
// always check the `self` type in method calls
1718+
resolved.hasSelfParam() and
1719+
pos.isSelf()
16911720
)
16921721
or
1722+
not this.(Call).hasTrait() and
16931723
result = resolved and
16941724
functionResolutionDependsOnArgument(impl, _, result, pos, _, _)
1725+
// or
1726+
// // always check the `self` type in method calls
1727+
// not this.(Call).hasTrait() and
1728+
// result = impl.getASuccessor(_) and
1729+
// resolved.hasSelfParam() and
1730+
// pos.isSelf()
16951731
)
16961732
}
16971733

@@ -1704,7 +1740,9 @@ private module FunctionCallResolution {
17041740
* `resolved` is the corresponding function resolved through path resolution.
17051741
*/
17061742
pragma[nomagic]
1707-
Function getAnAmbigousCandidate(ImplItemNode impl, FunctionPosition pos, Function resolved) {
1743+
Function getAnAmbigousCandidate(
1744+
ImplOrTraitItemNode impl, FunctionPosition pos, Function resolved
1745+
) {
17081746
exists(FunctionPosition pos0 |
17091747
result = this.getAnAmbigousCandidate0(impl, pos0, resolved) and
17101748
pos = pos0.getFunctionCallAdjusted(result)
@@ -1715,7 +1753,7 @@ private module FunctionCallResolution {
17151753
* Same as `getAnAmbigousCandidate`, ranks the positions to be checked.
17161754
*/
17171755
private Function getAnAmbigousCandidateRanked(
1718-
ImplItemNode impl, FunctionPosition pos, Function f, int rnk
1756+
ImplOrTraitItemNode impl, FunctionPosition pos, Function f, int rnk
17191757
) {
17201758
pos =
17211759
rank[rnk + 1](FunctionPosition pos0, int i1, int i2 |
@@ -1732,7 +1770,7 @@ private module FunctionCallResolution {
17321770

17331771
pragma[nomagic]
17341772
private Function resolveAmbigousFunctionCallTargetFromIndex(int index) {
1735-
exists(Impl impl, FunctionPosition pos, Function resolved |
1773+
exists(ImplOrTraitItemNode impl, FunctionPosition pos, Function resolved |
17361774
IsInstantiationOf<AmbigousFunctionCall, FunctionPositionType, AmbigousFuncIsInstantiationOfInput>::isInstantiationOf(MkAmbigousFunctionCall(this,
17371775
resolved, pos), impl, _) and
17381776
result = this.getAnAmbigousCandidateRanked(impl, pos, resolved, index)
@@ -1759,7 +1797,7 @@ private module FunctionCallResolution {
17591797
*/
17601798
pragma[nomagic]
17611799
private ItemNode resolveUnambigousFunctionCallTarget() {
1762-
result = this.getResolvedFunction() and
1800+
result = this.getPathResolutionResolvedFunction() and
17631801
not this.isAmbigous()
17641802
}
17651803

@@ -1785,13 +1823,24 @@ private module FunctionCallResolution {
17851823
AmbigousFunctionCall() { this = MkAmbigousFunctionCall(call, resolved, pos) }
17861824

17871825
pragma[nomagic]
1788-
Type getTypeAt(TypePath path) {
1826+
private Type getTypeAt0(TypePath path) {
17891827
result = inferType(call.(CallExpr).getArg(pos.asPositional()), path)
17901828
or
1829+
// pos.asPositional() = 0 and
1830+
// result = call.getQualifierType(path)
1831+
// or
17911832
pos.isReturn() and
17921833
result = inferType(call, path)
17931834
}
17941835

1836+
pragma[nomagic]
1837+
Type getTypeAt(TypePath path) {
1838+
result = this.getTypeAt0(path) and
1839+
not exists(getATraitBound(result))
1840+
or
1841+
result = TTrait(getATraitBound(this.getTypeAt0(path)))
1842+
}
1843+
17951844
string toString() { result = call.toString() + " (pos: " + pos + ")" }
17961845

17971846
Location getLocation() { result = call.getLocation() }
@@ -1937,9 +1986,7 @@ private module FunctionCallMatchingInput implements MatchingInputSig {
19371986
exists(Param p, int i |
19381987
p = this.getParam(i) and
19391988
result = p.getTypeRepr().(TypeMention).resolveTypeAt(path) and
1940-
if this.getParamList().hasSelfParam()
1941-
then dpos.asPositional() = i + 1
1942-
else dpos.asPositional() = i
1989+
if this.hasSelfParam() then dpos.asPositional() = i + 1 else dpos.asPositional() = i
19431990
)
19441991
or
19451992
dpos.asPositional() = 0 and
@@ -1992,14 +2039,8 @@ private module FunctionCallMatchingInput implements MatchingInputSig {
19922039

19932040
pragma[nomagic]
19942041
Type getInferredType(AccessPosition apos, TypePath path) {
1995-
// The `Self` type is supplied explicitly as a type qualifier, e.g. `Foo::<Bar>::baz()`
19962042
apos.asArgumentPosition().isSelf() and
1997-
exists(PathExpr pe, TypeMention tm |
1998-
pe = this.getFunction() and
1999-
tm = pe.getPath().getQualifier() and
2000-
result = tm.resolveTypeAt(path) and
2001-
not resolvePath(tm) instanceof Trait
2002-
)
2043+
result = this.getQualifierType(path)
20032044
or
20042045
result = inferType(this.getNodeAt(apos), path)
20052046
}
@@ -2028,6 +2069,7 @@ private Type inferCallExprType(AstNode n, TypePath path) {
20282069
private module OperationResolution {
20292070
/** An operation, `x + y`. */
20302071
final class Op extends Operation {
2072+
// Op() { none() }
20312073
pragma[nomagic]
20322074
private Type getTypeAt0(TypePath path) {
20332075
if this.(Call).implicitBorrowAt(any(ArgumentPosition pos | pos.isSelf()), true)
@@ -2099,7 +2141,7 @@ private module OperationResolution {
20992141
Type type, Trait trait, string name, int arity, ImplOrTraitItemNode i,
21002142
FunctionPositionType self
21012143
) {
2102-
MethodCallResolution::methodCandidate(type, name, arity, i, self) and
2144+
MethodCallResolution::methodCandidate(type, name, arity, i, self, _) and
21032145
(
21042146
trait = i.(ImplItemNode).resolveTraitTy()
21052147
or
@@ -2109,9 +2151,10 @@ private module OperationResolution {
21092151

21102152
pragma[nomagic]
21112153
predicate potentialInstantiationOf(Op op, TypeAbstraction abs, FunctionPositionType constraint) {
2112-
exists(Type type, Trait trait, string name, int arity |
2154+
exists(Type type, Trait trait, string name, int arity, Type selfType |
21132155
op.isOperation(type, trait, name, arity) and
2114-
MethodCallResolution::methodCandidate(type, name, arity, abs, constraint)
2156+
MethodCallResolution::methodCandidate(type, name, arity, abs, constraint, selfType) and
2157+
op.getTypeAt(_) = selfType
21152158
|
21162159
trait = abs.(ImplItemNode).resolveTraitTy()
21172160
or
@@ -3035,7 +3078,7 @@ private module Debug {
30353078
// filepath.matches("%/crates/wdk-macros/src/lib.rs") and
30363079
// endline = [255 .. 256]
30373080
filepath.matches("%/main.rs") and
3038-
startline = 2318
3081+
startline = 2317
30393082
)
30403083
}
30413084

rust/ql/test/library-tests/type-inference/type-inference.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6755,3 +6755,4 @@ inferType
67556755
| pattern_matching.rs:827:5:827:7 | f(...) | | {EXTERNAL LOCATION} | Option |
67566756
| pattern_matching.rs:827:5:827:7 | f(...) | T | file://:0:0:0:0 | () |
67576757
testFailures
6758+
| main.rs:2317:22:2317:43 | ...::my_from(...) | Unexpected result: target=MyFrom::my_from |

0 commit comments

Comments
 (0)