Skip to content

Commit b457a4d

Browse files
committed
wip2
1 parent 32e3727 commit b457a4d

File tree

4 files changed

+80
-48
lines changed

4 files changed

+80
-48
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -963,7 +963,9 @@ final class TraitItemNode extends ImplOrTraitItemNode, TypeItemNode instanceof T
963963
Path getABoundPath() { result = super.getATypeBound().getTypeRepr().(PathTypeRepr).getPath() }
964964

965965
pragma[nomagic]
966-
ItemNode resolveABound() { result = resolvePath(this.getABoundPath()) }
966+
ItemNode resolveBound(Path path) { path = this.getABoundPath() and result = resolvePath(path) }
967+
968+
ItemNode resolveABound() { result = this.resolveBound(_) }
967969

968970
override AssocItemNode getAnAssocItem() { result = this.getADescendant() }
969971

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

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -991,8 +991,10 @@ private module MethodResolution {
991991
)
992992
}
993993

994+
private module MethodTraitIsVisible = TraitIsVisible<methodCallTraitCandidate/2>;
995+
994996
private predicate methodCallVisibleTraitCandidate(MethodCall mc, Trait trait) {
995-
TraitIsVisible<methodCallTraitCandidate/2>::traitIsVisible(mc, trait)
997+
MethodTraitIsVisible::traitIsVisible(mc, trait)
996998
}
997999

9981000
bindingset[mc, impl]
@@ -1820,33 +1822,33 @@ private Type inferMethodCallType(AstNode n, TypePath path) {
18201822
* "calls" to tuple variants and tuple structs.
18211823
*/
18221824
private module NonMethodResolution {
1823-
private import FunctionOverloading
1824-
18251825
/**
1826-
* Holds if the associated function `implFunction` implements `traitFunction`,
1827-
* which belongs to `trait`, and resolving the function `implFunction` requires
1828-
* inspecting the type of applied _arguments_ at position `pos` in order to
1829-
* determine whether it is the correct resolution.
1826+
* Holds if the associated function `implFunction` at `impl` implements
1827+
* `traitFunction`, which belongs to `trait`, and resolving the function
1828+
* `implFunction` requires inspecting the type of applied _arguments_ at
1829+
* position `pos` in order to determine whether it is the correct resolution.
18301830
*
18311831
* `type` is the type at `pos` of `implFunction` which mathces a type parameter of
18321832
* `traitFunction` at `pos`.
18331833
*/
18341834
pragma[nomagic]
18351835
private predicate traitFunctionDependsOnArgument(
18361836
TraitItemNode trait, NonMethodFunction traitFunction, FunctionTypePosition pos, Type type,
1837-
NonMethodFunction implFunction
1837+
ImplItemNode impl, NonMethodFunction implFunction
18381838
) {
18391839
exists(TypePath path |
1840-
functionTypeAtPath(implFunction, pos, path, type) and
1840+
functionTypeAtPath(implFunction, impl, pos, path, type) and
18411841
implFunction.implements(traitFunction) and
1842-
traitTypeParameterOccurrence(trait, traitFunction, _, pos, path, _)
1842+
FunctionOverloading::traitTypeParameterOccurrence(trait, traitFunction, _, pos, path, _)
18431843
|
18441844
not pos.isReturn()
18451845
or
18461846
// We only check that the context of the call provides relevant type information
18471847
// when no argument can
18481848
not exists(FunctionTypePosition pos0 |
1849-
traitTypeParameterOccurrence(trait, traitFunction, _, pos0, _, _) and
1849+
FunctionOverloading::traitTypeParameterOccurrence(trait, traitFunction, _, pos0, _, _) or
1850+
FunctionOverloading::functionResolutionDependsOnArgument(impl, implFunction, pos0, _, _)
1851+
|
18501852
not pos0.isReturn()
18511853
)
18521854
)
@@ -1882,6 +1884,8 @@ private module NonMethodResolution {
18821884
)
18831885
}
18841886

1887+
private module BlanketTraitIsVisible = TraitIsVisible<blanketCallTraitCandidate/2>;
1888+
18851889
private Type getTypeAt(NonMethodCall fc, FunctionTypePosition pos, TypePath path) {
18861890
result = inferType(fc.getNodeAt(pos), path)
18871891
}
@@ -1896,7 +1900,7 @@ private module NonMethodResolution {
18961900
exists(getTypeAt(fc, pos, blanketPath)) and
18971901
functionInfoBlanketRelevantPos(f, name, arity, impl, trait, pos, t, blanketPath,
18981902
blanketTypeParam) and
1899-
TraitIsVisible<blanketCallTraitCandidate/2>::traitIsVisible(fc, trait)
1903+
BlanketTraitIsVisible::traitIsVisible(fc, trait)
19001904
)
19011905
}
19021906

@@ -2022,7 +2026,7 @@ private module NonMethodResolution {
20222026
pragma[nomagic]
20232027
private NonMethodFunction resolveCallTargetRec() {
20242028
result = this.resolveCallTargetBlanketCand(_) and
2025-
not functionResolutionDependsOnArgument(_, result, _, _, _)
2029+
not FunctionOverloading::functionResolutionDependsOnArgument(_, result, _, _, _)
20262030
or
20272031
NonMethodArgsAreInstantiationsOf::argsAreInstantiationsOf(this, _, result)
20282032
}
@@ -2031,7 +2035,7 @@ private module NonMethodResolution {
20312035
ItemNode resolveCallTargetNonRec() {
20322036
not this.(Call).hasTrait() and
20332037
result = this.getPathResolutionResolved() and
2034-
not functionResolutionDependsOnArgument(_, result, _, _, _)
2038+
not FunctionOverloading::functionResolutionDependsOnArgument(_, result, _, _, _)
20352039
}
20362040

20372041
pragma[inline]
@@ -2054,12 +2058,13 @@ private module NonMethodResolution {
20542058
|
20552059
FunctionOverloading::functionResolutionDependsOnArgument(i, f, pos, _, t0)
20562060
or
2057-
traitFunctionDependsOnArgument(_, _, pos, t0, f)
2061+
traitFunctionDependsOnArgument(_, _, pos, t0, i, f)
20582062
)
20592063
or
20602064
// match against the trait function itself
20612065
exists(Trait trait |
2062-
traitTypeParameterOccurrence(trait, f, _, pos, _, TSelfTypeParameter(trait))
2066+
FunctionOverloading::traitTypeParameterOccurrence(trait, f, _, pos, _,
2067+
TSelfTypeParameter(trait))
20632068
)
20642069
)
20652070
}
@@ -2072,14 +2077,15 @@ private module NonMethodResolution {
20722077
predicate hasTargetCand(ImplOrTraitItemNode i, Function f) {
20732078
f = this.resolveAssocCallTargetCand(i)
20742079
or
2075-
exists(TraitItemNode trait, NonMethodFunction resolved, Function f1 |
2080+
exists(TraitItemNode trait, NonMethodFunction resolved, ImplItemNode i1, Function f1 |
20762081
this.hasTraitResolved(trait, resolved) and
2077-
traitFunctionDependsOnArgument(trait, resolved, _, _, f1) and
2078-
f = i.getASuccessor(_)
2082+
traitFunctionDependsOnArgument(trait, resolved, _, _, i1, f1)
20792083
|
2080-
f = f1
2084+
f = f1 and
2085+
i = i1
20812086
or
2082-
f = resolved
2087+
f = resolved and
2088+
i = trait
20832089
)
20842090
}
20852091
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ predicate traitTypeParameterOccurrence(
7878
TraitItemNode trait, Function f, string functionName, FunctionTypePosition pos, TypePath path,
7979
TypeParameter tp
8080
) {
81-
f = trait.getAssocItem(functionName) and
82-
functionTypeAtPath(f, pos, path, tp) and
81+
f = trait.getASuccessor(functionName) and
82+
functionTypeAtPath(f, trait, pos, path, tp) and
8383
tp = trait.(TraitTypeAbstraction).getATypeParameter()
8484
}
8585

@@ -120,7 +120,7 @@ predicate functionResolutionDependsOnArgument(
120120
exists(TraitItemNode trait, string functionName |
121121
implHasSibling(impl, trait) and
122122
traitTypeParameterOccurrence(trait, _, functionName, pos, path, _) and
123-
functionTypeAtPath(f, pos, path, type) and
123+
functionTypeAtPath(f, impl, pos, path, type) and
124124
f = impl.getASuccessor(functionName) and
125125
not pos.isReturn()
126126
)

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

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,6 @@ class FunctionTypePosition extends TFunctionTypePosition {
5757
}
5858
}
5959

60-
pragma[nomagic]
61-
predicate functionTypeAtPath(Function f, FunctionTypePosition pos, TypePath path, Type type) {
62-
type = pos.getTypeMention(f).resolveTypeAt(path)
63-
}
64-
6560
/**
6661
* A helper module for implementing `Matching(WithEnvironment)InputSig` with
6762
* `DeclarationPosition = AccessPosition = FunctionTypePosition`.
@@ -82,15 +77,17 @@ private newtype TFunctionType =
8277
exists(pos.getTypeMention(f))
8378
} or
8479
MkInheritedFunctionType(
85-
Function f, FunctionTypePosition pos, ImplOrTraitItemNode parent, ImplOrTraitItemNode i
80+
Function f, FunctionTypePosition pos, TypeMention parentMention, ImplOrTraitItemNode parent,
81+
ImplOrTraitItemNode i
8682
) {
8783
exists(FunctionType inherited |
8884
inherited.appliesTo(f, pos, parent) and
8985
f = i.getASuccessor(_)
9086
|
91-
parent = i.(ImplItemNode).resolveTraitTy()
87+
parent = i.(ImplItemNode).resolveTraitTy() and
88+
parentMention = i.(ImplItemNode).getTraitPath()
9289
or
93-
parent = i.(TraitItemNode).resolveABound()
90+
parent = i.(TraitItemNode).resolveBound(parentMention)
9491
)
9592
}
9693

@@ -135,9 +132,10 @@ class FunctionType extends TFunctionType {
135132
}
136133

137134
private predicate isInheritedFunctionType(
138-
Function f, FunctionTypePosition pos, ImplOrTraitItemNode parent, ImplOrTraitItemNode i
135+
Function f, FunctionTypePosition pos, TypeMention parentMention, ImplOrTraitItemNode parent,
136+
ImplOrTraitItemNode i
139137
) {
140-
this = MkInheritedFunctionType(f, pos, parent, i)
138+
this = MkInheritedFunctionType(f, pos, parentMention, parent, i)
141139
}
142140

143141
/**
@@ -147,37 +145,49 @@ class FunctionType extends TFunctionType {
147145
predicate appliesTo(Function f, FunctionTypePosition pos, ImplOrTraitItemNode i) {
148146
this.isFunctionType(f, pos, i)
149147
or
150-
this.isInheritedFunctionType(f, pos, _, i)
148+
this.isInheritedFunctionType(f, pos, _, _, i)
151149
}
152150

151+
/**
152+
* Gets the type of this function at the given position and path.
153+
*/
153154
pragma[nomagic]
154-
private Type getTypeAt0(TypePath path) {
155+
Type getDeclaredTypeAt(TypePath path) {
155156
exists(Function f, FunctionTypePosition pos |
156157
this.isFunctionType(f, pos, _) and
157-
functionTypeAtPath(f, pos, path, result)
158+
result = pos.getTypeMention(f).resolveTypeAt(path)
158159
)
159160
or
160161
exists(
161-
Function f, FunctionTypePosition pos, FunctionType parentType, ImplOrTraitItemNode parent,
162-
ImplOrTraitItemNode i
162+
Function f, FunctionTypePosition pos, TypeMention parentMention, ImplOrTraitItemNode parent,
163+
FunctionType parentType, ImplOrTraitItemNode i
163164
|
164-
this.isInheritedFunctionType(f, pos, parent, i) and
165+
this.isInheritedFunctionType(f, pos, parentMention, parent, i) and
165166
parentType.appliesTo(f, pos, parent)
166167
|
167-
result = parentType.getTypeAt0(path) and
168-
not result instanceof TSelfTypeParameter
168+
result = parentType.getDeclaredTypeAt(path) and
169+
not result instanceof TypeParameter
169170
or
170-
exists(TypePath prefix, TypePath suffix |
171+
exists(TypePath prefix, TypePath suffix | path = prefix.append(suffix) |
171172
parentType.hasSelfTypeParameterAt(prefix) and
172-
result = resolveImplOrTraitType(i, suffix) and
173-
path = prefix.append(suffix)
173+
result = resolveImplOrTraitType(i, suffix)
174+
or
175+
exists(TypeParameter tp |
176+
parentType.hasTypeParameterAt(prefix, tp) and
177+
result = parentMention.resolveTypeAt(TypePath::singleton(tp).appendInverse(suffix))
178+
)
174179
)
175180
)
176181
}
177182

183+
pragma[nomagic]
184+
private predicate hasTypeParameterAt(TypePath path, TypeParameter tp) {
185+
this.getDeclaredTypeAt(path) = tp
186+
}
187+
178188
pragma[nomagic]
179189
private predicate hasSelfTypeParameterAt(TypePath path) {
180-
this.getTypeAt0(path) = TSelfTypeParameter(_)
190+
this.hasTypeParameterAt(path, TSelfTypeParameter(_))
181191
}
182192

183193
/**
@@ -190,7 +200,7 @@ class FunctionType extends TFunctionType {
190200
* traits when matching.
191201
*/
192202
Type getTypeAt(TypePath path) {
193-
exists(Type t | t = this.getTypeAt0(path) |
203+
exists(Type t | t = this.getDeclaredTypeAt(path) |
194204
not t instanceof SelfTypeParameter and
195205
result = t
196206
or
@@ -220,6 +230,20 @@ class FunctionType extends TFunctionType {
220230
Location getLocation() { result = this.getReportingNode().getLocation() }
221231
}
222232

233+
/**
234+
* Holds if the type of the function `f` at position `pos` and path `path` inside
235+
* `i` is `type`.
236+
*/
237+
pragma[nomagic]
238+
predicate functionTypeAtPath(
239+
Function f, ImplOrTraitItemNode i, FunctionTypePosition pos, TypePath path, Type type
240+
) {
241+
exists(FunctionType ft |
242+
ft.appliesTo(f, pos, i) and
243+
type = ft.getDeclaredTypeAt(path)
244+
)
245+
}
246+
223247
private Trait getALookupTrait(Type t) {
224248
result = t.(TypeParamTypeParameter).getTypeParam().(TypeParamItemNode).resolveABound()
225249
or

0 commit comments

Comments
 (0)