Skip to content

Commit afabb67

Browse files
committed
wip
1 parent 485e994 commit afabb67

File tree

4 files changed

+139
-35
lines changed

4 files changed

+139
-35
lines changed

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

Lines changed: 117 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -871,11 +871,6 @@ private module FunctionOverloading {
871871
Impl impl, TraitItemNode trait, Type rootType, TypeMention selfTy
872872
) {
873873
trait = impl.(ImplItemNode).resolveTraitTy() and
874-
// If `impl` has an expansion from a macro attribute, then it's been
875-
// superseded by the output of the expansion (and usually the expansion
876-
// contains the same `impl` block so considering both would give spurious
877-
// siblings).
878-
not exists(impl.getAttributeMacroExpansion()) and
879874
selfTy = impl.getSelfTy() and
880875
rootType = selfTy.resolveType()
881876
}
@@ -1393,7 +1388,8 @@ private module MethodCallResolution {
13931388
Function m, string name, int arity, ImplItemNode i, FunctionType selfType, TypePath blanketPath,
13941389
TypeParam blanketTypeParam
13951390
) {
1396-
methodInfoTypeParam(m, name, arity, i, selfType, blanketPath, blanketTypeParam) and
1391+
methodInfo(m, name, arity, i, selfType, _, _) and
1392+
TTypeParamTypeParameter(blanketTypeParam) = selfType.getTypeAt(blanketPath) and
13971393
blanketTypeParam = i.getBlanketImplementationTypeParam()
13981394
}
13991395

@@ -1702,7 +1698,7 @@ private module MethodCallResolution {
17021698
}
17031699

17041700
pragma[nomagic]
1705-
predicate hasInfo(
1701+
predicate hasSignature(
17061702
MethodCall mc, TypePath strippedTypePath, Type strippedType, string name, int arity
17071703
) {
17081704
strippedType = this.getTypeAt(strippedTypePath) and
@@ -1728,7 +1724,7 @@ private module MethodCallResolution {
17281724
pragma[nomagic]
17291725
predicate hasNoInherentTarget() {
17301726
exists(TypePath strippedTypePath, Type strippedType, string name, int arity |
1731-
this.hasInfo(_, strippedTypePath, strippedType, name, arity) and
1727+
this.hasSignature(_, strippedTypePath, strippedType, name, arity) and
17321728
forall(Impl i |
17331729
methodInfoNonBlanket(_, name, arity, i, _, strippedTypePath, strippedType) and
17341730
not i.hasTrait()
@@ -1800,7 +1796,7 @@ private module MethodCallResolution {
18001796
MethodCallCand mcc, Function m, TypePath blanketPath, TypeParam blanketTypeParam
18011797
) {
18021798
exists(MethodCall mc, string name, int arity |
1803-
mcc.hasInfo(mc, _, _, name, arity) and
1799+
mcc.hasSignature(mc, _, _, name, arity) and
18041800
methodCallBlanketCandidate(mc, m, _, _, blanketPath, blanketTypeParam)
18051801
)
18061802
}
@@ -1821,7 +1817,7 @@ private module MethodCallResolution {
18211817
MethodCall mc, Function m, string name, int arity, TypePath strippedTypePath,
18221818
Type strippedType
18231819
|
1824-
mcc.hasInfo(mc, strippedTypePath, strippedType, name, arity)
1820+
mcc.hasSignature(mc, strippedTypePath, strippedType, name, arity)
18251821
|
18261822
methodCallNonBlanketCandidate(mc, m, abs, constraint, strippedTypePath, strippedType)
18271823
or
@@ -2035,7 +2031,21 @@ private Type inferMethodCallExprType(AstNode n, TypePath path) {
20352031
)
20362032
}
20372033

2038-
/** Provides logic for resolving function calls. */
2034+
/**
2035+
* Provides logic for resolving function calls.
2036+
*
2037+
* We distinguish between three cases:
2038+
*
2039+
* 1. The qualifier of the function call is _not_ a trait, and the function call
2040+
* can be resolved using path resolution. In this case we use the resolved
2041+
* function directly, we do not even check the receiver type in case the resolved
2042+
* function is a method.
2043+
*
2044+
* 2. The qualifier of the function call _is_ a trait, and the function call can be
2045+
* resolved using path resolution. In this case we use the resolved function
2046+
* directly, we do not even check the receiver type in case the resolved
2047+
* function is a method.
2048+
*/
20392049
private module FunctionCallResolution {
20402050
private import FunctionOverloading
20412051

@@ -2068,8 +2078,22 @@ private module FunctionCallResolution {
20682078

20692079
/** A function call, `f(x)`. */
20702080
final class FunctionCall extends CallExpr {
2071-
private ItemNode getPathResolutionResolvedFunction() {
2072-
result = CallExprImpl::getResolvedFunction(this)
2081+
pragma[nomagic]
2082+
predicate hasSignature(string name, int arity) {
2083+
name = CallExprImpl::getFunctionPath(this).getText() and
2084+
arity = this.getNumberOfArgs()
2085+
}
2086+
2087+
/**
2088+
* Gets the item that this function call resolves to using path resolution,
2089+
* if any.
2090+
*/
2091+
ItemNode getPathResolutionResolvedFunction() {
2092+
exists(string name, int arity |
2093+
this.hasSignature(name, arity) and
2094+
result = CallExprImpl::getResolvedFunction(this) and
2095+
result.(FunctionCallMatchingInput::Declaration).getArity() = arity
2096+
)
20732097
}
20742098

20752099
pragma[nomagic]
@@ -2078,7 +2102,7 @@ private module FunctionCallResolution {
20782102
}
20792103

20802104
pragma[nomagic]
2081-
predicate hasInfo(
2105+
predicate hasSignature(
20822106
TypePath strippedTypePath, Type strippedType, TraitItemNode trait, Function resolved
20832107
) {
20842108
this.getTypeAt(strippedTypePath) = strippedType and
@@ -2089,9 +2113,8 @@ private module FunctionCallResolution {
20892113

20902114
pragma[nomagic]
20912115
private Function getATargetMethodCand() {
2092-
exists(TraitItemNode trait, ImplOrTraitItemNode i, FunctionType self |
2093-
FunctionMethodCallIsInstantiationOfInput::potentialInstantiationOf(this, trait, i, self,
2094-
result) and
2116+
exists(ImplOrTraitItemNode i, FunctionType self |
2117+
FunctionMethodCallIsInstantiationOfInput::potentialInstantiationOf(this, i, self, result) and
20952118
IsInstantiationOf<FunctionCall, FunctionType, FunctionMethodCallIsInstantiationOfInput>::isInstantiationOf(this,
20962119
i, self)
20972120
)
@@ -2156,6 +2179,38 @@ private module FunctionCallResolution {
21562179
}
21572180
}
21582181

2182+
private module SatisfiesBlanketConstraintInput implements
2183+
MethodCallResolution::BlanketImplementation::SatisfiesBlanketConstraintInputSig<FunctionCall>
2184+
{
2185+
pragma[nomagic]
2186+
private predicate hasBlanketCandidate(
2187+
FunctionCall call, Trait trait, Function m, TypePath blanketPath, TypeParam blanketTypeParam
2188+
) {
2189+
not exists(call.getPathResolutionResolvedFunction()) and
2190+
exists(string name, int arity, ImplItemNode impl |
2191+
call.hasSignature(name, arity + 1) and
2192+
MethodCallResolution::methodInfoBlanket(m, name, arity, impl, _, blanketPath,
2193+
blanketTypeParam) and
2194+
trait = impl.resolveTraitTy()
2195+
)
2196+
}
2197+
2198+
pragma[nomagic]
2199+
private predicate functionCallTraitCandidate(Element mc, Trait trait) {
2200+
hasBlanketCandidate(mc, trait, _, _, _)
2201+
}
2202+
2203+
pragma[nomagic]
2204+
predicate hasBlanketCandidate(
2205+
FunctionCall call, Function m, TypePath blanketPath, TypeParam blanketTypeParam
2206+
) {
2207+
exists(Trait trait |
2208+
hasBlanketCandidate(call, trait, m, blanketPath, blanketTypeParam) and
2209+
TraitIsVisible<functionCallTraitCandidate/2>::traitIsVisible(call, trait)
2210+
)
2211+
}
2212+
}
2213+
21592214
/**
21602215
* A configuration for matching the type of the first argument in a function call
21612216
* against the type of a `self` parameter.
@@ -2195,15 +2250,21 @@ private module FunctionCallResolution {
21952250

21962251
pragma[nomagic]
21972252
additional predicate potentialInstantiationOf(
2198-
FunctionCall call, TraitItemNode trait, ImplOrTraitItemNode i, FunctionType selfType,
2199-
Function f
2253+
FunctionCall call, ImplOrTraitItemNode i, FunctionType selfType, Function f
22002254
) {
2201-
exists(Function resolved, TypePath strippedTypePath, Type strippedType |
2202-
call.hasInfo(strippedTypePath, strippedType, trait, resolved)
2203-
|
2204-
methodInfo(strippedTypePath, strippedType, trait, f, resolved)
2255+
(
2256+
exists(
2257+
TraitItemNode trait, Function resolved, TypePath strippedTypePath, Type strippedType
2258+
|
2259+
call.hasSignature(strippedTypePath, strippedType, trait, resolved)
2260+
|
2261+
methodInfo(strippedTypePath, strippedType, trait, f, resolved)
2262+
or
2263+
methodInfoTypeParam(strippedTypePath, trait, f, resolved)
2264+
)
22052265
or
2206-
methodInfoTypeParam(strippedTypePath, trait, f, resolved)
2266+
MethodCallResolution::BlanketImplementation::SatisfiesBlanketConstraint<FunctionCall, SatisfiesBlanketConstraintInput>::satisfiesBlanketConstraint(call,
2267+
f)
22072268
) and
22082269
MethodCallResolution::methodInfo(f, _, _, i, selfType, _, _)
22092270
}
@@ -2212,7 +2273,7 @@ private module FunctionCallResolution {
22122273
predicate potentialInstantiationOf(
22132274
FunctionCall call, TypeAbstraction abs, FunctionType constraint
22142275
) {
2215-
potentialInstantiationOf(call, _, abs, constraint, _)
2276+
potentialInstantiationOf(call, abs, constraint, _)
22162277
}
22172278

22182279
predicate relevantTypeMention(FunctionType constraint) {
@@ -2236,6 +2297,13 @@ private module FunctionCallMatchingInput implements MatchingInputSig {
22362297

22372298
abstract Type getReturnType(TypePath path);
22382299

2300+
int getArity() {
2301+
result =
2302+
count(DeclarationPosition dpos |
2303+
dpos.isPositional() and exists(this.getParameterType(dpos, _))
2304+
)
2305+
}
2306+
22392307
Type getDeclaredType(DeclarationPosition dpos, TypePath path) {
22402308
result = this.getParameterType(dpos, path)
22412309
or
@@ -2423,7 +2491,7 @@ private module OperationResolution {
24232491
Type getTypeAt(TypePath path) { result = substituteLookupTraits(this.getTypeAt0(path)) }
24242492

24252493
pragma[nomagic]
2426-
predicate hasInfo(
2494+
predicate hasSignature(
24272495
TypePath strippedTypePath, Type strippedType, Trait trait, string name, int arity
24282496
) {
24292497
name = this.(Call).getMethodName() and
@@ -2461,18 +2529,32 @@ private module OperationResolution {
24612529
}
24622530
}
24632531

2532+
private module SatisfiesBlanketConstraintInput implements
2533+
MethodCallResolution::BlanketImplementation::SatisfiesBlanketConstraintInputSig<Op>
2534+
{
2535+
pragma[nomagic]
2536+
predicate hasBlanketCandidate(
2537+
Op op, Function m, TypePath blanketPath, TypeParam blanketTypeParam
2538+
) {
2539+
exists(Trait trait, string name, int arity, ImplItemNode impl |
2540+
op.hasSignature(_, _, trait, name, arity) and
2541+
MethodCallResolution::methodInfoBlanket(m, name, arity, impl, _, blanketPath,
2542+
blanketTypeParam) and
2543+
trait = impl.resolveTraitTy()
2544+
)
2545+
}
2546+
}
2547+
24642548
private module OperationIsInstantiationOfInput implements
24652549
IsInstantiationOfInputSig<Op, FunctionType>
24662550
{
2467-
// todo
24682551
bindingset[strippedTypePath]
24692552
private predicate methodInfoNonBlanket(
24702553
TypeAbstraction abs, FunctionType constraint, Trait trait, string name, int arity,
24712554
TypePath strippedTypePath, Type strippedType
24722555
) {
24732556
MethodCallResolution::methodInfoNonBlanket(_, name, arity, abs, constraint, strippedTypePath,
24742557
strippedType) and
2475-
not abs.(ImplItemNode).isBlanketImplementation() and
24762558
(
24772559
trait = abs.(ImplItemNode).resolveTraitTy()
24782560
or
@@ -2483,9 +2565,15 @@ private module OperationResolution {
24832565
pragma[nomagic]
24842566
predicate potentialInstantiationOf(Op op, TypeAbstraction abs, FunctionType constraint) {
24852567
exists(Trait trait, string name, int arity, TypePath strippedTypePath, Type strippedType |
2486-
op.hasInfo(strippedTypePath, strippedType, trait, name, arity) and
2568+
op.hasSignature(strippedTypePath, strippedType, trait, name, arity) and
24872569
methodInfoNonBlanket(abs, constraint, trait, name, arity, strippedTypePath, strippedType)
24882570
)
2571+
or
2572+
exists(Function m |
2573+
MethodCallResolution::methodInfoBlanket(m, _, _, abs, constraint, _, _) and
2574+
MethodCallResolution::BlanketImplementation::SatisfiesBlanketConstraint<Op, SatisfiesBlanketConstraintInput>::satisfiesBlanketConstraint(op,
2575+
m)
2576+
)
24892577
}
24902578

24912579
predicate relevantTypeMention(FunctionType constraint) {

rust/ql/test/library-tests/type-inference/blanket_impl.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ mod basic_blanket_impl {
5151
println!("{x3:?}");
5252
let x4 = (&S1).duplicate(); // $ target=Clone1duplicate
5353
println!("{x4:?}");
54-
let x5 = S1::duplicate(&S1); // $ MISSING: target=Clone1duplicate
54+
let x5 = S1::duplicate(&S1); // $ target=Clone1duplicate
5555
println!("{x5:?}");
5656
let x6 = S2.duplicate(); // $ MISSING: target=Clone1duplicate
5757
println!("{x6:?}");
@@ -174,11 +174,11 @@ pub mod sql_exec {
174174
let c = MySqlConnection {}; // $ certainType=c:MySqlConnection
175175

176176
c.execute1(); // $ target=execute1
177-
MySqlConnection::execute1(&c); // $ MISSING: target=execute1
177+
MySqlConnection::execute1(&c); // $ target=execute1
178178

179179
c.execute2("SELECT * FROM users"); // $ target=execute2
180180
c.execute2::<&str>("SELECT * FROM users"); // $ target=execute2
181-
MySqlConnection::execute2(&c, "SELECT * FROM users"); // $ MISSING: target=execute2
182-
MySqlConnection::execute2::<&str>(&c, "SELECT * FROM users"); // $ MISSING: target=execute2
181+
MySqlConnection::execute2(&c, "SELECT * FROM users"); // $ target=execute2
182+
MySqlConnection::execute2::<&str>(&c, "SELECT * FROM users"); // $ target=execute2
183183
}
184184
}

rust/ql/test/library-tests/type-inference/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2630,10 +2630,10 @@ pub mod path_buf {
26302630
}
26312631
}
26322632

2633+
mod blanket_impl;
26332634
mod closure;
26342635
mod dereference;
26352636
mod dyn_type;
2636-
mod blanket_impl;
26372637

26382638
fn main() {
26392639
field_access::f(); // $ target=f

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,16 @@ inferType
6262
| blanket_impl.rs:53:18:53:25 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments |
6363
| blanket_impl.rs:53:18:53:25 | MacroExpr | | {EXTERNAL LOCATION} | Arguments |
6464
| blanket_impl.rs:53:20:53:21 | x4 | | blanket_impl.rs:6:5:7:14 | S1 |
65+
| blanket_impl.rs:54:13:54:14 | x5 | | blanket_impl.rs:6:5:7:14 | S1 |
66+
| blanket_impl.rs:54:18:54:35 | ...::duplicate(...) | | blanket_impl.rs:6:5:7:14 | S1 |
6567
| blanket_impl.rs:54:32:54:34 | &S1 | | file://:0:0:0:0 | & |
6668
| blanket_impl.rs:54:32:54:34 | &S1 | &T | blanket_impl.rs:6:5:7:14 | S1 |
6769
| blanket_impl.rs:54:33:54:34 | S1 | | blanket_impl.rs:6:5:7:14 | S1 |
6870
| blanket_impl.rs:55:18:55:25 | "{x5:?}\\n" | | file://:0:0:0:0 | & |
6971
| blanket_impl.rs:55:18:55:25 | "{x5:?}\\n" | &T | {EXTERNAL LOCATION} | str |
7072
| blanket_impl.rs:55:18:55:25 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments |
7173
| blanket_impl.rs:55:18:55:25 | MacroExpr | | {EXTERNAL LOCATION} | Arguments |
74+
| blanket_impl.rs:55:20:55:21 | x5 | | blanket_impl.rs:6:5:7:14 | S1 |
7275
| blanket_impl.rs:56:18:56:19 | S2 | | blanket_impl.rs:9:5:10:14 | S2 |
7376
| blanket_impl.rs:57:18:57:25 | "{x6:?}\\n" | | file://:0:0:0:0 | & |
7477
| blanket_impl.rs:57:18:57:25 | "{x6:?}\\n" | &T | {EXTERNAL LOCATION} | str |
@@ -958,7 +961,9 @@ inferType
958961
| invalid/main.rs:46:13:46:13 | b | | invalid/main.rs:21:5:22:20 | Num |
959962
| invalid/main.rs:46:17:46:23 | Num(...) | | invalid/main.rs:21:5:22:20 | Num |
960963
| invalid/main.rs:46:21:46:22 | 10 | | {EXTERNAL LOCATION} | i32 |
964+
| invalid/main.rs:47:13:47:13 | c | | invalid/main.rs:21:5:22:20 | Num |
961965
| invalid/main.rs:47:17:47:17 | a | | invalid/main.rs:21:5:22:20 | Num |
966+
| invalid/main.rs:47:17:47:21 | ... + ... | | invalid/main.rs:21:5:22:20 | Num |
962967
| invalid/main.rs:47:21:47:21 | b | | invalid/main.rs:21:5:22:20 | Num |
963968
| main.rs:26:13:26:13 | x | | main.rs:5:5:8:5 | MyThing |
964969
| main.rs:26:17:26:32 | MyThing {...} | | main.rs:5:5:8:5 | MyThing |
@@ -3519,14 +3524,22 @@ inferType
35193524
| main.rs:1706:13:1709:13 | Vec2 {...} | | main.rs:1586:5:1591:5 | Vec2 |
35203525
| main.rs:1707:20:1707:23 | self | | main.rs:1586:5:1591:5 | Vec2 |
35213526
| main.rs:1707:20:1707:25 | self.x | | {EXTERNAL LOCATION} | i64 |
3527+
| main.rs:1707:20:1707:33 | ... \| ... | | {EXTERNAL LOCATION} | NonZero |
35223528
| main.rs:1707:20:1707:33 | ... \| ... | | {EXTERNAL LOCATION} | i64 |
3529+
| main.rs:1707:20:1707:33 | ... \| ... | T | {EXTERNAL LOCATION} | i64 |
35233530
| main.rs:1707:29:1707:31 | rhs | | main.rs:1586:5:1591:5 | Vec2 |
3531+
| main.rs:1707:29:1707:33 | rhs.x | | {EXTERNAL LOCATION} | NonZero |
35243532
| main.rs:1707:29:1707:33 | rhs.x | | {EXTERNAL LOCATION} | i64 |
3533+
| main.rs:1707:29:1707:33 | rhs.x | T | {EXTERNAL LOCATION} | i64 |
35253534
| main.rs:1708:20:1708:23 | self | | main.rs:1586:5:1591:5 | Vec2 |
35263535
| main.rs:1708:20:1708:25 | self.y | | {EXTERNAL LOCATION} | i64 |
3536+
| main.rs:1708:20:1708:33 | ... \| ... | | {EXTERNAL LOCATION} | NonZero |
35273537
| main.rs:1708:20:1708:33 | ... \| ... | | {EXTERNAL LOCATION} | i64 |
3538+
| main.rs:1708:20:1708:33 | ... \| ... | T | {EXTERNAL LOCATION} | i64 |
35283539
| main.rs:1708:29:1708:31 | rhs | | main.rs:1586:5:1591:5 | Vec2 |
3540+
| main.rs:1708:29:1708:33 | rhs.y | | {EXTERNAL LOCATION} | NonZero |
35293541
| main.rs:1708:29:1708:33 | rhs.y | | {EXTERNAL LOCATION} | i64 |
3542+
| main.rs:1708:29:1708:33 | rhs.y | T | {EXTERNAL LOCATION} | i64 |
35303543
| main.rs:1714:25:1714:33 | SelfParam | | file://:0:0:0:0 | & |
35313544
| main.rs:1714:25:1714:33 | SelfParam | &T | main.rs:1586:5:1591:5 | Vec2 |
35323545
| main.rs:1714:36:1714:38 | rhs | | main.rs:1586:5:1591:5 | Vec2 |
@@ -3872,9 +3885,13 @@ inferType
38723885
| main.rs:1863:26:1863:30 | 33i64 | | {EXTERNAL LOCATION} | i64 |
38733886
| main.rs:1863:26:1863:38 | ... & ... | | {EXTERNAL LOCATION} | i64 |
38743887
| main.rs:1863:34:1863:38 | 34i64 | | {EXTERNAL LOCATION} | i64 |
3888+
| main.rs:1864:13:1864:21 | i64_bitor | | {EXTERNAL LOCATION} | NonZero |
38753889
| main.rs:1864:13:1864:21 | i64_bitor | | {EXTERNAL LOCATION} | i64 |
3890+
| main.rs:1864:13:1864:21 | i64_bitor | T | {EXTERNAL LOCATION} | i64 |
38763891
| main.rs:1864:25:1864:29 | 35i64 | | {EXTERNAL LOCATION} | i64 |
3892+
| main.rs:1864:25:1864:37 | ... \| ... | | {EXTERNAL LOCATION} | NonZero |
38773893
| main.rs:1864:25:1864:37 | ... \| ... | | {EXTERNAL LOCATION} | i64 |
3894+
| main.rs:1864:25:1864:37 | ... \| ... | T | {EXTERNAL LOCATION} | i64 |
38783895
| main.rs:1864:33:1864:37 | 36i64 | | {EXTERNAL LOCATION} | i64 |
38793896
| main.rs:1865:13:1865:22 | i64_bitxor | | {EXTERNAL LOCATION} | i64 |
38803897
| main.rs:1865:26:1865:30 | 37i64 | | {EXTERNAL LOCATION} | i64 |
@@ -6924,4 +6941,3 @@ inferType
69246941
| pattern_matching.rs:827:5:827:7 | f(...) | | {EXTERNAL LOCATION} | Option |
69256942
| pattern_matching.rs:827:5:827:7 | f(...) | T | file://:0:0:0:0 | () |
69266943
testFailures
6927-
| invalid/main.rs:47:24:47:45 | //... | Missing result: target=BlanketAdd |

0 commit comments

Comments
 (0)