Skip to content

Commit 69c7964

Browse files
committed
wip
1 parent 9aa0f1a commit 69c7964

1 file changed

Lines changed: 25 additions & 19 deletions

File tree

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

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
*
44
* The library is initialized in three phases:
55
*
6-
* 1. `Make1`, which takes as input a definition of types (including type parameters)
7-
* and constructs the `TypePath` type used to represent paths into compound types.
6+
* 1. `Make1`, which takes as input a definition of atomic types (including type
7+
* parameters) and constructs the `TypePath` type used to represent paths into
8+
* compound types.
89
*
910
* 2. `Make2`, which takes as input a definition of type mentions (using the `TypePath`
1011
* type) as well as the type hierarchy and type constraints, and constructs the
@@ -18,13 +19,14 @@
1819
* nodes.
1920
*
2021
* Unlike unification-based type inference, this library does directed/bottom-up type
21-
* inference by default, but allowing for contextual/top-down type inference only when
22+
* inference by default, but allowing for contextual/top-down type inference when
2223
* explicitly needed.
2324
*
2425
* For example, in order to infer the type of a conditional expression,
25-
* `if cond { e1 } else { e2 }`, we first infer the types of `e1` and `e2` and then
26-
* apply their types to the conditional expression (not taking least-upper-bound or
27-
* similar into account). This corresponds to the type inference rules
26+
* `if cond { e1 } else { e2 }`, we propagate type information from either of the
27+
* branches `e1` and `e2` into the conditional expression (for simplicity, we do not
28+
* attempt to calculate least-upper-bound types or similar). This corresponds to the
29+
* two bottom-up type inference rules:
2830
*
2931
* ```text
3032
* e1: T
@@ -44,10 +46,11 @@
4446
* ```
4547
*
4648
* where the type of `Default::default()` needs to be inferred from the context, we
47-
* first assign `Default::default()` the special `UnknownType`, then using the
48-
* `cond-then` rule we conclude that the conditional has type `i64`, and then since
49-
* the `else` branch has `UnknownType`, we can apply the `cond-else` rule _backwards_
50-
* to infer that `Default::default()` has type `i64`.
49+
*
50+
* 1. assign `Default::default()` the special `UnknownType`,
51+
* 2. using the `cond-then` rule we conclude that the conditional has type `i64`, and
52+
* 3. since the `else` branch has `UnknownType`, we apply the `cond-else` rule _backwards_
53+
* to infer that `Default::default()` has type `i64`.
5154
*
5255
* Note that `UnknownType` can propagate bottom-up like any other type, which is needed
5356
* in cases like for example
@@ -2612,18 +2615,18 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
26122615
* context, and also implements logic for performing contextual inference.
26132616
*/
26142617
private module ContextualTyping {
2618+
pragma[nomagic]
2619+
private TypeParameter getAConstrained(TypeParameter tp) {
2620+
result = getATypeParameterConstraint(tp).getTypeAt(_)
2621+
}
2622+
26152623
/**
26162624
* Holds if parameterizable `p` mentions type parameter `tp` at some parameter,
26172625
* possibly via a constraint on another mentioned type parameter.
26182626
*/
26192627
pragma[nomagic]
26202628
private predicate mentionsTypeParameterAtParameter(Parameterizable p, TypeParameter tp) {
2621-
tp = p.getParameter(_).getType().getTypeAt(_)
2622-
or
2623-
exists(TypeParameter mid |
2624-
mentionsTypeParameterAtParameter(p, mid) and
2625-
tp = getATypeParameterConstraint(mid).getTypeAt(_)
2626-
)
2629+
tp = getAConstrained*(p.getParameter(_).getType().getTypeAt(_))
26272630
}
26282631

26292632
/**
@@ -2674,9 +2677,12 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
26742677
target = invocation.(InvocationMatchingGetTypeArgumentInput::Access).getTarget() and
26752678
parameterizableReturnContextTypedAt(target, path, tp) and
26762679
tp = target.getTypeParameter(_) and
2677-
// check that no explicit type arguments have been supplied for `tp`
2678-
not exists(
2679-
InvocationMatchingGetTypeArgument::getTypeArgument(invocation, target, tp, _)
2680+
// check that no explicit type arguments have been supplied which bind `tp`
2681+
not exists(TypeParameter supplied |
2682+
tp = getAConstrained*(supplied) and
2683+
exists(
2684+
InvocationMatchingGetTypeArgument::getTypeArgument(invocation, target, supplied, _)
2685+
)
26802686
)
26812687
)
26822688
}

0 commit comments

Comments
 (0)