Skip to content

Commit 43c075e

Browse files
committed
wip2
1 parent c58c696 commit 43c075e

File tree

4 files changed

+62
-25
lines changed

4 files changed

+62
-25
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ module Impl {
4747
*/
4848
TypeBound getATypeBound() { result = this.getTypeBound(_) }
4949

50+
/** Holds if this type parameter has at least one type bound. */
51+
predicate hasTypeBound() { exists(this.getATypeBound()) }
52+
5053
override string toAbbreviatedString() { result = this.getName().getText() }
5154

5255
override string toStringImpl() { result = this.getName().getText() }

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

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,7 @@ private predicate functionInfoBlanket(
840840
) {
841841
functionInfo(f, name, arity, impl, pos, t) and
842842
TTypeParamTypeParameter(blanketTypeParam) = t.getTypeAt(blanketPath) and
843-
blanketTypeParam = impl.getBlanketImplementationTypeParam() and
843+
MethodResolution::isBlanketLike(impl, blanketTypeParam) and
844844
trait = impl.resolveTraitTy()
845845
}
846846

@@ -991,6 +991,17 @@ private module MethodResolution {
991991
methodInfo(m, name, arity, i, selfType, strippedTypePath, TTypeParamTypeParameter(tp))
992992
}
993993

994+
predicate isBlanketLike(ImplItemNode i, TypeParam tp) {
995+
tp = i.getBlanketImplementationTypeParam()
996+
// or
997+
// exists(TypeMention tm, Type root, TypeParameter tp0 |
998+
// tm = i.(Impl).getSelfTy() and
999+
// complexSelfRoot(root, tp0) and
1000+
// tm.resolveType() = root and
1001+
// tm.resolveTypeAt(TypePath::singleton(tp0)) = TTypeParamTypeParameter(tp)
1002+
// )
1003+
}
1004+
9941005
/**
9951006
* Same as `methodInfo`, but restricted to non-blanket implementations, and
9961007
* allowing for any `strippedType` when the corresponding type inside `m` is
@@ -1005,7 +1016,7 @@ private module MethodResolution {
10051016
methodInfo(m, name, arity, i, selfType, strippedTypePath, strippedType) or
10061017
methodInfoTypeParam(m, name, arity, i, selfType, strippedTypePath, _)
10071018
) and
1008-
not i.(ImplItemNode).isBlanketImplementation()
1019+
not isBlanketLike(i, _)
10091020
}
10101021

10111022
/**
@@ -1193,6 +1204,10 @@ private module MethodResolution {
11931204
private predicate hasIncompatibleTarget(ImplOrTraitItemNode i, string derefChainBorrow) {
11941205
ArgIsInstantiationOf<MethodCallCand, MethodCallReceiverIsInstantiationOfInput>::argIsNotInstanceOf(MkMethodCallCand(this,
11951206
derefChainBorrow), i, _)
1207+
or
1208+
IsInstantiationOf<MethodCallCallExpr, TypeMentionTypeTree, MethodCallCallExprIsInstantiationOfInput>::isNotInstantiationOf(this,
1209+
i, _) and
1210+
derefChainBorrow = ";"
11961211
}
11971212

11981213
/**
@@ -1226,6 +1241,8 @@ private module MethodResolution {
12261241
// todo: also check that all blanket implementation candidates are incompatible
12271242
forall(ImplOrTraitItemNode i |
12281243
methodCallNonBlanketCandidate(this, _, i, _, strippedTypePath, strippedType)
1244+
or
1245+
CallExprImpl::getResolvedFunction(this) = i.(ImplItemNode).getASuccessor(_)
12291246
|
12301247
this.hasIncompatibleTarget(i, derefChainBorrow)
12311248
)
@@ -1247,6 +1264,8 @@ private module MethodResolution {
12471264
// todo: also check that all blanket implementation candidates are incompatible
12481265
forall(ImplOrTraitItemNode i |
12491266
methodCallNonBlanketCandidate(this, _, i, _, strippedTypePath, strippedType)
1267+
or
1268+
CallExprImpl::getResolvedFunction(this) = i.(ImplItemNode).getASuccessor(_)
12501269
|
12511270
this.hasIncompatibleTarget(i, derefChainBorrow)
12521271
)
@@ -1405,10 +1424,9 @@ private module MethodResolution {
14051424
override predicate supportsAutoDerefAndBorrow() { none() }
14061425
}
14071426

1408-
bindingset[item, name]
1409-
pragma[inline_late]
1410-
private Method getMethodSuccessor(ItemNode item, string name, int arity) {
1411-
result = item.getASuccessor(name) and
1427+
pragma[nomagic]
1428+
private Method getMethodSuccessor(ImplOrTraitItemNode i, string name, int arity) {
1429+
result = i.getASuccessor(name) and
14121430
arity = result.getParamList().getNumberOfParams()
14131431
}
14141432

@@ -1475,16 +1493,22 @@ private module MethodResolution {
14751493
}
14761494

14771495
pragma[nomagic]
1478-
private Method resolveCallTargetCand(ImplOrTraitItemNode i) {
1479-
exists(string name |
1496+
private predicate argIsInstanceOf(ImplOrTraitItemNode i, string name, int arity) {
1497+
(
14801498
ArgIsInstantiationOf<MethodCallCand, MethodCallReceiverIsInstantiationOfInput>::argIsInstanceOf(this,
14811499
i, _)
14821500
or
14831501
IsInstantiationOf<MethodCallCallExpr, TypeMentionTypeTree, MethodCallCallExprIsInstantiationOfInput>::isInstantiationOf(mc_,
14841502
i, _)
1485-
|
1486-
mc_.hasNameAndArity(name, _) and
1487-
result = getMethodSuccessor(i, name, _)
1503+
) and
1504+
mc_.hasNameAndArity(name, arity)
1505+
}
1506+
1507+
pragma[nomagic]
1508+
private Method resolveCallTargetCand(ImplOrTraitItemNode i) {
1509+
exists(string name, int arity |
1510+
this.argIsInstanceOf(i, name, arity) and
1511+
result = getMethodSuccessor(i, name, arity)
14881512
)
14891513
}
14901514

@@ -1881,13 +1905,21 @@ private module AssocFunctionResolution {
18811905
)
18821906
}
18831907

1908+
private Type getTypeAt(AssocFunctionCall fc, FunctionTypePosition pos, TypePath path) {
1909+
result = inferType(fc.getArg(pos.asPositional()), path)
1910+
or
1911+
pos.isReturn() and
1912+
result = inferType(fc, path)
1913+
}
1914+
18841915
pragma[nomagic]
18851916
private predicate functionCallBlanketCandidate(
18861917
AssocFunctionCall fc, AssocFunction f, FunctionTypePosition pos, TypePath blanketPath,
18871918
TypeParam blanketTypeParam
18881919
) {
18891920
exists(string name, int arity, ImplItemNode impl, Trait trait, FunctionType t |
18901921
fc.hasNameAndArity(name, arity) and
1922+
exists(getTypeAt(fc, pos, blanketPath)) and
18911923
functionInfoBlanketRelevantPos(f, name, arity, impl, trait, pos, t, blanketPath,
18921924
blanketTypeParam) and
18931925
TraitIsVisible<blanketCallTraitCandidate/2>::traitIsVisible(fc, trait)
@@ -1907,12 +1939,7 @@ private module AssocFunctionResolution {
19071939

19081940
Location getLocation() { result = fc.getLocation() }
19091941

1910-
Type getTypeAt(TypePath path) {
1911-
result = inferType(fc.getArg(pos.asPositional()), path)
1912-
or
1913-
pos.isReturn() and
1914-
result = inferType(fc, path)
1915-
}
1942+
Type getTypeAt(TypePath path) { result = getTypeAt(fc, pos, path) }
19161943

19171944
string toString() { result = fc.toString() + " [arg " + pos + "]" }
19181945
}
@@ -3048,12 +3075,12 @@ import Cached
30483075
Type inferType(AstNode n) { result = inferType(n, TypePath::nil()) }
30493076

30503077
/** Provides predicates for debugging the type inference implementation. */
3051-
private module Debug {
3078+
module Debug {
30523079
Locatable getRelevantLocatable() {
30533080
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
30543081
result.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
3055-
filepath.matches("%/blanket_impl.rs") and
3056-
startline = 96
3082+
filepath.matches("%/sqlx.rs") and
3083+
startline = 246
30573084
)
30583085
}
30593086

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ private import codeql.rust.internal.TypeInference
1515
* `traitBound` is the first non-trivial trait bound of `tp`.
1616
*/
1717
pragma[nomagic]
18-
private predicate blanketImplementationTraitBound(TypeParamItemNode tp, Trait traitBound) {
19-
tp = any(ImplItemNode impl).getBlanketImplementationTypeParam() and
18+
private predicate hasFirstNonTrivialTraitBound(TypeParamItemNode tp, Trait traitBound) {
2019
traitBound =
2120
min(Trait trait, int i |
2221
trait = tp.resolveBound(i) and
@@ -50,7 +49,8 @@ module SatisfiesBlanketConstraint<
5049
{
5150
private newtype TArgumentTypeAndBlanketOffset =
5251
MkArgumentTypeAndBlanketOffset(ArgumentType at, TypePath blanketPath) {
53-
Input::hasBlanketCandidate(at, _, blanketPath, _)
52+
Input::hasBlanketCandidate(at, _, blanketPath, _) and
53+
exists(at.getTypeAt(blanketPath))
5454
}
5555

5656
private class ArgumentTypeAndBlanketOffset extends MkArgumentTypeAndBlanketOffset {
@@ -76,7 +76,7 @@ module SatisfiesBlanketConstraint<
7676
exists(ArgumentType at, TypePath blanketPath, TypeParam blanketTypeParam |
7777
ato = MkArgumentTypeAndBlanketOffset(at, blanketPath) and
7878
Input::hasBlanketCandidate(at, f, blanketPath, blanketTypeParam) and
79-
blanketImplementationTraitBound(blanketTypeParam, traitBound)
79+
hasFirstNonTrivialTraitBound(blanketTypeParam, traitBound)
8080
)
8181
}
8282

@@ -90,7 +90,7 @@ module SatisfiesBlanketConstraint<
9090

9191
/**
9292
* Holds if the argument type `at` satisfies the first non-trivial blanket
93-
* constraint of the function `f`.
93+
* constraint of the function `f`, if such a constraint exists.
9494
*/
9595
pragma[nomagic]
9696
predicate satisfiesBlanketConstraint(ArgumentType at, Function f) {
@@ -100,5 +100,11 @@ module SatisfiesBlanketConstraint<
100100
SatisfiesConstraint<ArgumentTypeAndBlanketOffset, SatisfiesBlanketConstraintInput>::satisfiesConstraintType(ato,
101101
TTrait(traitBound), _, _)
102102
)
103+
or
104+
exists(TypePath blanketPath, TypeParam blanketTypeParam |
105+
Input::hasBlanketCandidate(at, f, blanketPath, blanketTypeParam) and
106+
exists(at.getTypeAt(blanketPath)) and
107+
not hasFirstNonTrivialTraitBound(blanketTypeParam, _)
108+
)
103109
}
104110
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7102,3 +7102,4 @@ inferType
71027102
| pattern_matching.rs:827:5:827:7 | f(...) | | {EXTERNAL LOCATION} | Option |
71037103
| pattern_matching.rs:827:5:827:7 | f(...) | T | file://:0:0:0:0 | () |
71047104
testFailures
7105+
| main.rs:2566:20:2566:32 | ... .into() | Fixed missing result: target=into |

0 commit comments

Comments
 (0)