Skip to content

Commit f65e02c

Browse files
committed
wip5
1 parent f36d707 commit f65e02c

3 files changed

Lines changed: 111 additions & 65 deletions

File tree

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,12 @@ private module Input3 implements InputSig3 {
531531

532532
abstract AstNode getArgument(int i);
533533

534+
Parameterizable getTargetForTypeQualifierMatching() {
535+
result = CallExprImpl::getResolvedFunction(this)
536+
or
537+
result = this.(Construction).getTarget()
538+
}
539+
534540
abstract Parameterizable getTarget(string derefChainBorrow);
535541
}
536542

@@ -621,10 +627,11 @@ private module Input3 implements InputSig3 {
621627
this instanceof CallExprImpl::TupleVariantExpr
622628
}
623629

624-
override TypeMention getTypeQualifier() { result = getCallExprTypeArgument2(this) }
630+
override TypeMention getTypeQualifier() { result = CallExprImpl::getFunctionPath(this) }
625631

626632
override Type getTypeArgument(int pos, TypePath path) {
627-
result = NonAssocCallExpr.super.getTypeArgument(pos, path)
633+
// result = NonAssocCallExpr.super.getTypeArgument(pos, path)
634+
none()
628635
}
629636

630637
override AstNode getArgument(int i) {
@@ -665,10 +672,6 @@ private module Input3 implements InputSig3 {
665672
override AstNode getArgument(int i) { none() }
666673
}
667674

668-
Parameterizable getAdditionalTargetForContextualReturnTyping(Invocation invocation) {
669-
result = CallExprImpl::getResolvedFunction(invocation)
670-
}
671-
672675
pragma[nomagic]
673676
private Type inferInvocationArgumentType0(Invocation invocation, int pos, TypePath path) {
674677
exists(FunctionPosition fpos |

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

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6109,14 +6109,12 @@ inferType
61096109
| dereference.rs:144:17:144:26 | key_to_key | K | {EXTERNAL LOCATION} | & |
61106110
| dereference.rs:144:17:144:26 | key_to_key | K.TRef | dereference.rs:122:5:123:21 | Key |
61116111
| dereference.rs:144:17:144:26 | key_to_key | S | {EXTERNAL LOCATION} | RandomState |
6112-
| dereference.rs:144:17:144:26 | key_to_key | V | dereference.rs:122:5:123:21 | Key |
61136112
| dereference.rs:144:17:144:26 | key_to_key | V | {EXTERNAL LOCATION} | & |
61146113
| dereference.rs:144:17:144:26 | key_to_key | V.TRef | dereference.rs:122:5:123:21 | Key |
61156114
| dereference.rs:144:30:144:54 | ...::new(...) | | {EXTERNAL LOCATION} | HashMap |
61166115
| dereference.rs:144:30:144:54 | ...::new(...) | K | {EXTERNAL LOCATION} | & |
61176116
| dereference.rs:144:30:144:54 | ...::new(...) | K.TRef | dereference.rs:122:5:123:21 | Key |
61186117
| dereference.rs:144:30:144:54 | ...::new(...) | S | {EXTERNAL LOCATION} | RandomState |
6119-
| dereference.rs:144:30:144:54 | ...::new(...) | V | dereference.rs:122:5:123:21 | Key |
61206118
| dereference.rs:144:30:144:54 | ...::new(...) | V | {EXTERNAL LOCATION} | & |
61216119
| dereference.rs:144:30:144:54 | ...::new(...) | V.TRef | dereference.rs:122:5:123:21 | Key |
61226120
| dereference.rs:145:17:145:19 | key | | {EXTERNAL LOCATION} | & |
@@ -6127,23 +6125,19 @@ inferType
61276125
| dereference.rs:146:9:149:9 | if ... {...} | | {EXTERNAL LOCATION} | () |
61286126
| dereference.rs:146:16:146:28 | Some(...) | | {EXTERNAL LOCATION} | Option |
61296127
| dereference.rs:146:16:146:28 | Some(...) | T | {EXTERNAL LOCATION} | & |
6130-
| dereference.rs:146:16:146:28 | Some(...) | T.TRef | dereference.rs:122:5:123:21 | Key |
61316128
| dereference.rs:146:16:146:28 | Some(...) | T.TRef | {EXTERNAL LOCATION} | & |
61326129
| dereference.rs:146:16:146:28 | Some(...) | T.TRef.TRef | dereference.rs:122:5:123:21 | Key |
61336130
| dereference.rs:146:21:146:27 | ref_key | | {EXTERNAL LOCATION} | & |
6134-
| dereference.rs:146:21:146:27 | ref_key | TRef | dereference.rs:122:5:123:21 | Key |
61356131
| dereference.rs:146:21:146:27 | ref_key | TRef | {EXTERNAL LOCATION} | & |
61366132
| dereference.rs:146:21:146:27 | ref_key | TRef.TRef | dereference.rs:122:5:123:21 | Key |
61376133
| dereference.rs:146:32:146:41 | key_to_key | | {EXTERNAL LOCATION} | HashMap |
61386134
| dereference.rs:146:32:146:41 | key_to_key | K | {EXTERNAL LOCATION} | & |
61396135
| dereference.rs:146:32:146:41 | key_to_key | K.TRef | dereference.rs:122:5:123:21 | Key |
61406136
| dereference.rs:146:32:146:41 | key_to_key | S | {EXTERNAL LOCATION} | RandomState |
6141-
| dereference.rs:146:32:146:41 | key_to_key | V | dereference.rs:122:5:123:21 | Key |
61426137
| dereference.rs:146:32:146:41 | key_to_key | V | {EXTERNAL LOCATION} | & |
61436138
| dereference.rs:146:32:146:41 | key_to_key | V.TRef | dereference.rs:122:5:123:21 | Key |
61446139
| dereference.rs:146:32:146:50 | key_to_key.get(...) | | {EXTERNAL LOCATION} | Option |
61456140
| dereference.rs:146:32:146:50 | key_to_key.get(...) | T | {EXTERNAL LOCATION} | & |
6146-
| dereference.rs:146:32:146:50 | key_to_key.get(...) | T.TRef | dereference.rs:122:5:123:21 | Key |
61476141
| dereference.rs:146:32:146:50 | key_to_key.get(...) | T.TRef | {EXTERNAL LOCATION} | & |
61486142
| dereference.rs:146:32:146:50 | key_to_key.get(...) | T.TRef.TRef | dereference.rs:122:5:123:21 | Key |
61496143
| dereference.rs:146:47:146:49 | key | | {EXTERNAL LOCATION} | & |
@@ -6155,18 +6149,15 @@ inferType
61556149
| dereference.rs:148:13:148:15 | key | TRef.TRef | dereference.rs:122:5:123:21 | Key |
61566150
| dereference.rs:148:13:148:25 | ... = ... | | {EXTERNAL LOCATION} | () |
61576151
| dereference.rs:148:19:148:25 | ref_key | | {EXTERNAL LOCATION} | & |
6158-
| dereference.rs:148:19:148:25 | ref_key | TRef | dereference.rs:122:5:123:21 | Key |
61596152
| dereference.rs:148:19:148:25 | ref_key | TRef | {EXTERNAL LOCATION} | & |
61606153
| dereference.rs:148:19:148:25 | ref_key | TRef.TRef | dereference.rs:122:5:123:21 | Key |
61616154
| dereference.rs:150:9:150:18 | key_to_key | | {EXTERNAL LOCATION} | HashMap |
61626155
| dereference.rs:150:9:150:18 | key_to_key | K | {EXTERNAL LOCATION} | & |
61636156
| dereference.rs:150:9:150:18 | key_to_key | K.TRef | dereference.rs:122:5:123:21 | Key |
61646157
| dereference.rs:150:9:150:18 | key_to_key | S | {EXTERNAL LOCATION} | RandomState |
6165-
| dereference.rs:150:9:150:18 | key_to_key | V | dereference.rs:122:5:123:21 | Key |
61666158
| dereference.rs:150:9:150:18 | key_to_key | V | {EXTERNAL LOCATION} | & |
61676159
| dereference.rs:150:9:150:18 | key_to_key | V.TRef | dereference.rs:122:5:123:21 | Key |
61686160
| dereference.rs:150:9:150:35 | key_to_key.insert(...) | | {EXTERNAL LOCATION} | Option |
6169-
| dereference.rs:150:9:150:35 | key_to_key.insert(...) | T | dereference.rs:122:5:123:21 | Key |
61706161
| dereference.rs:150:9:150:35 | key_to_key.insert(...) | T | {EXTERNAL LOCATION} | & |
61716162
| dereference.rs:150:9:150:35 | key_to_key.insert(...) | T.TRef | dereference.rs:122:5:123:21 | Key |
61726163
| dereference.rs:150:27:150:29 | key | | {EXTERNAL LOCATION} | & |
@@ -14318,7 +14309,6 @@ inferType
1431814309
| pattern_matching.rs:809:13:809:17 | stack | T | {EXTERNAL LOCATION} | i32 |
1431914310
| pattern_matching.rs:809:31:809:46 | MacroExpr | | {EXTERNAL LOCATION} | Vec |
1432014311
| pattern_matching.rs:809:31:809:46 | MacroExpr | A | {EXTERNAL LOCATION} | Global |
14321-
| pattern_matching.rs:809:31:809:46 | MacroExpr | T | {EXTERNAL LOCATION} | i32 |
1432214312
| pattern_matching.rs:809:36:809:39 | 1i32 | | {EXTERNAL LOCATION} | i32 |
1432314313
| pattern_matching.rs:809:42:809:42 | 2 | | {EXTERNAL LOCATION} | i32 |
1432414314
| pattern_matching.rs:809:45:809:45 | 3 | | {EXTERNAL LOCATION} | i32 |

shared/typeinference/codeql/typeinference/internal/TypeInference.qll

Lines changed: 102 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,7 +1611,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
16111611
}
16121612

16131613
pragma[inline]
1614-
private predicate typeMatch(
1614+
predicate typeMatch(
16151615
Access a, AccessEnvironment e, Declaration target, TypePath path, Type t, TypeParameter tp
16161616
) {
16171617
// A type given at the access corresponds directly to the type parameter
@@ -1831,7 +1831,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
18311831
Location getLocation();
18321832

18331833
/**
1834-
* Gets the type at `path` for the type argument at position `tapos` of
1834+
* Gets the type at `path` for the type argument at position `pos` of
18351835
* this access, if any.
18361836
*
18371837
* For example, in a method call like `M<int>()`, `int` is an explicit
@@ -2152,7 +2152,13 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
21522152

21532153
/** An invocation expression, for example a call or a variant construction. */
21542154
class Invocation extends Expr {
2155-
/** Gets the explicit type argument at position `pos` and `path` for this invocation, if any. */
2155+
/**
2156+
* Gets the explicit type argument at position `pos` and `path` for this invocation, if any.
2157+
*
2158+
* This should only include type arguments that are explicitly provided for the target
2159+
* and not type arguments that are part of a type qualifier (those should be
2160+
* handled via `getTypeQualifier`).
2161+
*/
21562162
Type getTypeArgument(int pos, TypePath path);
21572163

21582164
/**
@@ -2165,6 +2171,14 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
21652171
TypeMention getTypeQualifier();
21662172

21672173
/** Gets the target of this invocation in the given resolution context. */
2174+
Parameterizable getTargetForTypeQualifierMatching();
2175+
2176+
/**
2177+
* Gets the target of this invocation in the given resolution context.
2178+
*
2179+
* This predicate may depend possitively on the `inferType` predicate, for example
2180+
* in order to resolve a method call one needs to know the type of the receiver.
2181+
*/
21682182
Parameterizable getTarget(ResolutionContext ctx);
21692183
}
21702184

@@ -2234,11 +2248,6 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
22342248
result = inferTypeForDefaults(invocation, path)
22352249
}
22362250

2237-
/** TODO. */
2238-
default Parameterizable getAdditionalTargetForContextualReturnTyping(Invocation invocation) {
2239-
none()
2240-
}
2241-
22422251
/** A member that can be accessed, such as a field. */
22432252
class Member extends AstNode {
22442253
/** Gets the type at `path` of the entity that declares this member. */
@@ -2621,42 +2630,35 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
26212630
not mentionsTypeParameterAtParameter(p, tp)
26222631
}
26232632

2624-
// only needed to get access to `Matching::getTypeArgument`.
2625-
private module InvocationMatchingGetTypeArgumentInput implements MatchingInputSig {
2626-
import InvocationMatchingInput
2627-
2628-
predicate getATypeParameterConstraint =
2629-
InvocationMatchingInput::getATypeParameterConstraint/2;
2630-
2631-
class Access extends InvocationMatchingInput::Access {
2632-
Type getInferredType(AccessPosition apos, TypePath path) { none() }
2633-
2634-
Declaration getTarget() {
2635-
result = this.getTarget(_)
2636-
or
2637-
result = getAdditionalTargetForContextualReturnTyping(this)
2638-
}
2639-
}
2633+
bindingset[invocation, target]
2634+
pragma[inline_late]
2635+
private predicate hasTypeArgument(
2636+
Invocation invocation, Parameterizable target, TypeParameter tp
2637+
) {
2638+
exists(Type t |
2639+
InvocationTypeQualifierMatching::typeMatch(invocation, _, _, _, t, tp) and
2640+
not t instanceof PseudoType
2641+
)
2642+
or
2643+
exists(InvocationMatching::getTypeArgument(invocation, target, tp, _))
26402644
}
26412645

2642-
private module InvocationMatchingGetTypeArgument =
2643-
Matching<InvocationMatchingGetTypeArgumentInput>;
2644-
26452646
/**
26462647
* Holds if `invocation` resolves some target where the return type at `path`
26472648
* may have to be inferred from the context.
26482649
*/
26492650
pragma[nomagic]
26502651
predicate needsContextualTyping(Invocation invocation, TypePath path) {
26512652
exists(Parameterizable target, TypeParameter tp |
2652-
target = invocation.(InvocationMatchingGetTypeArgumentInput::Access).getTarget() and
2653+
target = invocation.(InvocationTypeQualifierMatchingInput::Access).getTarget()
2654+
or
2655+
target = invocation.getTarget(_)
2656+
|
26532657
parameterizableReturnContextTypedAt(target, path, tp) and
26542658
// check that no explicit type arguments have been supplied which bind `tp`
26552659
not exists(TypeParameter supplied |
26562660
tp = getAConstrained*(supplied) and
2657-
exists(
2658-
InvocationMatchingGetTypeArgument::getTypeArgument(invocation, target, supplied, _)
2659-
)
2661+
hasTypeArgument(invocation, target, supplied)
26602662
)
26612663
)
26622664
}
@@ -2890,10 +2892,57 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
28902892
)
28912893
}
28922894

2895+
final private class ParameterizableFinal = Parameterizable;
2896+
2897+
final private class InvocationFinal = Invocation;
2898+
2899+
private module InvocationTypeQualifierMatchingInput implements MatchingInputSig {
2900+
private import codeql.util.Unit
2901+
2902+
class DeclarationPosition = Unit;
2903+
2904+
class AccessPosition = Unit;
2905+
2906+
bindingset[apos]
2907+
bindingset[dpos]
2908+
predicate accessDeclarationPositionMatch(AccessPosition apos, DeclarationPosition dpos) {
2909+
apos = dpos
2910+
}
2911+
2912+
final class Declaration extends ParameterizableFinal {
2913+
Type getDeclaredType(DeclarationPosition dpos, TypePath path) {
2914+
result = this.getDeclaringType(path) and
2915+
exists(dpos)
2916+
}
2917+
}
2918+
2919+
bindingset[decl]
2920+
TypeMention getATypeParameterConstraint(TypeParameter tp, Declaration decl) {
2921+
result = Input2::getATypeParameterConstraint(tp) and
2922+
exists(decl)
2923+
or
2924+
result = decl.getAdditionalTypeParameterConstraint(tp)
2925+
}
2926+
2927+
final class Access extends InvocationFinal {
2928+
Type getInferredType(AccessPosition apos, TypePath path) {
2929+
result = this.getTypeQualifier().getTypeAt(path) and
2930+
exists(apos)
2931+
}
2932+
2933+
Declaration getTarget() { result = super.getTargetForTypeQualifierMatching() }
2934+
}
2935+
}
2936+
2937+
private module InvocationTypeQualifierMatching =
2938+
Matching<InvocationTypeQualifierMatchingInput>;
2939+
28932940
/**
28942941
* A matching configuration for resolving types of invocations.
28952942
*/
28962943
private module InvocationMatchingInput implements MatchingWithEnvironmentInputSig {
2944+
import InvocationTypeQualifierMatchingInput
2945+
28972946
class DeclarationPosition = int;
28982947

28992948
class AccessPosition = DeclarationPosition;
@@ -2907,36 +2956,44 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
29072956
/** Gets the position used to represent the return type of a callable/type of a call. */
29082957
additional int getReturnPosition() { result = -1 }
29092958

2910-
/** Gets the position used to represent the declaring type of a callable/type qualifier of a call. */
2911-
additional int getDeclaringPosition() { result = -2 }
2912-
2913-
final private class ParameterizableFinal = Parameterizable;
2914-
2959+
// /** Gets the position used to represent the declaring type of a callable/type qualifier of a call. */
29152960
class Declaration extends ParameterizableFinal {
2961+
TypeParameter getTypeParameter(int pos) {
2962+
InvocationTypeQualifierMatching::typeMatch(_, _, this, _, _, result) and
2963+
pos = -getTypeParameterId(result) - 1
2964+
or
2965+
result = super.getTypeParameter(pos)
2966+
// none()
2967+
}
2968+
29162969
Type getDeclaredType(DeclarationPosition dpos, TypePath path) {
29172970
result = this.getParameter(dpos).getType().getTypeAt(path)
29182971
or
29192972
dpos = getReturnPosition() and
29202973
result = getParameterizableType(this, path)
2921-
or
2922-
dpos = getDeclaringPosition() and
2923-
result = this.getDeclaringType(path)
2974+
// or
2975+
// dpos = getDeclaringPosition() and
2976+
// result = this.getDeclaringType(path)
29242977
}
29252978
}
29262979

29272980
bindingset[decl]
29282981
TypeMention getATypeParameterConstraint(TypeParameter tp, Declaration decl) {
2929-
result = Input2::getATypeParameterConstraint(tp) and
2930-
exists(decl)
2931-
or
2932-
result = decl.getAdditionalTypeParameterConstraint(tp)
2982+
result = InvocationTypeQualifierMatchingInput::getATypeParameterConstraint(tp, decl)
29332983
}
29342984

29352985
class AccessEnvironment = ResolutionContext;
29362986

2937-
final private class InvocationFinal = Invocation;
2938-
29392987
class Access extends InvocationFinal {
2988+
Type getTypeArgument(int pos, TypePath path) {
2989+
exists(TypeParameter tp |
2990+
InvocationTypeQualifierMatching::typeMatch(this, _, _, path, result, tp) and
2991+
pos = -getTypeParameterId(tp) - 1
2992+
)
2993+
or
2994+
result = super.getTypeArgument(pos, path)
2995+
}
2996+
29402997
pragma[nomagic]
29412998
private Type getInferredResultType(AccessPosition apos, TypePath path) {
29422999
result = inferInvocationTypeContextual(this, path) and
@@ -2949,10 +3006,6 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
29493006
or
29503007
result = this.getInferredResultType(apos, path) and
29513008
exists(e)
2952-
or
2953-
result = this.getTypeQualifier().getTypeAt(path) and
2954-
apos = getDeclaringPosition() and
2955-
exists(e)
29563009
}
29573010

29583011
Declaration getTarget(AccessEnvironment e) { result = super.getTarget(e) }

0 commit comments

Comments
 (0)