Skip to content

Commit 6f9a2f2

Browse files
committed
wip
1 parent 4852ae8 commit 6f9a2f2

File tree

3 files changed

+96
-93
lines changed

3 files changed

+96
-93
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,7 @@ final class ImplTraitTypeReprAbstraction extends TypeAbstraction, ImplTraitTypeR
630630
* Holds if `root` is a valid complex [`self` root type][1], with type
631631
* parameter `tp`.
632632
*
633-
* [1]: https://doc.rust-lang.org/stable/reference/items/associated-items.html?highlight=self#r-items.associated.fn.method.self-ty
633+
* [1]: https://doc.rust-lang.org/stable/reference/items/associated-items.html#r-items.associated.fn.method.self-ty
634634
*/
635635
pragma[nomagic]
636636
predicate complexSelfRoot(Type root, TypeParameter tp) {

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

Lines changed: 93 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -889,8 +889,9 @@ private predicate isComplexRootStripped(TypePath path, Type type) {
889889
* T1, &T1, &mut T1, ..., Tn, &Tn, &mut Tn
890890
* ```
891891
*
892-
* we recursively build up the list, only adding a new candidate receiver type to the list
893-
* when we can rule out that the method cannot be found for the current candidate:
892+
* we recursively compute a set of candidates, only adding a new candidate receiver type
893+
* to the set when we can rule out that the method cannot be found for the current
894+
* candidate:
894895
*
895896
* ```text
896897
* forall method:
@@ -1214,7 +1215,7 @@ private module MethodResolution {
12141215
* as long as the method cannot be resolved in an earlier candidate type, and possibly
12151216
* applying a borrow at the end.
12161217
*
1217-
* The string `derefChainBorrow` encodes the sequences of dereferences and whether a
1218+
* The string `derefChainBorrow` encodes the sequence of dereferences and whether a
12181219
* borrow has been applied.
12191220
*
12201221
* [1]: https://doc.rust-lang.org/reference/expressions/method-call-expr.html#r-expr.method.candidate-receivers
@@ -1302,14 +1303,14 @@ private module MethodResolution {
13021303
private class MethodCallCallExpr extends MethodCall, CallExpr {
13031304
MethodCallCallExpr() {
13041305
exists(getCallExprPathQualifier(this)) and
1305-
// even if a function cannot be resolved by path resolution, it may still
1306-
// be possible to resolve a blanket implementation
1306+
// even if a method cannot be resolved by path resolution, it may still
1307+
// be possible to resolve a blanket implementation (so not `forex`)
13071308
forall(ItemNode i | i = CallExprImpl::getResolvedFunction(this) | i instanceof Method)
13081309
}
13091310

13101311
/**
13111312
* Holds if this call has a type qualifier, and we are able to resolve,
1312-
* using path resolution, the function to a member of `impl`.
1313+
* using path resolution, the method to a member of `impl`.
13131314
*
13141315
* When this is the case, we still want to check that the type qualifier
13151316
* is an instance of the type being implemented, which is done in
@@ -1557,8 +1558,10 @@ private module MethodResolution {
15571558
ArgIsInstantiationOf<MethodCallCand, ReceiverIsInstantiationOfSelfParamInput>;
15581559

15591560
/**
1560-
* A configuration for matching the type qualifier of a function call against
1561-
* the type being implemented in an `impl` block.
1561+
* A configuration for matching the type qualifier of a method call
1562+
* against the type being implemented in an `impl` block. For example,
1563+
* in `Q::m(x)`, we check that the type of `Q` is an instance of the
1564+
* type being implemented.
15621565
*/
15631566
private module TypeQualifierIsInstantiationOfImplSelfInput implements
15641567
IsInstantiationOfInputSig<MethodCallCallExpr, TypeMentionTypeTree>
@@ -1897,91 +1900,11 @@ private module NonMethodResolution {
18971900

18981901
private module BlanketTraitIsVisible = TraitIsVisible<blanketCallTraitCandidate/2>;
18991902

1900-
private Type getTypeAt(NonMethodCall fc, FunctionTypePosition pos, TypePath path) {
1901-
result = inferType(fc.getNodeAt(pos), path)
1902-
}
1903-
1904-
pragma[nomagic]
1905-
private predicate functionCallBlanketCandidate(
1906-
NonMethodCall fc, NonMethodFunction f, ImplItemNode impl, FunctionTypePosition pos,
1907-
TypePath blanketPath, TypeParam blanketTypeParam
1908-
) {
1909-
exists(string name, int arity, Trait trait, AssocFunctionType t |
1910-
fc.hasNameAndArity(name, arity) and
1911-
exists(getTypeAt(fc, pos, blanketPath)) and
1912-
functionInfoBlanketRelevantPos(f, name, arity, impl, trait, pos, t, blanketPath,
1913-
blanketTypeParam) and
1914-
BlanketTraitIsVisible::traitIsVisible(fc, trait)
1915-
)
1916-
}
1917-
1918-
private newtype TCallAndPos =
1919-
MkCallAndPos(NonMethodCall fc, FunctionTypePosition pos) {
1920-
functionCallBlanketCandidate(fc, _, _, pos, _, _)
1921-
}
1922-
1923-
/** A call tagged with a position. */
1924-
private class CallAndPos extends MkCallAndPos {
1925-
NonMethodCall fc;
1926-
FunctionTypePosition pos;
1927-
1928-
CallAndPos() { this = MkCallAndPos(fc, pos) }
1929-
1930-
Location getLocation() { result = fc.getLocation() }
1931-
1932-
Type getTypeAt(TypePath path) { result = getTypeAt(fc, pos, path) }
1933-
1934-
string toString() { result = fc.toString() + " [arg " + pos + "]" }
1935-
}
1936-
1937-
private module ArgSatisfiesBlanketConstraintInput implements
1938-
BlanketImplementation::SatisfiesBlanketConstraintInputSig<CallAndPos>
1939-
{
1940-
pragma[nomagic]
1941-
predicate hasBlanketCandidate(
1942-
CallAndPos fcp, ImplItemNode impl, TypePath blanketPath, TypeParam blanketTypeParam
1943-
) {
1944-
exists(NonMethodCall fc, FunctionTypePosition pos |
1945-
fcp = MkCallAndPos(fc, pos) and
1946-
functionCallBlanketCandidate(fc, _, impl, pos, blanketPath, blanketTypeParam)
1947-
)
1948-
}
1949-
}
1950-
1951-
private module ArgSatisfiesBlanketConstraint =
1952-
BlanketImplementation::SatisfiesBlanketConstraint<CallAndPos, ArgSatisfiesBlanketConstraintInput>;
1953-
1954-
/**
1955-
* A configuration for matching the type of an argument against the type of
1956-
* a parameter that mentions a satisfied blanket type parameter.
1957-
*/
1958-
private module ArgIsInstantiationOfBlanketParamInput implements
1959-
IsInstantiationOfInputSig<CallAndPos, AssocFunctionType>
1960-
{
1961-
pragma[nomagic]
1962-
predicate potentialInstantiationOf(
1963-
CallAndPos fcp, TypeAbstraction abs, AssocFunctionType constraint
1964-
) {
1965-
exists(FunctionTypePosition pos |
1966-
ArgSatisfiesBlanketConstraint::satisfiesBlanketConstraint(fcp, abs) and
1967-
fcp = MkCallAndPos(_, pos) and
1968-
functionInfoBlanketRelevantPos(_, _, _, abs, _, pos, constraint, _, _)
1969-
)
1970-
}
1971-
1972-
predicate relevantTypeMention(AssocFunctionType constraint) {
1973-
functionInfoBlanketRelevantPos(_, _, _, _, _, _, constraint, _, _)
1974-
}
1975-
}
1976-
1977-
private module ArgIsInstantiationOfBlanketParam =
1978-
ArgIsInstantiationOf<CallAndPos, ArgIsInstantiationOfBlanketParamInput>;
1979-
19801903
/** A non-method call, `f(x)`. */
19811904
final class NonMethodCall extends CallExpr {
19821905
NonMethodCall() {
19831906
// even if a function cannot be resolved by path resolution, it may still
1984-
// be possible to resolve a blanket implementation
1907+
// be possible to resolve a blanket implementation (so not `forex`)
19851908
forall(Function f | f = CallExprImpl::getResolvedFunction(this) |
19861909
f instanceof NonMethodFunction
19871910
)
@@ -2009,7 +1932,7 @@ private module NonMethodResolution {
20091932
private NonMethodFunction resolveCallTargetBlanketCand(ImplItemNode impl) {
20101933
exists(string name |
20111934
this.hasNameAndArity(pragma[only_bind_into](name), _) and
2012-
ArgIsInstantiationOfBlanketParam::argIsInstantiationOf(MkCallAndPos(this, _), impl, _) and
1935+
ArgIsInstantiationOfBlanketParam::argIsInstantiationOf(MkCallAndBlanketPos(this, _), impl, _) and
20131936
result = impl.getASuccessor(pragma[only_bind_into](name))
20141937
)
20151938
}
@@ -2032,6 +1955,23 @@ private module NonMethodResolution {
20321955
result = this and pos.isReturn()
20331956
}
20341957

1958+
Type getTypeAt(FunctionTypePosition pos, TypePath path) {
1959+
result = inferType(this.getNodeAt(pos), path)
1960+
}
1961+
1962+
pragma[nomagic]
1963+
predicate resolveCallTargetBlanketCandidate(
1964+
ImplItemNode impl, FunctionTypePosition pos, TypePath blanketPath, TypeParam blanketTypeParam
1965+
) {
1966+
exists(string name, int arity, Trait trait, AssocFunctionType t |
1967+
this.hasNameAndArity(name, arity) and
1968+
exists(this.getTypeAt(pos, blanketPath)) and
1969+
functionInfoBlanketRelevantPos(_, name, arity, impl, trait, pos, t, blanketPath,
1970+
blanketTypeParam) and
1971+
BlanketTraitIsVisible::traitIsVisible(this, trait)
1972+
)
1973+
}
1974+
20351975
pragma[nomagic]
20361976
predicate hasTraitResolved(TraitItemNode trait, NonMethodFunction resolved) {
20371977
resolved = this.getPathResolutionResolved() and
@@ -2061,6 +2001,69 @@ private module NonMethodResolution {
20612001
}
20622002
}
20632003

2004+
private newtype TCallAndBlanketPos =
2005+
MkCallAndBlanketPos(NonMethodCall fc, FunctionTypePosition pos) {
2006+
fc.resolveCallTargetBlanketCandidate(_, pos, _, _)
2007+
}
2008+
2009+
/** A call tagged with a position. */
2010+
private class CallAndBlanketPos extends MkCallAndBlanketPos {
2011+
NonMethodCall fc;
2012+
FunctionTypePosition pos;
2013+
2014+
CallAndBlanketPos() { this = MkCallAndBlanketPos(fc, pos) }
2015+
2016+
Location getLocation() { result = fc.getLocation() }
2017+
2018+
Type getTypeAt(TypePath path) { result = fc.getTypeAt(pos, path) }
2019+
2020+
string toString() { result = fc.toString() + " [arg " + pos + "]" }
2021+
}
2022+
2023+
private module ArgSatisfiesBlanketConstraintInput implements
2024+
BlanketImplementation::SatisfiesBlanketConstraintInputSig<CallAndBlanketPos>
2025+
{
2026+
pragma[nomagic]
2027+
predicate hasBlanketCandidate(
2028+
CallAndBlanketPos fcp, ImplItemNode impl, TypePath blanketPath, TypeParam blanketTypeParam
2029+
) {
2030+
exists(NonMethodCall fc, FunctionTypePosition pos |
2031+
fcp = MkCallAndBlanketPos(fc, pos) and
2032+
fc.resolveCallTargetBlanketCandidate(impl, pos, blanketPath, blanketTypeParam)
2033+
)
2034+
}
2035+
}
2036+
2037+
private module ArgSatisfiesBlanketConstraint =
2038+
BlanketImplementation::SatisfiesBlanketConstraint<CallAndBlanketPos,
2039+
ArgSatisfiesBlanketConstraintInput>;
2040+
2041+
/**
2042+
* A configuration for matching the type of an argument against the type of
2043+
* a parameter that mentions a satisfied blanket type parameter.
2044+
*/
2045+
private module ArgIsInstantiationOfBlanketParamInput implements
2046+
IsInstantiationOfInputSig<CallAndBlanketPos, AssocFunctionType>
2047+
{
2048+
pragma[nomagic]
2049+
predicate potentialInstantiationOf(
2050+
CallAndBlanketPos fcp, TypeAbstraction abs, AssocFunctionType constraint
2051+
) {
2052+
exists(FunctionTypePosition pos |
2053+
ArgSatisfiesBlanketConstraint::satisfiesBlanketConstraint(fcp, abs) and
2054+
fcp = MkCallAndBlanketPos(_, pos) and
2055+
functionInfoBlanketRelevantPos(_, _, _, abs, _, pos, constraint, _, _)
2056+
)
2057+
}
2058+
2059+
predicate relevantTypeMention(AssocFunctionType constraint) {
2060+
functionInfoBlanketRelevantPos(_, _, _, _, _, _, constraint, _, _)
2061+
}
2062+
}
2063+
2064+
private module ArgIsInstantiationOfBlanketParam =
2065+
ArgIsInstantiationOf<CallAndBlanketPos, ArgIsInstantiationOfBlanketParamInput>;
2066+
20642067
private module NonMethodArgsAreInstantiationsOfInput implements ArgsAreInstantiationsOfInputSig {
20652068
predicate toCheck(
20662069
ImplOrTraitItemNode i, Function f, FunctionTypePosition pos, AssocFunctionType t

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,8 +394,8 @@ module ArgsAreInstantiationsOf<ArgsAreInstantiationsOfInputSig Input> {
394394
predicate potentialInstantiationOf(
395395
CallAndPos cp, TypeAbstraction abs, AssocFunctionType constraint
396396
) {
397-
exists(Input::Call call, FunctionTypePosition pos, int rnk, Function f |
398-
potentialInstantiationOf0(cp, call, pos, rnk, f, abs, constraint)
397+
exists(Input::Call call, int rnk, Function f |
398+
potentialInstantiationOf0(cp, call, _, rnk, f, abs, constraint)
399399
|
400400
rnk = 0
401401
or

0 commit comments

Comments
 (0)