From 05c5f2f570524fdaca5ec81df9bad5112b10e3c1 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 20 Oct 2026 10:33:55 +0200 Subject: [PATCH 1/6] Type inference: Introduce `stepLanguageSpecificExtra` --- .../codeql/typeinference/internal/TypeInference.qll | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll index 60e2419e6cad..c298bc81be5c 100644 --- a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll +++ b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll @@ -2667,6 +2667,16 @@ module Make1 Input1> { */ predicate stepLanguageSpecific(AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2); + /** + * Like `stepLanguageSpecific`, but allows for recursion. Only use this predicate when + * using `stepLanguageSpecific` results in non-monotonicity. + */ + default predicate stepLanguageSpecificExtra( + AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2 + ) { + none() + } + /** * Gets the inferred type of `n` at `path`. * @@ -2893,6 +2903,8 @@ module Make1 Input1> { private predicate step(AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2) { stepLanguageSpecific(n1, prefix1, n2, prefix2) or + stepLanguageSpecificExtra(n1, prefix1, n2, prefix2) + or Certain::stepCertain(n1, prefix1, n2, prefix2) or prefix1.isEmpty() and From 81c2e37ca774f5fc61bac1c44fef65d3ea22240b Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 20 Oct 2026 10:34:44 +0200 Subject: [PATCH 2/6] Type inference: Introduce `allowFullContextualInference` --- .../typeinference/internal/TypeInference.qll | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll index c298bc81be5c..f47f90222415 100644 --- a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll +++ b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll @@ -2694,6 +2694,13 @@ module Make1 Input1> { * in `inferTypeLanguageSpecific`; if in doubt, use `inferTypeLanguageSpecific` instead. */ default Type inferTypeCertainLanguageSpecific(AstNode n, TypePath path) { none() } + + /** + * Holds if full contextual inference is allowed for the node `n` at the + * type path `path`. This means that `n` does not need to be assigned + * `UnknownType` at (a prefix of) `path`. + */ + default predicate allowFullContextualInference(AstNode n, TypePath path) { none() } } module Make3 { @@ -3310,6 +3317,8 @@ module Make1 Input1> { pragma[nomagic] predicate hasUnknownTypeAt(AstNode n, TypePath path) { inferType(n, path) instanceof UnknownType + or + allowFullContextualInference(n, path) } pragma[nomagic] @@ -3338,10 +3347,7 @@ module Make1 Input1> { private Type inferTypeContextualCand1(AstNode n, TypePath prefix, TypePath path) { result = inferTypeContextualCand0(n, path) and hasUnknownType(n) and - prefix = path.getAPrefix() and - // no need to propagate `UnknownType`s contextually; `n` must already have an - // `UnknownType` at some prefix of `path` - not result instanceof UnknownType + prefix = path.getAPrefix() } pragma[nomagic] @@ -3379,6 +3385,8 @@ module Make1 Input1> { path.isEmpty() or isValidContextualNonEmptyPath(n, path) + or + allowFullContextualInference(n, path.getAPrefix()) ) } } From 238259138238be2c2ec9a3007216d9a8daef9cf6 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 20 Oct 2026 10:35:06 +0200 Subject: [PATCH 3/6] Type inference: Make `needsContextualTyping` a parameterized module --- .../typeinference/internal/TypeInference.qll | 123 +++++++++++------- 1 file changed, 74 insertions(+), 49 deletions(-) diff --git a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll index f47f90222415..de0e01455955 100644 --- a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll +++ b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll @@ -3253,67 +3253,92 @@ module Make1 Input1> { * This module identifies calls where the return type may need to be inferred from the * context, and also implements logic for performing contextual inference. */ - private module ContextualTyping { - pragma[nomagic] - private TypeParameter getAConstrained(TypeParameter tp) { - result = getATypeParameterConstraint(tp).getTypeAt(_) - } - + module ContextualTyping { /** - * Holds if callable `c` mentions type parameter `tp` at some parameter, - * possibly via a constraint on another mentioned type parameter. + * Provides the input to `ContextualReturnType`. */ - pragma[nomagic] - private predicate mentionsTypeParameterAtParameter(Callable c, TypeParameter tp) { - tp = getAConstrained*(c.getParameter(_).getType().getTypeAt(_)) + signature module ContextualReturnTypeInputSig { + /** Holds if `c` has the type parameter `tp` at its return type at `path`. */ + default predicate callableHasTypeParameterAtReturnType( + Callable c, TypePath path, TypeParameter tp + ) { + tp = getCallableReturnType(c, path) + } + + /** Gets a parameter of `c`. */ + default Parameter getACallableParameter(Callable c) { result = c.getParameter(_) } } /** - * Holds if the return type of the callable `c` at `path` is type parameter - * `tp`, and `tp` does not appear in the type of any parameter of `c`. - * - * In this case, the context in which `p` is called may be needed to infer - * the instantiation of `tp`. - * - * This covers functions like `Default::default` and `Vec::new` in Rust. + * Provide logic for identifying calls where the return type may need to be inferred from the context. */ - pragma[nomagic] - private predicate callableReturnContextTypedAt(Callable c, TypePath path, TypeParameter tp) { - tp = getCallableReturnType(c, path) and - not mentionsTypeParameterAtParameter(c, tp) - } + module ContextualReturnType { + pragma[nomagic] + private TypeParameter getAConstrained(TypeParameter tp) { + result = getATypeParameterConstraint(tp).getTypeAt(_) + } - bindingset[invocation, target] - pragma[inline_late] - private predicate hasTypeArgument(Invocation invocation, Callable target, TypeParameter tp) { - exists(Type t | - InvocationTypeQualifierMatching::typeMatch(invocation, _, _, _, t, tp) and - not t instanceof PseudoType - ) - or - exists(InvocationMatching::getTypeArgument(invocation, target, tp, _)) - } + /** + * Holds if callable `c` mentions type parameter `tp` at some parameter, + * possibly via a constraint on another mentioned type parameter. + */ + pragma[nomagic] + private predicate mentionsTypeParameterAtParameter(Callable c, TypeParameter tp) { + tp = getAConstrained*(Input::getACallableParameter(c).getType().getTypeAt(_)) + } - /** - * Holds if `invocation` resolves to some target where the return type at `path` - * may have to be inferred from the context. - */ - pragma[nomagic] - predicate needsContextualTyping(Invocation invocation, TypePath path) { - exists(Callable target, TypeParameter tp | - target = invocation.getATargetForTypeQualifierMatching() + /** + * Holds if the return type of the callable `c` at `path` is type parameter + * `tp`, and `tp` does not appear in the type of any parameter of `c`. + * + * In this case, the context in which `p` is called may be needed to infer + * the instantiation of `tp`. + * + * This covers functions like `Default::default` and `Vec::new` in Rust. + */ + pragma[nomagic] + private predicate callableReturnContextTypedAt(Callable c, TypePath path, TypeParameter tp) { + Input::callableHasTypeParameterAtReturnType(c, path, tp) and + not mentionsTypeParameterAtParameter(c, tp) + } + + bindingset[invocation, target] + pragma[inline_late] + private predicate hasTypeArgument(Invocation invocation, Callable target, TypeParameter tp) { + exists(Type t | + InvocationTypeQualifierMatching::typeMatch(invocation, _, _, _, t, tp) and + not t instanceof PseudoType + ) or - target = invocation.getTarget(_) - | - callableReturnContextTypedAt(target, path, tp) and - // check that no explicit type arguments have been supplied that bind `tp` - not exists(TypeParameter supplied | - tp = getAConstrained*(supplied) and - hasTypeArgument(invocation, target, supplied) + exists(InvocationMatching::getTypeArgument(invocation, target, tp, _)) + } + + /** + * Holds if `invocation` resolves to some target where the return type at `path` + * may have to be inferred from the context. + */ + pragma[nomagic] + predicate needsContextualTyping(Invocation invocation, TypePath path) { + exists(Callable target, TypeParameter tp | + target = invocation.getATargetForTypeQualifierMatching() + or + target = invocation.getTarget(_) + | + callableReturnContextTypedAt(target, path, tp) and + // check that no explicit type arguments have been supplied that bind `tp` + not exists(TypeParameter supplied | + tp = getAConstrained*(supplied) and + hasTypeArgument(invocation, target, supplied) + ) ) - ) + } } + private module DefaultContextualReturnTypeInput implements ContextualReturnTypeInputSig { } + + predicate needsContextualTyping = + ContextualReturnType::needsContextualTyping/2; + pragma[nomagic] predicate hasUnknownTypeAt(AstNode n, TypePath path) { inferType(n, path) instanceof UnknownType From 39950744c1bd76612c35b2048ceba157641f3956 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 19 Oct 2026 20:12:23 +0200 Subject: [PATCH 4/6] Type inference: Improve performance of `infersUnknownTypeArg` --- .../typeinference/internal/TypeInference.qll | 41 +++++++++++++++---- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll index de0e01455955..eb9799cfa48f 100644 --- a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll +++ b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll @@ -3510,6 +3510,38 @@ module Make1 Input1> { } } + /** + * Holds if the type of `n` at `path` is `t` and the `j`th element of `path` + * corresponds to the `i`th type parameter of the unknown type. + */ + pragma[nomagic] + private predicate infersUnknownTypeArg0(AstNode n, int i, int j, TypePath path, Type t) { + exists(TypeParameter tp | + ContextualTyping::hasUnknownType(n) and + tp = any(UnknownType ut).getPositionalTypeParameter(i) and + t = inferType(n, path) and + not t instanceof UnknownType and + tp = path.getElement(j) + ) + } + + /** + * Holds if the type of `n` at `path` is `t`, where + * `path = prefix ++ tp_i ++ suffix` and `tp_i` is the `i`th type parameter + * of the unknown type. + */ + pragma[nomagic] + private predicate infersUnknownTypeArg1( + AstNode n, TypePath prefix, int i, TypePath suffix, Type t + ) { + exists(TypePath path, int j, TypePath suffix0 | + infersUnknownTypeArg0(n, i, j, path, t) and + prefix = path.getProperPrefix(j) and + path = prefix.appendInverse(suffix0) and + suffix0.isCons(_, suffix) + ) + } + /** * Holds if `n` has unknown type at `prefix`, but is still able to * infer a known type at `suffix` for the `i`th type parameter of whatever @@ -3531,13 +3563,8 @@ module Make1 Input1> { private predicate infersUnknownTypeArg( AstNode n, TypePath prefix, int i, TypePath suffix, Type t ) { - exists(TypeParameter tp, TypePath suffix0 | - ContextualTyping::hasUnknownTypeAt(n, prefix) and - suffix0.isCons(tp, suffix) and - tp = any(UnknownType ut).getPositionalTypeParameter(i) and - t = inferType(n, prefix.appendInverse(suffix0)) and - not t instanceof UnknownType - ) + ContextualTyping::hasUnknownTypeAt(n, prefix) and + infersUnknownTypeArg1(n, prefix, i, suffix, t) } pragma[nomagic] From 5046538b2861b73651f25fa40f9799f90a5d1e0e Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 8 Oct 2026 21:26:56 +0200 Subject: [PATCH 5/6] Unified: Add more type inference tests for constructors --- .../internal/typeinference/TypeInference.qll | 8 + .../type-inference/constructors.swift | 69 +++++++ .../type-inference/type-inference.expected | 169 +++++++++++++----- 3 files changed, 205 insertions(+), 41 deletions(-) diff --git a/unified/ql/lib/codeql/unified/internal/typeinference/TypeInference.qll b/unified/ql/lib/codeql/unified/internal/typeinference/TypeInference.qll index 5bd2d7f885bc..30f617990985 100644 --- a/unified/ql/lib/codeql/unified/internal/typeinference/TypeInference.qll +++ b/unified/ql/lib/codeql/unified/internal/typeinference/TypeInference.qll @@ -693,6 +693,14 @@ Callable resolveCallTarget(CallExpr ce) { private predicate typeTestAstNodeRepr(AstNode n, string repr) { repr = [n.toString(), n.(Identifier).getValue(), "." + n.(MemberAccessExpr).getMemberName()] + or + exists(string s | + typeTestAstNodeRepr(n.(CallExpr).getCallee(), s) and + repr = s + "(...)" + or + typeTestAstNodeRepr(n.(GenericTypeExpr).getBase(), s) and + repr = s + "<...>" + ) } module TypeTest implements TestSig { diff --git a/unified/ql/test/library-tests/type-inference/constructors.swift b/unified/ql/test/library-tests/type-inference/constructors.swift index eb1d4ae49d06..04930cbe2eed 100644 --- a/unified/ql/test/library-tests/type-inference/constructors.swift +++ b/unified/ql/test/library-tests/type-inference/constructors.swift @@ -9,6 +9,62 @@ class C1 { var c11 = C1() // $ type=c11:C1 target=C1.init_conv $ SPURIOUS: target=C1.init var c12 = C1.init() // $ type=c12:C1 target=C1.init_conv $ SPURIOUS: target=C1.init +class C2: C1 {} // inherits `init` + +var c21 = C2() // $ type=c21:C2 $ MISSING: target=C1.init_conv $ SPURIOUS: target=C2.init +var c22 = C2.init() // $ target=C1.init_conv $ MISSING: type=c22:C2 $ SPURIOUS: target=C1.init + +class C3 { + init() {} +} + +var c3 = C3() // $ type=c3:C3 target=C3.init + +class C4: C3 { + init(_ x: Int) { + super.init() // $ target=C3.init + } + + override convenience init() { // name=C4.init_conv + self.init(0) // $ target=C4.init $ SPURIOUS: target=C4.init_conv + } +} + +class C5: C4 {} // inherits `init` and `convenience init` + +var c51 = C5() // $ type=c51:C5 $ MISSING: target=C4.init $ SPURIOUS: target=C5.init +var c52 = C5(0) // $ type=c52:C5 $ MISSING: target=C4.init $ SPURIOUS: target=C5.init + +class C6 { + init(x: T1, y: T2) {} + + private init(s: String) {} // name=C6.init_private + + convenience init(x: T1) { // name=C6.init_conv + fatalError("Convenience initializer not implemented") + } +} + +class C7: C6 {} // inherits `init(x: T4, y: T3)` and `convenience init(x: T4)` + +var c71 = C7(x: "string", y: true) // $ MISSING: type=c71@C7:Bool type=c71@C7:String target=C6.init $ SPURIOUS: target=C7.init +var c72 = C7(x: 0) // $ type=c72@C7:Bool $ MISSING: type=c72@C7:Int target=C6.init $ SPURIOUS: target=C7.init + +class C8: C7 { // inherits `init(x: String, y: Int)` + convenience init(x: String) { // name=C8.init_conv + self.init(x: x, y: 0) // $ target=C6.init $ SPURIOUS: target=C8.init_conv + } +} + +class C9: C8 {} + +let c91: C9 = C9(x: "") // $ MISSING: type=C9(...)@C9:Int target=C8.init_conv $ SPURIOUS: target=C9.init +let c92 = C9(x: "") // $ type=C9<...>(...)@C9:Int $ MISSING: target=C8.init_conv $ SPURIOUS: target=C9.init + +class C10: C6 {} + +let c10: C10<_, Int> = C10(x: "") // $ MISSING: type=C10(...)@C10:Int target=C6.init_conv $ SPURIOUS: target=C10.init + struct S1 { // implicit `init(f1: T, f2: String = "default", f3: (T) -> T = { $0 })` var f1: T var f2: String = "default" @@ -18,3 +74,16 @@ struct S1 { // implicit `init(f1: T, f2: String = "default", f3: (T) -> T = var s11 = S1(f1: 0) // $ target=S1.init type=s11@S1:Int var s12 = S1(f1: true, f2: "") // $ target=S1.init type=s12@S1:Bool S1(f1: 0, f2: "", f3: { x in x }) // $ target=S1.init type=x:Int +S1(f1: 0, f3: { x in x }) // $ target=S1.init $ MISSING: type=x:Int (optional parameters are not handled) + +enum E1 { + case a(Int) + + static func foo() { + let e1 = a(0) // $ target=E1.a type=e1:E1 + } +} + +enum E2 { case a(A) } + +let e2: E2<_, String> = E2.a(1) // $ target=E2.a $ MISSING: type=.a(...)@E2:String diff --git a/unified/ql/test/library-tests/type-inference/type-inference.expected b/unified/ql/test/library-tests/type-inference/type-inference.expected index ebd75b0b3ad3..3f9b33d68956 100644 --- a/unified/ql/test/library-tests/type-inference/type-inference.expected +++ b/unified/ql/test/library-tests/type-inference/type-inference.expected @@ -129,15 +129,32 @@ inferCertainType | closures.swift:66:9:68:9 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | | constructors.swift:2:12:2:12 | x | | {EXTERNAL LOCATION} | Int | | constructors.swift:5:9:5:12 | self | | constructors.swift:1:1:7:1 | C1 | -| constructors.swift:13:9:13:10 | f1 | | constructors.swift:12:11:12:11 | T | -| constructors.swift:14:9:14:10 | f2 | | {EXTERNAL LOCATION} | String | -| constructors.swift:15:9:15:10 | f3 | | {EXTERNAL LOCATION} | Function | -| constructors.swift:15:9:15:10 | f3 | Args | {EXTERNAL LOCATION} | Tuple1 | -| constructors.swift:15:9:15:10 | f3 | Args.T0 | constructors.swift:12:11:12:11 | T | -| constructors.swift:15:9:15:10 | f3 | Return | constructors.swift:12:11:12:11 | T | -| constructors.swift:15:24:15:29 | FunctionExpr | | {EXTERNAL LOCATION} | Function | -| constructors.swift:20:23:20:32 | FunctionExpr | | {EXTERNAL LOCATION} | Function | -| constructors.swift:20:23:20:32 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| constructors.swift:24:12:24:12 | x | | {EXTERNAL LOCATION} | Int | +| constructors.swift:29:9:29:12 | self | | constructors.swift:23:1:31:1 | C4 | +| constructors.swift:39:10:39:10 | x | | constructors.swift:38:10:38:11 | T1 | +| constructors.swift:39:17:39:17 | y | | constructors.swift:38:14:38:15 | T2 | +| constructors.swift:41:18:41:18 | s | | {EXTERNAL LOCATION} | String | +| constructors.swift:43:22:43:22 | x | | constructors.swift:38:10:38:11 | T1 | +| constructors.swift:54:22:54:22 | x | | {EXTERNAL LOCATION} | String | +| constructors.swift:55:9:55:12 | self | | constructors.swift:53:1:57:1 | C8 | +| constructors.swift:55:22:55:22 | x | | {EXTERNAL LOCATION} | String | +| constructors.swift:61:5:61:7 | c91 | | constructors.swift:59:1:59:19 | C9 | +| constructors.swift:61:5:61:7 | c91 | T9 | {EXTERNAL LOCATION} | Int | +| constructors.swift:66:5:66:7 | c10 | | constructors.swift:64:1:64:42 | C10 | +| constructors.swift:66:5:66:7 | c10 | T10b | {EXTERNAL LOCATION} | Int | +| constructors.swift:69:9:69:10 | f1 | | constructors.swift:68:11:68:11 | T | +| constructors.swift:70:9:70:10 | f2 | | {EXTERNAL LOCATION} | String | +| constructors.swift:71:9:71:10 | f3 | | {EXTERNAL LOCATION} | Function | +| constructors.swift:71:9:71:10 | f3 | Args | {EXTERNAL LOCATION} | Tuple1 | +| constructors.swift:71:9:71:10 | f3 | Args.T0 | constructors.swift:68:11:68:11 | T | +| constructors.swift:71:9:71:10 | f3 | Return | constructors.swift:68:11:68:11 | T | +| constructors.swift:71:24:71:29 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| constructors.swift:76:23:76:32 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| constructors.swift:76:23:76:32 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| constructors.swift:77:15:77:24 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| constructors.swift:77:15:77:24 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| constructors.swift:89:5:89:6 | e2 | | constructors.swift:87:1:87:27 | E2 | +| constructors.swift:89:5:89:6 | e2 | B | {EXTERNAL LOCATION} | String | | fields.swift:2:7:2:20 | inheritedField | | {EXTERNAL LOCATION} | Int | | fields.swift:6:7:6:17 | storedField | | {EXTERNAL LOCATION} | String | | fields.swift:7:7:7:18 | genericField | | fields.swift:5:22:5:22 | T | @@ -1093,8 +1110,6 @@ inferType | closures.swift:69:5:69:5 | _ | | {EXTERNAL LOCATION} | String | | closures.swift:69:5:69:14 | ... = ... | | {EXTERNAL LOCATION} | String | | closures.swift:69:9:69:14 | result | | {EXTERNAL LOCATION} | String | -| constructors.swift:1:1:20:33 | Block | | constructors.swift:12:1:16:1 | S1 | -| constructors.swift:1:1:20:33 | Block | T | {EXTERNAL LOCATION} | Int | | constructors.swift:2:12:2:12 | x | | {EXTERNAL LOCATION} | Int | | constructors.swift:4:24:6:5 | Block | | constructors.swift:1:1:7:1 | C1 | | constructors.swift:5:9:5:12 | self | | constructors.swift:1:1:7:1 | C1 | @@ -1104,36 +1119,108 @@ inferType | constructors.swift:9:11:9:14 | C1(...) | | constructors.swift:1:1:7:1 | C1 | | constructors.swift:10:5:10:7 | c12 | | constructors.swift:1:1:7:1 | C1 | | constructors.swift:10:11:10:19 | ... .init(...) | | constructors.swift:1:1:7:1 | C1 | -| constructors.swift:13:9:13:10 | f1 | | constructors.swift:12:11:12:11 | T | -| constructors.swift:14:9:14:10 | f2 | | {EXTERNAL LOCATION} | String | -| constructors.swift:14:22:14:30 | "default" | | {EXTERNAL LOCATION} | String | -| constructors.swift:15:9:15:10 | f3 | | {EXTERNAL LOCATION} | Function | -| constructors.swift:15:9:15:10 | f3 | Args | {EXTERNAL LOCATION} | Tuple1 | -| constructors.swift:15:9:15:10 | f3 | Args.T0 | constructors.swift:12:11:12:11 | T | -| constructors.swift:15:9:15:10 | f3 | Return | constructors.swift:12:11:12:11 | T | -| constructors.swift:15:24:15:29 | FunctionExpr | | {EXTERNAL LOCATION} | Function | -| constructors.swift:18:5:18:7 | s11 | | constructors.swift:12:1:16:1 | S1 | -| constructors.swift:18:5:18:7 | s11 | T | {EXTERNAL LOCATION} | Int | -| constructors.swift:18:11:18:19 | S1(...) | | constructors.swift:12:1:16:1 | S1 | -| constructors.swift:18:11:18:19 | S1(...) | T | {EXTERNAL LOCATION} | Int | -| constructors.swift:18:18:18:18 | 0 | | {EXTERNAL LOCATION} | Int | -| constructors.swift:19:5:19:7 | s12 | | constructors.swift:12:1:16:1 | S1 | -| constructors.swift:19:5:19:7 | s12 | T | {EXTERNAL LOCATION} | Bool | -| constructors.swift:19:11:19:30 | S1(...) | | constructors.swift:12:1:16:1 | S1 | -| constructors.swift:19:11:19:30 | S1(...) | T | {EXTERNAL LOCATION} | Bool | -| constructors.swift:19:18:19:21 | true | | {EXTERNAL LOCATION} | Bool | -| constructors.swift:19:28:19:29 | "" | | {EXTERNAL LOCATION} | String | -| constructors.swift:20:1:20:33 | S1(...) | | constructors.swift:12:1:16:1 | S1 | -| constructors.swift:20:1:20:33 | S1(...) | T | {EXTERNAL LOCATION} | Int | -| constructors.swift:20:8:20:8 | 0 | | {EXTERNAL LOCATION} | Int | -| constructors.swift:20:15:20:16 | "" | | {EXTERNAL LOCATION} | String | -| constructors.swift:20:23:20:32 | FunctionExpr | | {EXTERNAL LOCATION} | Function | -| constructors.swift:20:23:20:32 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | -| constructors.swift:20:23:20:32 | FunctionExpr | Args.T0 | {EXTERNAL LOCATION} | Int | -| constructors.swift:20:23:20:32 | FunctionExpr | Return | {EXTERNAL LOCATION} | Int | -| constructors.swift:20:25:20:25 | x | | {EXTERNAL LOCATION} | Int | -| constructors.swift:20:30:20:30 | Block | | {EXTERNAL LOCATION} | Int | -| constructors.swift:20:30:20:30 | x | | {EXTERNAL LOCATION} | Int | +| constructors.swift:14:5:14:7 | c21 | | constructors.swift:12:1:12:15 | C2 | +| constructors.swift:14:11:14:14 | C2(...) | | constructors.swift:12:1:12:15 | C2 | +| constructors.swift:15:5:15:7 | c22 | | constructors.swift:1:1:7:1 | C1 | +| constructors.swift:15:11:15:19 | ... .init(...) | | constructors.swift:1:1:7:1 | C1 | +| constructors.swift:21:5:21:6 | c3 | | constructors.swift:17:1:19:1 | C3 | +| constructors.swift:21:10:21:13 | C3(...) | | constructors.swift:17:1:19:1 | C3 | +| constructors.swift:24:12:24:12 | x | | {EXTERNAL LOCATION} | Int | +| constructors.swift:24:20:26:5 | Block | | constructors.swift:17:1:19:1 | C3 | +| constructors.swift:25:9:25:13 | super | | constructors.swift:17:1:19:1 | C3 | +| constructors.swift:25:9:25:20 | ... .init(...) | | constructors.swift:17:1:19:1 | C3 | +| constructors.swift:28:33:30:5 | Block | | constructors.swift:23:1:31:1 | C4 | +| constructors.swift:29:9:29:12 | self | | constructors.swift:23:1:31:1 | C4 | +| constructors.swift:29:9:29:20 | ... .init(...) | | constructors.swift:23:1:31:1 | C4 | +| constructors.swift:29:19:29:19 | 0 | | {EXTERNAL LOCATION} | Int | +| constructors.swift:35:5:35:7 | c51 | | constructors.swift:33:1:33:15 | C5 | +| constructors.swift:35:11:35:14 | C5(...) | | constructors.swift:33:1:33:15 | C5 | +| constructors.swift:36:5:36:7 | c52 | | constructors.swift:33:1:33:15 | C5 | +| constructors.swift:36:11:36:15 | C5(...) | | constructors.swift:33:1:33:15 | C5 | +| constructors.swift:36:14:36:14 | 0 | | {EXTERNAL LOCATION} | Int | +| constructors.swift:39:10:39:10 | x | | constructors.swift:38:10:38:11 | T1 | +| constructors.swift:39:17:39:17 | y | | constructors.swift:38:14:38:15 | T2 | +| constructors.swift:41:18:41:18 | s | | {EXTERNAL LOCATION} | String | +| constructors.swift:43:22:43:22 | x | | constructors.swift:38:10:38:11 | T1 | +| constructors.swift:44:20:44:60 | "Convenience initializer not implemented" | | {EXTERNAL LOCATION} | String | +| constructors.swift:50:5:50:7 | c71 | | constructors.swift:48:1:48:31 | C7 | +| constructors.swift:50:11:50:34 | C7(...) | | constructors.swift:48:1:48:31 | C7 | +| constructors.swift:50:17:50:24 | "string" | | {EXTERNAL LOCATION} | String | +| constructors.swift:50:30:50:33 | true | | {EXTERNAL LOCATION} | Bool | +| constructors.swift:51:5:51:7 | c72 | | constructors.swift:48:1:48:31 | C7 | +| constructors.swift:51:5:51:7 | c72 | T3 | {EXTERNAL LOCATION} | Bool | +| constructors.swift:51:11:51:27 | ...(...) | | constructors.swift:48:1:48:31 | C7 | +| constructors.swift:51:11:51:27 | ...(...) | T3 | {EXTERNAL LOCATION} | Bool | +| constructors.swift:51:26:51:26 | 0 | | {EXTERNAL LOCATION} | Int | +| constructors.swift:54:22:54:22 | x | | {EXTERNAL LOCATION} | String | +| constructors.swift:54:33:56:5 | Block | | constructors.swift:38:1:46:1 | C6 | +| constructors.swift:54:33:56:5 | Block | | constructors.swift:53:1:57:1 | C8 | +| constructors.swift:54:33:56:5 | Block | T1 | {EXTERNAL LOCATION} | String | +| constructors.swift:54:33:56:5 | Block | T2 | {EXTERNAL LOCATION} | Int | +| constructors.swift:55:9:55:12 | self | | constructors.swift:53:1:57:1 | C8 | +| constructors.swift:55:9:55:29 | ... .init(...) | | constructors.swift:38:1:46:1 | C6 | +| constructors.swift:55:9:55:29 | ... .init(...) | | constructors.swift:53:1:57:1 | C8 | +| constructors.swift:55:9:55:29 | ... .init(...) | T1 | {EXTERNAL LOCATION} | String | +| constructors.swift:55:9:55:29 | ... .init(...) | T2 | {EXTERNAL LOCATION} | Int | +| constructors.swift:55:22:55:22 | x | | {EXTERNAL LOCATION} | String | +| constructors.swift:55:28:55:28 | 0 | | {EXTERNAL LOCATION} | Int | +| constructors.swift:61:5:61:7 | c91 | | constructors.swift:59:1:59:19 | C9 | +| constructors.swift:61:5:61:7 | c91 | T9 | {EXTERNAL LOCATION} | Int | +| constructors.swift:61:20:61:28 | C9(...) | | constructors.swift:59:1:59:19 | C9 | +| constructors.swift:61:26:61:27 | "" | | {EXTERNAL LOCATION} | String | +| constructors.swift:62:5:62:7 | c92 | | constructors.swift:59:1:59:19 | C9 | +| constructors.swift:62:5:62:7 | c92 | T9 | {EXTERNAL LOCATION} | Int | +| constructors.swift:62:11:62:24 | ...(...) | | constructors.swift:59:1:59:19 | C9 | +| constructors.swift:62:11:62:24 | ...(...) | T9 | {EXTERNAL LOCATION} | Int | +| constructors.swift:62:22:62:23 | "" | | {EXTERNAL LOCATION} | String | +| constructors.swift:66:5:66:7 | c10 | | constructors.swift:64:1:64:42 | C10 | +| constructors.swift:66:5:66:7 | c10 | T10b | {EXTERNAL LOCATION} | Int | +| constructors.swift:66:24:66:33 | C10(...) | | constructors.swift:64:1:64:42 | C10 | +| constructors.swift:66:31:66:32 | "" | | {EXTERNAL LOCATION} | String | +| constructors.swift:69:9:69:10 | f1 | | constructors.swift:68:11:68:11 | T | +| constructors.swift:70:9:70:10 | f2 | | {EXTERNAL LOCATION} | String | +| constructors.swift:70:22:70:30 | "default" | | {EXTERNAL LOCATION} | String | +| constructors.swift:71:9:71:10 | f3 | | {EXTERNAL LOCATION} | Function | +| constructors.swift:71:9:71:10 | f3 | Args | {EXTERNAL LOCATION} | Tuple1 | +| constructors.swift:71:9:71:10 | f3 | Args.T0 | constructors.swift:68:11:68:11 | T | +| constructors.swift:71:9:71:10 | f3 | Return | constructors.swift:68:11:68:11 | T | +| constructors.swift:71:24:71:29 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| constructors.swift:74:5:74:7 | s11 | | constructors.swift:68:1:72:1 | S1 | +| constructors.swift:74:5:74:7 | s11 | T | {EXTERNAL LOCATION} | Int | +| constructors.swift:74:11:74:19 | S1(...) | | constructors.swift:68:1:72:1 | S1 | +| constructors.swift:74:11:74:19 | S1(...) | T | {EXTERNAL LOCATION} | Int | +| constructors.swift:74:18:74:18 | 0 | | {EXTERNAL LOCATION} | Int | +| constructors.swift:75:5:75:7 | s12 | | constructors.swift:68:1:72:1 | S1 | +| constructors.swift:75:5:75:7 | s12 | T | {EXTERNAL LOCATION} | Bool | +| constructors.swift:75:11:75:30 | S1(...) | | constructors.swift:68:1:72:1 | S1 | +| constructors.swift:75:11:75:30 | S1(...) | T | {EXTERNAL LOCATION} | Bool | +| constructors.swift:75:18:75:21 | true | | {EXTERNAL LOCATION} | Bool | +| constructors.swift:75:28:75:29 | "" | | {EXTERNAL LOCATION} | String | +| constructors.swift:76:1:76:33 | S1(...) | | constructors.swift:68:1:72:1 | S1 | +| constructors.swift:76:1:76:33 | S1(...) | T | {EXTERNAL LOCATION} | Int | +| constructors.swift:76:8:76:8 | 0 | | {EXTERNAL LOCATION} | Int | +| constructors.swift:76:15:76:16 | "" | | {EXTERNAL LOCATION} | String | +| constructors.swift:76:23:76:32 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| constructors.swift:76:23:76:32 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| constructors.swift:76:23:76:32 | FunctionExpr | Args.T0 | {EXTERNAL LOCATION} | Int | +| constructors.swift:76:23:76:32 | FunctionExpr | Return | {EXTERNAL LOCATION} | Int | +| constructors.swift:76:25:76:25 | x | | {EXTERNAL LOCATION} | Int | +| constructors.swift:76:30:76:30 | Block | | {EXTERNAL LOCATION} | Int | +| constructors.swift:76:30:76:30 | x | | {EXTERNAL LOCATION} | Int | +| constructors.swift:77:1:77:25 | S1(...) | | constructors.swift:68:1:72:1 | S1 | +| constructors.swift:77:1:77:25 | S1(...) | T | {EXTERNAL LOCATION} | Int | +| constructors.swift:77:8:77:8 | 0 | | {EXTERNAL LOCATION} | Int | +| constructors.swift:77:15:77:24 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| constructors.swift:77:15:77:24 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| constructors.swift:83:13:83:14 | e1 | | constructors.swift:79:1:85:1 | E1 | +| constructors.swift:83:18:83:21 | a(...) | | constructors.swift:79:1:85:1 | E1 | +| constructors.swift:83:20:83:20 | 0 | | {EXTERNAL LOCATION} | Int | +| constructors.swift:89:5:89:6 | e2 | | constructors.swift:87:1:87:27 | E2 | +| constructors.swift:89:5:89:6 | e2 | A | {EXTERNAL LOCATION} | Int | +| constructors.swift:89:5:89:6 | e2 | B | {EXTERNAL LOCATION} | String | +| constructors.swift:89:25:89:31 | ... .a(...) | | constructors.swift:87:1:87:27 | E2 | +| constructors.swift:89:25:89:31 | ... .a(...) | A | {EXTERNAL LOCATION} | Int | +| constructors.swift:89:30:89:30 | 1 | | {EXTERNAL LOCATION} | Int | | fields.swift:2:7:2:20 | inheritedField | | {EXTERNAL LOCATION} | Int | | fields.swift:2:29:2:29 | 0 | | {EXTERNAL LOCATION} | Int | | fields.swift:6:7:6:17 | storedField | | {EXTERNAL LOCATION} | String | From 4898fef24cc48d819d1d04c64d690564a6b5a377 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 20 Oct 2026 10:33:29 +0200 Subject: [PATCH 6/6] Unified: Improve type inference for constructor calls --- .../codeql/unified/internal/ExprPositions.qll | 8 +- .../unified/internal/StaticNameBinding.qll | 16 ++ .../unified/internal/typeinference/Type.qll | 15 +- .../internal/typeinference/TypeInference.qll | 212 +++++++++++++++--- .../internal/typeinference/TypeMention.qll | 28 ++- .../type-inference/constructors.swift | 20 +- .../library-tests/type-inference/lub.swift | 2 +- .../type-inference/type-inference.expected | 168 +++++++++++++- 8 files changed, 402 insertions(+), 67 deletions(-) diff --git a/unified/ql/lib/codeql/unified/internal/ExprPositions.qll b/unified/ql/lib/codeql/unified/internal/ExprPositions.qll index 2b40902f5c78..820e6a277eae 100644 --- a/unified/ql/lib/codeql/unified/internal/ExprPositions.qll +++ b/unified/ql/lib/codeql/unified/internal/ExprPositions.qll @@ -36,13 +36,7 @@ predicate isInTypeContext(Expr expr) { or expr.getParent() instanceof TypeConstraint or - exists(Identifier id | id = NameBinding::getStaticBindingTargetFromRef(expr) | - id = any(ClassLikeDeclaration c).getNameNode() - or - id = any(TypeAliasDeclaration t).getNameNode() - or - id = any(TypeParameter t).getNameNode() - ) + exists(NameBinding::getTypeFromRef(expr)) or any(ExprPositionsPlugin p).isInTypeContext(expr) or diff --git a/unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll b/unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll index 60487c6c12a0..58fd36fc5512 100644 --- a/unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll +++ b/unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll @@ -810,6 +810,22 @@ NameBinding getStaticBindingTargetFromRef(AstNode access) { result = getStaticBindingTargetFromIdentifier(getIdentifierFromRef(access)) } +/** + * Gets the type being accessed by `access`, if any. + */ +Identifier getTypeFromRef(AstNode access) { + result = getStaticBindingTargetFromRef(access) and + ( + result = any(ClassLikeDeclaration c).getNameNode() + or + result = any(TypeAliasDeclaration t).getNameNode() + or + result = any(TypeParameter t).getNameNode() + or + result = any(AssociatedTypeDeclaration t).getNameNode() + ) +} + /** * Gets the name of the implicit receiver parameter in scope at `callable` (possibly declared by an outer callable). * diff --git a/unified/ql/lib/codeql/unified/internal/typeinference/Type.qll b/unified/ql/lib/codeql/unified/internal/typeinference/Type.qll index 934b6d90f6fc..181e129fc955 100644 --- a/unified/ql/lib/codeql/unified/internal/typeinference/Type.qll +++ b/unified/ql/lib/codeql/unified/internal/typeinference/Type.qll @@ -80,6 +80,9 @@ abstract private class TypeImpl extends TType { */ TypeParameter getATypeParameter() { result = this.getPositionalTypeParameter(_) } + /** Gets the name node of this type, if any. */ + abstract Identifier getNameNode(); + /** Gets a textual representation of this type. */ abstract string toString(); @@ -99,6 +102,8 @@ class ClassLikeDeclarationType extends TypeImpl, TClassLikeDeclarationType { string getName() { result = c.getName() } + override Identifier getNameNode() { result = c.getNameNode() } + override TypeParameter getPositionalTypeParameter(int i) { result = TTypeParameterType(c.getTypeParameter(i)) } @@ -117,7 +122,9 @@ class ClassLikeDeclarationType extends TypeImpl, TClassLikeDeclarationType { /** * A pseudo type that does not correspond to any concrete type in the source code. */ -abstract class PseudoType extends TypeImpl { } +abstract class PseudoType extends TypeImpl { + override Identifier getNameNode() { none() } +} /** * A type representing an unknown type. @@ -173,6 +180,8 @@ class TypeParameterType extends TypeParameter, TTypeParameterType { override ClassLikeDeclaration getDeclaringItem() { typeParam = result.getATypeParameter() } + override Identifier getNameNode() { result = typeParam.getNameNode() } + override string toString() { result = typeParam.getName() } override Location getLocation() { result = typeParam.getLocation() } @@ -192,6 +201,8 @@ class AssociatedTypeParameterType extends TypeParameter, TAssociatedTypeParamete override ClassLikeDeclaration getDeclaringItem() { result = c } + override Identifier getNameNode() { result = assocTypeDecl.getNameNode() } + override string toString() { if inherited = true then result = assocTypeDecl.getName() + " (inherited)" @@ -213,6 +224,8 @@ class UnknownTypeTypeParameter extends TypeParameter, TUnknownTypeTypeParameter override AstNode getDeclaringItem() { none() } + override Identifier getNameNode() { none() } + override TypeParameter getPositionalTypeParameter(int j) { none() } override string toString() { result = "unknown type parameter " + i } diff --git a/unified/ql/lib/codeql/unified/internal/typeinference/TypeInference.qll b/unified/ql/lib/codeql/unified/internal/typeinference/TypeInference.qll index 30f617990985..77805591b9ef 100644 --- a/unified/ql/lib/codeql/unified/internal/typeinference/TypeInference.qll +++ b/unified/ql/lib/codeql/unified/internal/typeinference/TypeInference.qll @@ -135,7 +135,11 @@ module Input3 implements InputSig3 { class AstNode = Unified::AstNode; class Expr extends Unified::Expr { - Expr() { isInAssignmentContext(this, _) or hasResultValue(this) } + Expr() { + isInAssignmentContext(this, _) or + hasResultValue(this) or + this = Construction::getSyntheticConstructionReceiver(_) + } } class Cast extends Expr, TypeCastExpr { @@ -270,6 +274,7 @@ module Input3 implements InputSig3 { pragma[nomagic] private predicate lookupMember0(MemberAccessExpr mae, ClassLikeDeclaration cls, string name) { + not exists(getStaticBindingTargetFromRef(mae)) and // if a static member can be resolved, use it cls = inferType(mae.getBase()).(ClassLikeDeclarationType).getClassLikeDeclaration() and name = mae.getMemberName() } @@ -393,12 +398,7 @@ module Input3 implements InputSig3 { ) } - override TypeMention getType() { - result = c.getReturnType() - or - c instanceof ConstructorDeclaration and - result = this.getDeclaringType() - } + override TypeMention getType() { result = c.getReturnType() } override Identifier getNameNode() { result = c.(AccessorDeclaration).getNameNode() @@ -456,26 +456,29 @@ module Input3 implements InputSig3 { class InvocationResolutionContext = Unit; + private TypeMention getQualifierTypeMention(CallExpr ce) { + result = ce.getCallee() + or + not ce.getCallee() instanceof TypeMention and + result = ce.getCallee().(MemberAccessExpr).getBase() + } + class Invocation extends Expr, CallExpr { - Type getTypeQualifier(TypePath path) { - exists(TypeMention tm | result = tm.getTypeAt(path) | - tm = super.getCallee() - or - not super.getCallee() instanceof TypeMention and - tm = super.getCallee().(MemberAccessExpr).getBase() - ) - } + Type getTypeQualifier(TypePath path) { result = getQualifierTypeMention(this).getTypeAt(path) } Type getTypeArgument(int i, TypePath path) { none() } - int getNumberOfArguments() { result = CallExpr.super.getNumberOfArguments() + 1 } - Expr getArgument(int i) { i = 0 and - exists(boolean isFunctionExprInvoke | exists(this.getTargetImpl(isFunctionExprInvoke)) | - if isFunctionExprInvoke = true - then result = CallExpr.super.getCallee() - else result = CallExpr.super.getCallee().(MemberAccessExpr).getBase() + ( + result = Construction::getSyntheticConstructionReceiver(this) + or + not exists(Construction::getSyntheticConstructionReceiver(this)) and + exists(boolean isFunctionExprInvoke | exists(this.getTargetImpl(isFunctionExprInvoke)) | + if isFunctionExprInvoke = true + then result = CallExpr.super.getCallee() + else result = CallExpr.super.getCallee().(MemberAccessExpr).getBase() + ) ) or result = CallExpr.super.getArgument(i - 1).getValue() @@ -488,13 +491,13 @@ module Input3 implements InputSig3 { result = getFunctionInvoke(t) } - private Callable getTargetViaStaticNameBinding() { + Callable getTargetViaStaticNameBinding() { exists(NameBinding b | b = getStaticBindingTargetFromRef(this.getCallee()) | // object creation (including enum constructors): `String(42)`, `Optional.Some(42)` - exists(ClassLikeDeclaration cls, ConstructorDeclaration init | + exists(ClassLikeDeclaration cls | cls.getNameNode() = b and - init = cls.getAMember() and - result.asCallable() = init + result.isInstanceMemberOf(cls, _) and + result.asCallable() instanceof ConstructorDeclaration ) or // call without explicit receiver: `foo(42)` @@ -535,13 +538,13 @@ module Input3 implements InputSig3 { result = inferType(invocation.(CallExpr).getCallee(), path) or exists(TypePath prefix, TypePath suffix, int j | - functionInvokeSignature(t, invocation.getNumberOfArguments() - 1, j, i, prefix) and + functionInvokeSignature(t, invocation.getNumberOfArguments(), j, i, prefix) and result = inferType(invocation.getArgument(j + 1), suffix) and path = prefix.append(suffix) ) ) or - // A call to a regular function or method + // A non-function-expression call exists(invocation.getTargetImpl(false)) and ( result = inferType(invocation.getArgument(i), path) @@ -612,6 +615,155 @@ module Input3 implements InputSig3 { ) } + predicate stepLanguageSpecificExtra(AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2) { + Construction::step(n1, prefix1, n2, prefix2) + } + + /** + * Provides logic for resolving types of constructor invocations. + * + * Constructors are treated as instance methods without return types, in order + * to be able to handle inherited constructors similar to ordinary instance + * methods: + * + * ```swift + * class A { + * init(x : Ta) { ... } + * } + * + * class B : A { } + * + * A.init(0); // (1) has type `A` + * B.init(.some(0)); // (2) has type `B` + * B(.none); // (3) has type `B` + * ``` + * + * Because the constructor calls are treated as normal instance method calls, + * we use the type qualifier to represent the receiver, and then allow for + * contextual type information to flow into the receiver: + * + * (1) The receiver has type `A`, `Ta` is inferred to be instantiated to `Int`, + * which is propagated directly back into the receiver. + * (2) The receiver has type `B`, `Ta` is inferred to be instantiated to `Int?` + * which in turn means `Tb` is inferred to be instantiated to `Int`, which + * is then propagated back into the receiver. + * (3) The receiver has type `B`, and no further type inference is needed. + */ + private module Construction { + /** + * Gets the AST node that is used to represent the receiver in a constructor + * invocation without an actual receiver. + */ + TypeMention getSyntheticConstructionReceiver(Invocation invocation) { + invocation.getTargetViaStaticNameBinding().asCallable() instanceof ConstructorDeclaration and + result = getQualifierTypeMention(invocation) + } + + private predicate constructionReceiver(Invocation i, Callable constructor, Expr receiver) { + constructor = i.getTargetImpl(_) and + constructor.asCallable() instanceof ConstructorDeclaration and + receiver = i.getArgument(0) + } + + /** + * Since we handle constructors as instance methods without return types, + * we need to explicitly handle constructors where (parts of) the type of + * the constructed object must be inferred from the context. + * + * Example: + * + * ```swift + * class C { + * init(x : T1) { ... } // `T2` must be inferred from the context + * } + * ``` + */ + private module ContextualConstructorReturnTypeInput implements + M3::ContextualTyping::ContextualReturnTypeInputSig + { + predicate callableHasTypeParameterAtReturnType(Callable c, TypePath path, TypeParameter tp) { + c.asCallable() instanceof ConstructorDeclaration and + tp = c.getDeclaringType().getTypeAt(path) + } + + Parameter getACallableParameter(Callable c) { + result = c.getParameter(_) and + not result.getParameterEx().isImplicitReceiverParameter(_) + } + } + + private module ContextualConstructorReturnType = + M3::ContextualTyping::ContextualReturnType; + + private predicate needsContextualTyping(Invocation i, TypePath path) { + exists(Callable constructor, Expr receiver, ClassLikeDeclarationType receiverType | + constructionReceiver(i, constructor, receiver) and + receiverType = inferType(receiver) + | + ContextualConstructorReturnType::needsContextualTyping(i, path) and + receiverType = constructor.getDeclaringType().getType() + or + // inherited constructor + exists( + ClassLikeDeclarationType declType, TypeAbstraction abs, TypeMention constraint, + TypeParameter tp + | + declType = constructor.getDeclaringType().getType() and + BaseTypes::rootTypesSatisfaction(receiverType, declType, abs, _, constraint) and + path = TypePath::singleton(tp) + | + // `A : B` + exists(TypePath path0 | + BaseTypes::conditionSatisfiesConstraintTypeAt(abs, _, constraint, path0, tp) and + ContextualConstructorReturnType::needsContextualTyping(i, path0) + ) + or + // `A : B` + tp = receiverType.getATypeParameter() and + not BaseTypes::conditionSatisfiesConstraintTypeAt(abs, _, constraint, _, tp) and + not exists(Type t | t = i.getTypeQualifier(path) and not t instanceof PseudoType) + ) + ) + } + + /** + * Propagate type information from the receiver of a construction to the construction + * itself. + * + * Note that this works both for calls with synthetic receivers, `A.init(0)` or `A(0)`, + * as well as calls receivers, `self.init(0)` or `super.init(0)`. + */ + predicate step(AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2) { + constructionReceiver(n2, _, n1) and + prefix1.isEmpty() and + prefix2.isEmpty() + } + + Type inferType(AstNode n, TypePath path) { + n = + any(TypeMention tm | + tm = getSyntheticConstructionReceiver(_) and + result = tm.getTypeAt(path) + ) + or + needsContextualTyping(n, path) and + result instanceof UnknownType + } + + predicate allowFullContextualInference(TypeMention tm, TypePath path) { + // For a construction such as `Optional.some(0)`, we need contextual inference + // to infer the type of the wrapped object + tm = getSyntheticConstructionReceiver(_) and + exists(TypePath prefix, Type t, TypeParameter tp | + t = tm.getTypeAt(prefix) and + not t instanceof UnknownType and + tp = t.getATypeParameter() and + path = TypePath::snoc(prefix, tp) and + not exists(tm.getTypeAt(path)) + ) + } + } + Type inferTypeLanguageSpecific(AstNode n, TypePath path) { result = Plugin::inferType(n, path) or @@ -650,10 +802,16 @@ module Input3 implements InputSig3 { n.(ArrayLiteral).getNumberOfElements() = 0 and path = TypePath::singleton(getArrayElementTypeParameter()) and result instanceof UnknownType + or + result = Construction::inferType(n, path) } pragma[nomagic] Type inferTypeCertainLanguageSpecific(AstNode n, TypePath path) { none() } + + predicate allowFullContextualInference(AstNode n, TypePath path) { + Construction::allowFullContextualInference(n, path) + } } private module M3 = Make3; diff --git a/unified/ql/lib/codeql/unified/internal/typeinference/TypeMention.qll b/unified/ql/lib/codeql/unified/internal/typeinference/TypeMention.qll index 99d12990044b..aa48459feeb0 100644 --- a/unified/ql/lib/codeql/unified/internal/typeinference/TypeMention.qll +++ b/unified/ql/lib/codeql/unified/internal/typeinference/TypeMention.qll @@ -21,18 +21,10 @@ abstract private class TypeMentionImpl extends AstNode { final Type getType() { result = this.getTypeAt(TypePath::nil()) } } -private Type resolveType(Identifier access) { - exists(NameBinding b | b = getStaticBindingTargetFromIdentifier(access) | - b = result.(ClassLikeDeclarationType).getClassLikeDeclaration().getNameNode() - or - b = result.(TypeParameterType).getTypeParameter().getNameNode() - ) -} - final class ExprTypeMention = ExprTypeMentionImpl; abstract private class ExprTypeMentionImpl extends TypeMentionImpl, Expr { - ExprTypeMentionImpl() { isInTypeContext(this) } + ExprTypeMentionImpl() { isInTypeContext(this) and not this instanceof GenericTypeExpr } pragma[nomagic] abstract TypePath getTypeArgumentPath(int i); @@ -44,7 +36,7 @@ abstract private class ExprTypeMentionImpl extends TypeMentionImpl, Expr { private class AliasExprTypeMention extends ExprTypeMentionImpl { private TypeAliasDeclaration alias; - AliasExprTypeMention() { alias.getNameNode() = getStaticBindingTargetFromRef(this) } + AliasExprTypeMention() { alias.getNameNode() = getTypeFromRef(this) } private TypeParameterType getAliasTypeParameter(int i) { result.getTypeParameter() = alias.getTypeParameter(i) @@ -70,7 +62,21 @@ private class NonAliasExprTypeMention extends ExprTypeMentionImpl { NonAliasExprTypeMention() { not this instanceof AliasExprTypeMention } private Type getRootType0() { - result = resolveType(this) + exists(Identifier i | i = getTypeFromRef(this) | + // for now, we resolve enum cases to their enclosing class + exists(EnumCaseClass c | + i = c.getNameNode() and + result.getNameNode() = c.getEnclosingClass().getNameNode() + ) + or + not i = any(EnumCaseClass c).getNameNode() and + result.getNameNode() = i and + ( + not result instanceof AssociatedTypeParameterType + or + result = TAssociatedTypeParameterType(this.getEnclosingClass(), _, _) + ) + ) or result = Plugin::getFunctionExprType(this) or diff --git a/unified/ql/test/library-tests/type-inference/constructors.swift b/unified/ql/test/library-tests/type-inference/constructors.swift index 04930cbe2eed..42d366f6399b 100644 --- a/unified/ql/test/library-tests/type-inference/constructors.swift +++ b/unified/ql/test/library-tests/type-inference/constructors.swift @@ -11,8 +11,8 @@ var c12 = C1.init() // $ type=c12:C1 target=C1.init_conv $ SPURIOUS: target=C1. class C2: C1 {} // inherits `init` -var c21 = C2() // $ type=c21:C2 $ MISSING: target=C1.init_conv $ SPURIOUS: target=C2.init -var c22 = C2.init() // $ target=C1.init_conv $ MISSING: type=c22:C2 $ SPURIOUS: target=C1.init +var c21 = C2() // $ type=c21:C2 target=C1.init_conv $ SPURIOUS: target=C1.init +var c22 = C2.init() // $ target=C1.init_conv type=c22:C2 $ SPURIOUS: target=C1.init class C3 { init() {} @@ -32,8 +32,8 @@ class C4: C3 { class C5: C4 {} // inherits `init` and `convenience init` -var c51 = C5() // $ type=c51:C5 $ MISSING: target=C4.init $ SPURIOUS: target=C5.init -var c52 = C5(0) // $ type=c52:C5 $ MISSING: target=C4.init $ SPURIOUS: target=C5.init +var c51 = C5() // $ type=c51:C5 target=C4.init_conv $ SPURIOUS: target=C4.init +var c52 = C5(0) // $ type=c52:C5 target=C4.init $ SPURIOUS: target=C4.init_conv class C6 { init(x: T1, y: T2) {} @@ -47,8 +47,8 @@ class C6 { class C7: C6 {} // inherits `init(x: T4, y: T3)` and `convenience init(x: T4)` -var c71 = C7(x: "string", y: true) // $ MISSING: type=c71@C7:Bool type=c71@C7:String target=C6.init $ SPURIOUS: target=C7.init -var c72 = C7(x: 0) // $ type=c72@C7:Bool $ MISSING: type=c72@C7:Int target=C6.init $ SPURIOUS: target=C7.init +var c71 = C7(x: "string", y: true) // $ type=c71@C7:Bool type=c71@C7:String target=C6.init $ SPURIOUS: target=C6.init_conv +var c72 = C7(x: 0) // $ type=c72@C7:Bool type=c72@C7:Int target=C6.init_conv $ SPURIOUS: target=C6.init class C8: C7 { // inherits `init(x: String, y: Int)` convenience init(x: String) { // name=C8.init_conv @@ -58,12 +58,12 @@ class C8: C7 { // inherits `init(x: String, y: Int)` class C9: C8 {} -let c91: C9 = C9(x: "") // $ MISSING: type=C9(...)@C9:Int target=C8.init_conv $ SPURIOUS: target=C9.init -let c92 = C9(x: "") // $ type=C9<...>(...)@C9:Int $ MISSING: target=C8.init_conv $ SPURIOUS: target=C9.init +let c91: C9 = C9(x: "") // $ type=C9(...)@C9:Int target=C8.init_conv $ SPURIOUS: target=C6.init +let c92 = C9(x: "") // $ type=C9<...>(...)@C9:Int target=C8.init_conv $ SPURIOUS: target=C6.init class C10: C6 {} -let c10: C10<_, Int> = C10(x: "") // $ MISSING: type=C10(...)@C10:Int target=C6.init_conv $ SPURIOUS: target=C10.init +let c10: C10<_, Int> = C10(x: "") // $ target=C6.init_conv $ SPURIOUS: target=C6.init $ MISSING: type=C10(...)@C10:Int -- we currently incorrectly conclude that a type argument has been supplied for `C6.T2`, which means contextual inference is disabled struct S1 { // implicit `init(f1: T, f2: String = "default", f3: (T) -> T = { $0 })` var f1: T @@ -86,4 +86,4 @@ enum E1 { enum E2 { case a(A) } -let e2: E2<_, String> = E2.a(1) // $ target=E2.a $ MISSING: type=.a(...)@E2:String +let e2: E2<_, String> = E2.a(1) // $ target=E2.a type=.a(...)@E2:String diff --git a/unified/ql/test/library-tests/type-inference/lub.swift b/unified/ql/test/library-tests/type-inference/lub.swift index f8f9ed711523..066d654a1a93 100644 --- a/unified/ql/test/library-tests/type-inference/lub.swift +++ b/unified/ql/test/library-tests/type-inference/lub.swift @@ -10,6 +10,6 @@ class C: A {} func foo() { let b = B() // $ type=b:B target=B.init - let c = C() // $ type=c:C target=C.init + let c = C() // $ type=c:C target=A.init let x = 2 > 3 ? b : c // $ MISSING: type=x:A } diff --git a/unified/ql/test/library-tests/type-inference/type-inference.expected b/unified/ql/test/library-tests/type-inference/type-inference.expected index 3f9b33d68956..1ffd1d078e97 100644 --- a/unified/ql/test/library-tests/type-inference/type-inference.expected +++ b/unified/ql/test/library-tests/type-inference/type-inference.expected @@ -725,6 +725,8 @@ inferType | basics.swift:40:19:40:19 | 0 | | {EXTERNAL LOCATION} | Int | | basics.swift:45:7:45:7 | g | | basics.swift:27:1:36:1 | Generic | | basics.swift:45:7:45:7 | g | T | {EXTERNAL LOCATION} | Int | +| basics.swift:45:11:45:17 | Generic | | basics.swift:27:1:36:1 | Generic | +| basics.swift:45:11:45:17 | Generic | T | {EXTERNAL LOCATION} | Int | | basics.swift:45:11:45:24 | Generic(...) | | basics.swift:27:1:36:1 | Generic | | basics.swift:45:11:45:24 | Generic(...) | T | {EXTERNAL LOCATION} | Int | | basics.swift:45:22:45:23 | 42 | | {EXTERNAL LOCATION} | Int | @@ -733,6 +735,7 @@ inferType | basics.swift:46:11:46:11 | g | T | {EXTERNAL LOCATION} | Int | | basics.swift:46:11:46:22 | ... .getValue(...) | | {EXTERNAL LOCATION} | Int | | basics.swift:48:7:48:8 | gd | | basics.swift:38:1:42:1 | GenericDerived | +| basics.swift:48:12:48:25 | GenericDerived | | basics.swift:38:1:42:1 | GenericDerived | | basics.swift:48:12:48:27 | GenericDerived(...) | | basics.swift:38:1:42:1 | GenericDerived | | basics.swift:49:7:49:7 | y | | {EXTERNAL LOCATION} | Int | | basics.swift:49:11:49:12 | gd | | basics.swift:38:1:42:1 | GenericDerived | @@ -742,6 +745,7 @@ inferType | basics.swift:56:12:56:20 | ... * ... | | {EXTERNAL LOCATION} | Int | | basics.swift:56:20:56:20 | 2 | | {EXTERNAL LOCATION} | Int | | basics.swift:61:7:61:9 | obj | | basics.swift:5:1:14:1 | C | +| basics.swift:61:13:61:13 | C | | basics.swift:5:1:14:1 | C | | basics.swift:61:13:61:20 | C(...) | | basics.swift:5:1:14:1 | C | | basics.swift:61:18:61:19 | 10 | | {EXTERNAL LOCATION} | Int | | basics.swift:62:7:62:7 | d | | {EXTERNAL LOCATION} | Int | @@ -774,6 +778,7 @@ inferType | classes.swift:25:39:27:3 | Block | | {EXTERNAL LOCATION} | String | | classes.swift:26:12:26:12 | s | | {EXTERNAL LOCATION} | String | | classes.swift:31:7:31:7 | o | | classes.swift:20:1:28:1 | Overloaded | +| classes.swift:31:11:31:20 | Overloaded | | classes.swift:20:1:28:1 | Overloaded | | classes.swift:31:11:31:22 | Overloaded(...) | | classes.swift:20:1:28:1 | Overloaded | | classes.swift:32:7:32:8 | r1 | | {EXTERNAL LOCATION} | Int | | classes.swift:32:7:32:8 | r1 | | {EXTERNAL LOCATION} | String | @@ -810,6 +815,7 @@ inferType | classes.swift:46:12:46:15 | data | Element | {EXTERNAL LOCATION} | Array | | classes.swift:46:12:46:15 | data | Element.Element | {EXTERNAL LOCATION} | Int | | classes.swift:51:7:51:7 | m | | classes.swift:38:1:48:1 | Matrix | +| classes.swift:51:11:51:16 | Matrix | | classes.swift:38:1:48:1 | Matrix | | classes.swift:51:11:51:40 | Matrix(...) | | classes.swift:38:1:48:1 | Matrix | | classes.swift:51:24:51:39 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | | classes.swift:51:24:51:39 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Array | @@ -836,6 +842,7 @@ inferType | classes.swift:66:14:66:17 | self | | classes.swift:58:3:68:3 | Inner | | classes.swift:66:14:66:23 | ... .value | | {EXTERNAL LOCATION} | Int | | classes.swift:72:7:72:11 | inner | | classes.swift:58:3:68:3 | Inner | +| classes.swift:72:15:72:25 | ... .Inner | | classes.swift:58:3:68:3 | Inner | | classes.swift:72:15:72:36 | ... .Inner(...) | | classes.swift:58:3:68:3 | Inner | | classes.swift:72:34:72:35 | 99 | | {EXTERNAL LOCATION} | Int | | classes.swift:73:7:73:7 | v | | {EXTERNAL LOCATION} | Int | @@ -858,6 +865,7 @@ inferType | classes.swift:91:23:93:3 | Block | | {EXTERNAL LOCATION} | Int | | classes.swift:92:12:92:16 | value | | {EXTERNAL LOCATION} | Int | | classes.swift:97:7:97:7 | b | | classes.swift:78:1:94:1 | Builder | +| classes.swift:97:11:97:17 | Builder | | classes.swift:78:1:94:1 | Builder | | classes.swift:97:11:97:19 | Builder(...) | | classes.swift:78:1:94:1 | Builder | | classes.swift:98:7:98:12 | result | | {EXTERNAL LOCATION} | Int | | classes.swift:98:16:98:16 | b | | classes.swift:78:1:94:1 | Builder | @@ -873,6 +881,7 @@ inferType | classes.swift:104:63:106:3 | Block | | {EXTERNAL LOCATION} | Int | | classes.swift:105:12:105:18 | retries | | {EXTERNAL LOCATION} | Int | | classes.swift:110:7:110:9 | cfg | | classes.swift:103:1:107:1 | Config | +| classes.swift:110:13:110:18 | Config | | classes.swift:103:1:107:1 | Config | | classes.swift:110:13:110:20 | Config(...) | | classes.swift:103:1:107:1 | Config | | classes.swift:111:7:111:8 | r1 | | {EXTERNAL LOCATION} | Int | | classes.swift:111:12:111:14 | cfg | | classes.swift:103:1:107:1 | Config | @@ -904,6 +913,7 @@ inferType | classes.swift:130:28:130:30 | 5.0 | | {EXTERNAL LOCATION} | Double | | classes.swift:130:34:130:37 | 32.0 | | {EXTERNAL LOCATION} | Double | | classes.swift:135:7:135:7 | t | | classes.swift:118:1:132:1 | Temperature | +| classes.swift:135:11:135:21 | Temperature | | classes.swift:118:1:132:1 | Temperature | | classes.swift:135:11:135:37 | Temperature(...) | | classes.swift:118:1:132:1 | Temperature | | classes.swift:135:32:135:36 | 100.0 | | {EXTERNAL LOCATION} | Double | | classes.swift:136:7:136:7 | c | | {EXTERNAL LOCATION} | Double | @@ -927,6 +937,7 @@ inferType | classes.swift:167:35:169:3 | Block | | {EXTERNAL LOCATION} | String | | classes.swift:168:12:168:17 | "Meow" | | {EXTERNAL LOCATION} | String | | classes.swift:173:7:173:7 | d | | classes.swift:148:1:160:1 | Dog | +| classes.swift:173:11:173:13 | Dog | | classes.swift:148:1:160:1 | Dog | | classes.swift:173:11:173:15 | Dog(...) | | classes.swift:148:1:160:1 | Dog | | classes.swift:174:7:174:8 | ds | | {EXTERNAL LOCATION} | String | | classes.swift:174:12:174:12 | d | | classes.swift:148:1:160:1 | Dog | @@ -935,6 +946,7 @@ inferType | classes.swift:175:12:175:12 | d | | classes.swift:148:1:160:1 | Dog | | classes.swift:175:12:175:20 | ... .fetch(...) | | {EXTERNAL LOCATION} | String | | classes.swift:177:7:177:8 | ct | | classes.swift:162:1:170:1 | Cat | +| classes.swift:177:12:177:14 | Cat | | classes.swift:162:1:170:1 | Cat | | classes.swift:177:12:177:16 | Cat(...) | | classes.swift:162:1:170:1 | Cat | | classes.swift:178:7:178:8 | cs | | {EXTERNAL LOCATION} | String | | classes.swift:178:12:178:13 | ct | | classes.swift:162:1:170:1 | Cat | @@ -948,6 +960,7 @@ inferType | classes.swift:190:26:192:3 | Block | | {EXTERNAL LOCATION} | Int | | classes.swift:191:12:191:16 | count | | {EXTERNAL LOCATION} | Int | | classes.swift:196:7:196:9 | ctr | | classes.swift:183:1:193:1 | Counter | +| classes.swift:196:13:196:19 | Counter | | classes.swift:183:1:193:1 | Counter | | classes.swift:196:13:196:21 | Counter(...) | | classes.swift:183:1:193:1 | Counter | | classes.swift:197:3:197:5 | ctr | | classes.swift:183:1:193:1 | Counter | | classes.swift:198:7:198:9 | val | | {EXTERNAL LOCATION} | Int | @@ -1009,6 +1022,7 @@ inferType | closures.swift:19:38:21:5 | FunctionExpr | Args.T0 | {EXTERNAL LOCATION} | Int | | closures.swift:19:38:21:5 | FunctionExpr | Return | {EXTERNAL LOCATION} | String | | closures.swift:19:40:19:44 | value | | {EXTERNAL LOCATION} | Int | +| closures.swift:20:9:20:14 | String | | {EXTERNAL LOCATION} | String | | closures.swift:20:9:20:21 | Block | | {EXTERNAL LOCATION} | String | | closures.swift:20:9:20:21 | String(...) | | {EXTERNAL LOCATION} | String | | closures.swift:20:16:20:20 | value | | {EXTERNAL LOCATION} | Int | @@ -1080,6 +1094,7 @@ inferType | closures.swift:55:31:57:5 | FunctionExpr | Args.T0 | {EXTERNAL LOCATION} | Int | | closures.swift:55:31:57:5 | FunctionExpr | Return | {EXTERNAL LOCATION} | String | | closures.swift:55:33:55:33 | x | | {EXTERNAL LOCATION} | Int | +| closures.swift:56:9:56:14 | String | | {EXTERNAL LOCATION} | String | | closures.swift:56:9:56:17 | Block | | {EXTERNAL LOCATION} | String | | closures.swift:56:9:56:17 | String(...) | | {EXTERNAL LOCATION} | String | | closures.swift:56:16:56:16 | x | | {EXTERNAL LOCATION} | Int | @@ -1103,6 +1118,7 @@ inferType | closures.swift:66:9:68:9 | FunctionExpr | Args.T0 | {EXTERNAL LOCATION} | Int | | closures.swift:66:9:68:9 | FunctionExpr | Return | {EXTERNAL LOCATION} | String | | closures.swift:66:11:66:15 | value | | {EXTERNAL LOCATION} | Int | +| closures.swift:67:13:67:18 | String | | {EXTERNAL LOCATION} | String | | closures.swift:67:13:67:25 | Block | | {EXTERNAL LOCATION} | String | | closures.swift:67:13:67:25 | String(...) | | {EXTERNAL LOCATION} | String | | closures.swift:67:20:67:24 | value | | {EXTERNAL LOCATION} | Int | @@ -1116,14 +1132,19 @@ inferType | constructors.swift:5:9:5:20 | ... .init(...) | | constructors.swift:1:1:7:1 | C1 | | constructors.swift:5:19:5:19 | 0 | | {EXTERNAL LOCATION} | Int | | constructors.swift:9:5:9:7 | c11 | | constructors.swift:1:1:7:1 | C1 | +| constructors.swift:9:11:9:12 | C1 | | constructors.swift:1:1:7:1 | C1 | | constructors.swift:9:11:9:14 | C1(...) | | constructors.swift:1:1:7:1 | C1 | | constructors.swift:10:5:10:7 | c12 | | constructors.swift:1:1:7:1 | C1 | +| constructors.swift:10:11:10:12 | C1 | | constructors.swift:1:1:7:1 | C1 | | constructors.swift:10:11:10:19 | ... .init(...) | | constructors.swift:1:1:7:1 | C1 | | constructors.swift:14:5:14:7 | c21 | | constructors.swift:12:1:12:15 | C2 | +| constructors.swift:14:11:14:12 | C2 | | constructors.swift:12:1:12:15 | C2 | | constructors.swift:14:11:14:14 | C2(...) | | constructors.swift:12:1:12:15 | C2 | -| constructors.swift:15:5:15:7 | c22 | | constructors.swift:1:1:7:1 | C1 | -| constructors.swift:15:11:15:19 | ... .init(...) | | constructors.swift:1:1:7:1 | C1 | +| constructors.swift:15:5:15:7 | c22 | | constructors.swift:12:1:12:15 | C2 | +| constructors.swift:15:11:15:12 | C2 | | constructors.swift:12:1:12:15 | C2 | +| constructors.swift:15:11:15:19 | ... .init(...) | | constructors.swift:12:1:12:15 | C2 | | constructors.swift:21:5:21:6 | c3 | | constructors.swift:17:1:19:1 | C3 | +| constructors.swift:21:10:21:11 | C3 | | constructors.swift:17:1:19:1 | C3 | | constructors.swift:21:10:21:13 | C3(...) | | constructors.swift:17:1:19:1 | C3 | | constructors.swift:24:12:24:12 | x | | {EXTERNAL LOCATION} | Int | | constructors.swift:24:20:26:5 | Block | | constructors.swift:17:1:19:1 | C3 | @@ -1134,8 +1155,10 @@ inferType | constructors.swift:29:9:29:20 | ... .init(...) | | constructors.swift:23:1:31:1 | C4 | | constructors.swift:29:19:29:19 | 0 | | {EXTERNAL LOCATION} | Int | | constructors.swift:35:5:35:7 | c51 | | constructors.swift:33:1:33:15 | C5 | +| constructors.swift:35:11:35:12 | C5 | | constructors.swift:33:1:33:15 | C5 | | constructors.swift:35:11:35:14 | C5(...) | | constructors.swift:33:1:33:15 | C5 | | constructors.swift:36:5:36:7 | c52 | | constructors.swift:33:1:33:15 | C5 | +| constructors.swift:36:11:36:12 | C5 | | constructors.swift:33:1:33:15 | C5 | | constructors.swift:36:11:36:15 | C5(...) | | constructors.swift:33:1:33:15 | C5 | | constructors.swift:36:14:36:14 | 0 | | {EXTERNAL LOCATION} | Int | | constructors.swift:39:10:39:10 | x | | constructors.swift:38:10:38:11 | T1 | @@ -1144,38 +1167,53 @@ inferType | constructors.swift:43:22:43:22 | x | | constructors.swift:38:10:38:11 | T1 | | constructors.swift:44:20:44:60 | "Convenience initializer not implemented" | | {EXTERNAL LOCATION} | String | | constructors.swift:50:5:50:7 | c71 | | constructors.swift:48:1:48:31 | C7 | +| constructors.swift:50:5:50:7 | c71 | T3 | {EXTERNAL LOCATION} | Bool | +| constructors.swift:50:5:50:7 | c71 | T4 | {EXTERNAL LOCATION} | String | +| constructors.swift:50:11:50:12 | C7 | | constructors.swift:48:1:48:31 | C7 | +| constructors.swift:50:11:50:12 | C7 | T3 | {EXTERNAL LOCATION} | Bool | +| constructors.swift:50:11:50:12 | C7 | T4 | {EXTERNAL LOCATION} | String | | constructors.swift:50:11:50:34 | C7(...) | | constructors.swift:48:1:48:31 | C7 | +| constructors.swift:50:11:50:34 | C7(...) | T3 | {EXTERNAL LOCATION} | Bool | +| constructors.swift:50:11:50:34 | C7(...) | T4 | {EXTERNAL LOCATION} | String | | constructors.swift:50:17:50:24 | "string" | | {EXTERNAL LOCATION} | String | | constructors.swift:50:30:50:33 | true | | {EXTERNAL LOCATION} | Bool | | constructors.swift:51:5:51:7 | c72 | | constructors.swift:48:1:48:31 | C7 | | constructors.swift:51:5:51:7 | c72 | T3 | {EXTERNAL LOCATION} | Bool | +| constructors.swift:51:5:51:7 | c72 | T4 | {EXTERNAL LOCATION} | Int | +| constructors.swift:51:11:51:21 | GenericTypeExpr | | constructors.swift:48:1:48:31 | C7 | +| constructors.swift:51:11:51:21 | GenericTypeExpr | T3 | {EXTERNAL LOCATION} | Bool | +| constructors.swift:51:11:51:21 | GenericTypeExpr | T4 | {EXTERNAL LOCATION} | Int | | constructors.swift:51:11:51:27 | ...(...) | | constructors.swift:48:1:48:31 | C7 | | constructors.swift:51:11:51:27 | ...(...) | T3 | {EXTERNAL LOCATION} | Bool | +| constructors.swift:51:11:51:27 | ...(...) | T4 | {EXTERNAL LOCATION} | Int | | constructors.swift:51:26:51:26 | 0 | | {EXTERNAL LOCATION} | Int | | constructors.swift:54:22:54:22 | x | | {EXTERNAL LOCATION} | String | -| constructors.swift:54:33:56:5 | Block | | constructors.swift:38:1:46:1 | C6 | | constructors.swift:54:33:56:5 | Block | | constructors.swift:53:1:57:1 | C8 | -| constructors.swift:54:33:56:5 | Block | T1 | {EXTERNAL LOCATION} | String | -| constructors.swift:54:33:56:5 | Block | T2 | {EXTERNAL LOCATION} | Int | | constructors.swift:55:9:55:12 | self | | constructors.swift:53:1:57:1 | C8 | -| constructors.swift:55:9:55:29 | ... .init(...) | | constructors.swift:38:1:46:1 | C6 | | constructors.swift:55:9:55:29 | ... .init(...) | | constructors.swift:53:1:57:1 | C8 | -| constructors.swift:55:9:55:29 | ... .init(...) | T1 | {EXTERNAL LOCATION} | String | -| constructors.swift:55:9:55:29 | ... .init(...) | T2 | {EXTERNAL LOCATION} | Int | | constructors.swift:55:22:55:22 | x | | {EXTERNAL LOCATION} | String | | constructors.swift:55:28:55:28 | 0 | | {EXTERNAL LOCATION} | Int | | constructors.swift:61:5:61:7 | c91 | | constructors.swift:59:1:59:19 | C9 | | constructors.swift:61:5:61:7 | c91 | T9 | {EXTERNAL LOCATION} | Int | +| constructors.swift:61:20:61:21 | C9 | | constructors.swift:59:1:59:19 | C9 | +| constructors.swift:61:20:61:21 | C9 | T9 | {EXTERNAL LOCATION} | Int | | constructors.swift:61:20:61:28 | C9(...) | | constructors.swift:59:1:59:19 | C9 | +| constructors.swift:61:20:61:28 | C9(...) | T9 | {EXTERNAL LOCATION} | Int | | constructors.swift:61:26:61:27 | "" | | {EXTERNAL LOCATION} | String | | constructors.swift:62:5:62:7 | c92 | | constructors.swift:59:1:59:19 | C9 | | constructors.swift:62:5:62:7 | c92 | T9 | {EXTERNAL LOCATION} | Int | +| constructors.swift:62:11:62:17 | GenericTypeExpr | | constructors.swift:59:1:59:19 | C9 | +| constructors.swift:62:11:62:17 | GenericTypeExpr | T9 | {EXTERNAL LOCATION} | Int | | constructors.swift:62:11:62:24 | ...(...) | | constructors.swift:59:1:59:19 | C9 | | constructors.swift:62:11:62:24 | ...(...) | T9 | {EXTERNAL LOCATION} | Int | | constructors.swift:62:22:62:23 | "" | | {EXTERNAL LOCATION} | String | | constructors.swift:66:5:66:7 | c10 | | constructors.swift:64:1:64:42 | C10 | +| constructors.swift:66:5:66:7 | c10 | T10a | {EXTERNAL LOCATION} | String | | constructors.swift:66:5:66:7 | c10 | T10b | {EXTERNAL LOCATION} | Int | +| constructors.swift:66:24:66:26 | C10 | | constructors.swift:64:1:64:42 | C10 | +| constructors.swift:66:24:66:26 | C10 | T10a | {EXTERNAL LOCATION} | String | | constructors.swift:66:24:66:33 | C10(...) | | constructors.swift:64:1:64:42 | C10 | +| constructors.swift:66:24:66:33 | C10(...) | T10a | {EXTERNAL LOCATION} | String | | constructors.swift:66:31:66:32 | "" | | {EXTERNAL LOCATION} | String | | constructors.swift:69:9:69:10 | f1 | | constructors.swift:68:11:68:11 | T | | constructors.swift:70:9:70:10 | f2 | | {EXTERNAL LOCATION} | String | @@ -1187,15 +1225,21 @@ inferType | constructors.swift:71:24:71:29 | FunctionExpr | | {EXTERNAL LOCATION} | Function | | constructors.swift:74:5:74:7 | s11 | | constructors.swift:68:1:72:1 | S1 | | constructors.swift:74:5:74:7 | s11 | T | {EXTERNAL LOCATION} | Int | +| constructors.swift:74:11:74:12 | S1 | | constructors.swift:68:1:72:1 | S1 | +| constructors.swift:74:11:74:12 | S1 | T | {EXTERNAL LOCATION} | Int | | constructors.swift:74:11:74:19 | S1(...) | | constructors.swift:68:1:72:1 | S1 | | constructors.swift:74:11:74:19 | S1(...) | T | {EXTERNAL LOCATION} | Int | | constructors.swift:74:18:74:18 | 0 | | {EXTERNAL LOCATION} | Int | | constructors.swift:75:5:75:7 | s12 | | constructors.swift:68:1:72:1 | S1 | | constructors.swift:75:5:75:7 | s12 | T | {EXTERNAL LOCATION} | Bool | +| constructors.swift:75:11:75:12 | S1 | | constructors.swift:68:1:72:1 | S1 | +| constructors.swift:75:11:75:12 | S1 | T | {EXTERNAL LOCATION} | Bool | | constructors.swift:75:11:75:30 | S1(...) | | constructors.swift:68:1:72:1 | S1 | | constructors.swift:75:11:75:30 | S1(...) | T | {EXTERNAL LOCATION} | Bool | | constructors.swift:75:18:75:21 | true | | {EXTERNAL LOCATION} | Bool | | constructors.swift:75:28:75:29 | "" | | {EXTERNAL LOCATION} | String | +| constructors.swift:76:1:76:2 | S1 | | constructors.swift:68:1:72:1 | S1 | +| constructors.swift:76:1:76:2 | S1 | T | {EXTERNAL LOCATION} | Int | | constructors.swift:76:1:76:33 | S1(...) | | constructors.swift:68:1:72:1 | S1 | | constructors.swift:76:1:76:33 | S1(...) | T | {EXTERNAL LOCATION} | Int | | constructors.swift:76:8:76:8 | 0 | | {EXTERNAL LOCATION} | Int | @@ -1207,19 +1251,26 @@ inferType | constructors.swift:76:25:76:25 | x | | {EXTERNAL LOCATION} | Int | | constructors.swift:76:30:76:30 | Block | | {EXTERNAL LOCATION} | Int | | constructors.swift:76:30:76:30 | x | | {EXTERNAL LOCATION} | Int | +| constructors.swift:77:1:77:2 | S1 | | constructors.swift:68:1:72:1 | S1 | +| constructors.swift:77:1:77:2 | S1 | T | {EXTERNAL LOCATION} | Int | | constructors.swift:77:1:77:25 | S1(...) | | constructors.swift:68:1:72:1 | S1 | | constructors.swift:77:1:77:25 | S1(...) | T | {EXTERNAL LOCATION} | Int | | constructors.swift:77:8:77:8 | 0 | | {EXTERNAL LOCATION} | Int | | constructors.swift:77:15:77:24 | FunctionExpr | | {EXTERNAL LOCATION} | Function | | constructors.swift:77:15:77:24 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | | constructors.swift:83:13:83:14 | e1 | | constructors.swift:79:1:85:1 | E1 | +| constructors.swift:83:18:83:18 | a | | constructors.swift:79:1:85:1 | E1 | | constructors.swift:83:18:83:21 | a(...) | | constructors.swift:79:1:85:1 | E1 | | constructors.swift:83:20:83:20 | 0 | | {EXTERNAL LOCATION} | Int | | constructors.swift:89:5:89:6 | e2 | | constructors.swift:87:1:87:27 | E2 | | constructors.swift:89:5:89:6 | e2 | A | {EXTERNAL LOCATION} | Int | | constructors.swift:89:5:89:6 | e2 | B | {EXTERNAL LOCATION} | String | +| constructors.swift:89:25:89:28 | ... .a | | constructors.swift:87:1:87:27 | E2 | +| constructors.swift:89:25:89:28 | ... .a | A | {EXTERNAL LOCATION} | Int | +| constructors.swift:89:25:89:28 | ... .a | B | {EXTERNAL LOCATION} | String | | constructors.swift:89:25:89:31 | ... .a(...) | | constructors.swift:87:1:87:27 | E2 | | constructors.swift:89:25:89:31 | ... .a(...) | A | {EXTERNAL LOCATION} | Int | +| constructors.swift:89:25:89:31 | ... .a(...) | B | {EXTERNAL LOCATION} | String | | constructors.swift:89:30:89:30 | 1 | | {EXTERNAL LOCATION} | Int | | fields.swift:2:7:2:20 | inheritedField | | {EXTERNAL LOCATION} | Int | | fields.swift:2:29:2:29 | 0 | | {EXTERNAL LOCATION} | Int | @@ -1245,6 +1296,8 @@ inferType | fields.swift:31:7:31:12 | nested | | fields.swift:26:1:28:1 | NestedField | | fields.swift:35:7:35:15 | container | | fields.swift:5:1:20:1 | FieldContainer | | fields.swift:35:7:35:15 | container | T | {EXTERNAL LOCATION} | Int | +| fields.swift:35:19:35:32 | FieldContainer | | fields.swift:5:1:20:1 | FieldContainer | +| fields.swift:35:19:35:32 | FieldContainer | T | {EXTERNAL LOCATION} | Int | | fields.swift:35:19:35:50 | FieldContainer(...) | | fields.swift:5:1:20:1 | FieldContainer | | fields.swift:35:19:35:50 | FieldContainer(...) | T | {EXTERNAL LOCATION} | Int | | fields.swift:35:48:35:49 | 42 | | {EXTERNAL LOCATION} | Int | @@ -1263,7 +1316,9 @@ inferType | fields.swift:39:7:39:17 | staticValue | | {EXTERNAL LOCATION} | Bool | | fields.swift:39:21:39:52 | ... .staticField | | {EXTERNAL LOCATION} | Bool | | fields.swift:41:7:41:11 | outer | | fields.swift:30:1:32:1 | OuterField | +| fields.swift:41:15:41:24 | OuterField | | fields.swift:30:1:32:1 | OuterField | | fields.swift:41:15:41:57 | OuterField(...) | | fields.swift:30:1:32:1 | OuterField | +| fields.swift:41:34:41:44 | NestedField | | fields.swift:26:1:28:1 | NestedField | | fields.swift:41:34:41:56 | NestedField(...) | | fields.swift:26:1:28:1 | NestedField | | fields.swift:41:53:41:55 | 1.0 | | {EXTERNAL LOCATION} | Double | | fields.swift:42:7:42:17 | nestedValue | | {EXTERNAL LOCATION} | Double | @@ -1321,6 +1376,9 @@ inferType | generics.swift:38:7:38:7 | p | | generics.swift:19:1:35:1 | Pair | | generics.swift:38:7:38:7 | p | A | {EXTERNAL LOCATION} | Int | | generics.swift:38:7:38:7 | p | B | {EXTERNAL LOCATION} | String | +| generics.swift:38:11:38:14 | Pair | | generics.swift:19:1:35:1 | Pair | +| generics.swift:38:11:38:14 | Pair | A | {EXTERNAL LOCATION} | Int | +| generics.swift:38:11:38:14 | Pair | B | {EXTERNAL LOCATION} | String | | generics.swift:38:11:38:37 | Pair(...) | | generics.swift:19:1:35:1 | Pair | | generics.swift:38:11:38:37 | Pair(...) | A | {EXTERNAL LOCATION} | Int | | generics.swift:38:11:38:37 | Pair(...) | B | {EXTERNAL LOCATION} | String | @@ -1344,6 +1402,8 @@ inferType | generics.swift:53:10:53:17 | ... .failure | T | generics.swift:45:13:45:13 | T | | generics.swift:60:7:60:7 | r | | generics.swift:45:1:57:1 | Result | | generics.swift:60:7:60:7 | r | T | {EXTERNAL LOCATION} | Int | +| generics.swift:60:11:60:24 | ... .success | | generics.swift:45:1:57:1 | Result | +| generics.swift:60:11:60:24 | ... .success | T | {EXTERNAL LOCATION} | Int | | generics.swift:60:11:60:28 | ... .success(...) | | generics.swift:45:1:57:1 | Result | | generics.swift:60:11:60:28 | ... .success(...) | T | {EXTERNAL LOCATION} | Int | | generics.swift:60:26:60:27 | 42 | | {EXTERNAL LOCATION} | Int | @@ -1396,6 +1456,7 @@ inferType | generics.swift:78:5:80:5 | FunctionExpr | Args.T0 | {EXTERNAL LOCATION} | Int | | generics.swift:78:5:80:5 | FunctionExpr | Return | {EXTERNAL LOCATION} | String | | generics.swift:79:7:79:7 | x | | {EXTERNAL LOCATION} | Int | +| generics.swift:79:12:79:17 | String | | {EXTERNAL LOCATION} | String | | generics.swift:79:12:79:20 | Block | | {EXTERNAL LOCATION} | String | | generics.swift:79:12:79:20 | String(...) | | {EXTERNAL LOCATION} | String | | generics.swift:79:19:79:19 | x | | {EXTERNAL LOCATION} | Int | @@ -1419,6 +1480,8 @@ inferType | generics.swift:123:12:123:19 | "number" | | {EXTERNAL LOCATION} | String | | generics.swift:128:7:128:7 | w | | generics.swift:93:1:113:1 | Wrapper | | generics.swift:128:7:128:7 | w | T | {EXTERNAL LOCATION} | Int | +| generics.swift:128:11:128:17 | Wrapper | | generics.swift:93:1:113:1 | Wrapper | +| generics.swift:128:11:128:17 | Wrapper | T | {EXTERNAL LOCATION} | Int | | generics.swift:128:11:128:21 | Wrapper(...) | | generics.swift:93:1:113:1 | Wrapper | | generics.swift:128:11:128:21 | Wrapper(...) | T | {EXTERNAL LOCATION} | Int | | generics.swift:128:19:128:20 | 42 | | {EXTERNAL LOCATION} | Int | @@ -1519,6 +1582,9 @@ inferType | generics.swift:197:7:197:7 | d | | generics.swift:154:1:162:1 | Derived | | generics.swift:197:7:197:7 | d | T1 | {EXTERNAL LOCATION} | Int | | generics.swift:197:7:197:7 | d | T2 | {EXTERNAL LOCATION} | String | +| generics.swift:197:11:197:17 | Derived | | generics.swift:154:1:162:1 | Derived | +| generics.swift:197:11:197:17 | Derived | T1 | {EXTERNAL LOCATION} | Int | +| generics.swift:197:11:197:17 | Derived | T2 | {EXTERNAL LOCATION} | String | | generics.swift:197:11:197:25 | Derived(...) | | generics.swift:154:1:162:1 | Derived | | generics.swift:197:11:197:25 | Derived(...) | T1 | {EXTERNAL LOCATION} | Int | | generics.swift:197:11:197:25 | Derived(...) | T2 | {EXTERNAL LOCATION} | String | @@ -1536,6 +1602,8 @@ inferType | generics.swift:199:12:199:24 | ... .getValue2(...) | | {EXTERNAL LOCATION} | Int | | generics.swift:201:7:201:8 | dd | | generics.swift:164:1:172:1 | DerivedDerived | | generics.swift:201:7:201:8 | dd | D | {EXTERNAL LOCATION} | String | +| generics.swift:201:12:201:25 | DerivedDerived | | generics.swift:164:1:172:1 | DerivedDerived | +| generics.swift:201:12:201:25 | DerivedDerived | D | {EXTERNAL LOCATION} | String | | generics.swift:201:12:201:36 | DerivedDerived(...) | | generics.swift:164:1:172:1 | DerivedDerived | | generics.swift:201:12:201:36 | DerivedDerived(...) | D | {EXTERNAL LOCATION} | String | | generics.swift:201:27:201:35 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | @@ -1559,6 +1627,8 @@ inferType | generics.swift:205:22:205:24 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | | generics.swift:205:22:205:24 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int | | generics.swift:205:23:205:23 | 2 | | {EXTERNAL LOCATION} | Int | +| generics.swift:205:27:205:40 | DerivedDerived | | generics.swift:164:1:172:1 | DerivedDerived | +| generics.swift:205:27:205:40 | DerivedDerived | D | {EXTERNAL LOCATION} | Int | | generics.swift:205:27:205:44 | DerivedDerived(...) | | generics.swift:164:1:172:1 | DerivedDerived | | generics.swift:205:27:205:44 | DerivedDerived(...) | D | {EXTERNAL LOCATION} | Int | | generics.swift:205:42:205:43 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | @@ -1567,6 +1637,8 @@ inferType | generics.swift:207:15:207:17 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | | generics.swift:207:15:207:17 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int | | generics.swift:207:16:207:16 | 2 | | {EXTERNAL LOCATION} | Int | +| generics.swift:207:20:207:33 | DerivedDerived | | generics.swift:164:1:172:1 | DerivedDerived | +| generics.swift:207:20:207:33 | DerivedDerived | D | {EXTERNAL LOCATION} | Int | | generics.swift:207:20:207:37 | DerivedDerived(...) | | generics.swift:164:1:172:1 | DerivedDerived | | generics.swift:207:20:207:37 | DerivedDerived(...) | D | {EXTERNAL LOCATION} | Int | | generics.swift:207:35:207:36 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | @@ -1577,12 +1649,16 @@ inferType | generics.swift:209:11:209:43 | bar(...) | D | {EXTERNAL LOCATION} | Int | | generics.swift:209:15:209:19 | false | | {EXTERNAL LOCATION} | Bool | | generics.swift:209:22:209:22 | 2 | | {EXTERNAL LOCATION} | Int | +| generics.swift:209:25:209:38 | DerivedDerived | | generics.swift:164:1:172:1 | DerivedDerived | +| generics.swift:209:25:209:38 | DerivedDerived | D | {EXTERNAL LOCATION} | Int | | generics.swift:209:25:209:42 | DerivedDerived(...) | | generics.swift:164:1:172:1 | DerivedDerived | | generics.swift:209:25:209:42 | DerivedDerived(...) | D | {EXTERNAL LOCATION} | Int | | generics.swift:209:40:209:41 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | | generics.swift:209:40:209:41 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int | | generics.swift:211:8:211:12 | false | | {EXTERNAL LOCATION} | Bool | | generics.swift:211:15:211:15 | 2 | | {EXTERNAL LOCATION} | Int | +| generics.swift:211:18:211:31 | DerivedDerived | | generics.swift:164:1:172:1 | DerivedDerived | +| generics.swift:211:18:211:31 | DerivedDerived | D | {EXTERNAL LOCATION} | Int | | generics.swift:211:18:211:35 | DerivedDerived(...) | | generics.swift:164:1:172:1 | DerivedDerived | | generics.swift:211:18:211:35 | DerivedDerived(...) | D | {EXTERNAL LOCATION} | Int | | generics.swift:211:33:211:34 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | @@ -1597,16 +1673,26 @@ inferType | generics.swift:213:11:213:47 | baz(...) | T2 | {EXTERNAL LOCATION} | Bool | | generics.swift:213:15:213:19 | false | | {EXTERNAL LOCATION} | Bool | | generics.swift:213:22:213:22 | 2 | | {EXTERNAL LOCATION} | Int | +| generics.swift:213:25:213:31 | Derived | | generics.swift:154:1:162:1 | Derived | +| generics.swift:213:25:213:31 | Derived | T1 | {EXTERNAL LOCATION} | Optional | +| generics.swift:213:25:213:31 | Derived | T1.Wrapped | {EXTERNAL LOCATION} | Int | +| generics.swift:213:25:213:31 | Derived | T2 | {EXTERNAL LOCATION} | Bool | | generics.swift:213:25:213:46 | Derived(...) | | generics.swift:154:1:162:1 | Derived | | generics.swift:213:25:213:46 | Derived(...) | T1 | {EXTERNAL LOCATION} | Optional | | generics.swift:213:25:213:46 | Derived(...) | T1.Wrapped | {EXTERNAL LOCATION} | Int | +| generics.swift:213:25:213:46 | Derived(...) | T2 | {EXTERNAL LOCATION} | Bool | | generics.swift:213:33:213:45 | ... .none | | {EXTERNAL LOCATION} | Optional | | generics.swift:213:33:213:45 | ... .none | Wrapped | {EXTERNAL LOCATION} | Int | | generics.swift:215:8:215:12 | false | | {EXTERNAL LOCATION} | Bool | | generics.swift:215:15:215:15 | 2 | | {EXTERNAL LOCATION} | Int | +| generics.swift:215:18:215:24 | Derived | | generics.swift:154:1:162:1 | Derived | +| generics.swift:215:18:215:24 | Derived | T1 | {EXTERNAL LOCATION} | Optional | +| generics.swift:215:18:215:24 | Derived | T1.Wrapped | {EXTERNAL LOCATION} | Int | +| generics.swift:215:18:215:24 | Derived | T2 | {EXTERNAL LOCATION} | Bool | | generics.swift:215:18:215:39 | Derived(...) | | generics.swift:154:1:162:1 | Derived | | generics.swift:215:18:215:39 | Derived(...) | T1 | {EXTERNAL LOCATION} | Optional | | generics.swift:215:18:215:39 | Derived(...) | T1.Wrapped | {EXTERNAL LOCATION} | Int | +| generics.swift:215:18:215:39 | Derived(...) | T2 | {EXTERNAL LOCATION} | Bool | | generics.swift:215:26:215:38 | ... .none | | {EXTERNAL LOCATION} | Optional | | generics.swift:215:26:215:38 | ... .none | Wrapped | {EXTERNAL LOCATION} | Int | | generics.swift:227:22:229:3 | Block | | generics.swift:220:1:224:1 | MyProtocol2 | @@ -1625,6 +1711,8 @@ inferType | generics.swift:253:10:253:10 | c | | generics.swift:252:14:252:27 | T | | generics.swift:257:7:257:7 | c | | generics.swift:232:1:238:1 | MyClass | | generics.swift:257:7:257:7 | c | T | {EXTERNAL LOCATION} | Int | +| generics.swift:257:11:257:17 | MyClass | | generics.swift:232:1:238:1 | MyClass | +| generics.swift:257:11:257:17 | MyClass | T | {EXTERNAL LOCATION} | Int | | generics.swift:257:11:257:21 | MyClass(...) | | generics.swift:232:1:238:1 | MyClass | | generics.swift:257:11:257:21 | MyClass(...) | T | {EXTERNAL LOCATION} | Int | | generics.swift:257:19:257:20 | 42 | | {EXTERNAL LOCATION} | Int | @@ -1640,11 +1728,13 @@ inferType | generics.swift:283:12:283:16 | "sub" | | {EXTERNAL LOCATION} | String | | generics.swift:287:65:287:69 | value | | generics.swift:287:33:287:60 | T | | generics.swift:288:10:288:14 | value | | generics.swift:287:33:287:60 | T | +| generics.swift:292:42:292:61 | StringAssociatedType | | generics.swift:275:1:285:1 | StringAssociatedType | | generics.swift:292:42:292:63 | StringAssociatedType(...) | | generics.swift:275:1:285:1 | StringAssociatedType | | generics.swift:306:25:308:3 | Block | | {EXTERNAL LOCATION} | Int | | generics.swift:307:12:307:13 | 42 | | {EXTERNAL LOCATION} | Int | | generics.swift:316:7:316:11 | value | | {EXTERNAL LOCATION} | Int | | generics.swift:316:15:316:66 | getPrimaryAssociatedType(...) | | {EXTERNAL LOCATION} | Int | +| generics.swift:316:40:316:63 | IntPrimaryAssociatedType | | generics.swift:303:1:309:1 | IntPrimaryAssociatedType | | generics.swift:316:40:316:65 | IntPrimaryAssociatedType(...) | | generics.swift:303:1:309:1 | IntPrimaryAssociatedType | | key_paths.swift:4:7:4:7 | x | | {EXTERNAL LOCATION} | Double | | key_paths.swift:5:7:5:7 | y | | {EXTERNAL LOCATION} | Double | @@ -1680,20 +1770,24 @@ inferType | key_paths.swift:23:5:23:18 | ... = ... | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:23:16:23:18 | end | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:31:7:31:7 | p | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:31:11:31:15 | Point | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:31:11:31:31 | Point(...) | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:31:20:31:22 | 3.0 | | {EXTERNAL LOCATION} | Double | | key_paths.swift:31:28:31:30 | 4.0 | | {EXTERNAL LOCATION} | Double | | key_paths.swift:32:14:32:14 | p | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:33:14:33:14 | p | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:42:7:42:7 | s | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:42:11:42:15 | Point | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:42:11:42:31 | Point(...) | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:42:20:42:22 | 0.0 | | {EXTERNAL LOCATION} | Double | | key_paths.swift:42:28:42:30 | 0.0 | | {EXTERNAL LOCATION} | Double | | key_paths.swift:43:7:43:7 | e | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:43:11:43:15 | Point | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:43:11:43:31 | Point(...) | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:43:20:43:22 | 1.0 | | {EXTERNAL LOCATION} | Double | | key_paths.swift:43:28:43:30 | 1.0 | | {EXTERNAL LOCATION} | Double | | key_paths.swift:44:7:44:10 | line | | key_paths.swift:17:1:25:1 | Line | +| key_paths.swift:44:14:44:17 | Line | | key_paths.swift:17:1:25:1 | Line | | key_paths.swift:44:14:44:35 | Line(...) | | key_paths.swift:17:1:25:1 | Line | | key_paths.swift:44:26:44:26 | s | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:44:34:44:34 | e | | key_paths.swift:3:1:15:1 | Point | @@ -1733,10 +1827,12 @@ inferType | key_paths.swift:74:5:74:18 | ... = ... | | {EXTERNAL LOCATION} | String | | key_paths.swift:74:16:74:18 | zip | | {EXTERNAL LOCATION} | String | | key_paths.swift:80:7:80:10 | addr | | key_paths.swift:68:1:76:1 | Address | +| key_paths.swift:80:14:80:20 | Address | | key_paths.swift:68:1:76:1 | Address | | key_paths.swift:80:14:80:47 | Address(...) | | key_paths.swift:68:1:76:1 | Address | | key_paths.swift:80:28:80:32 | "NYC" | | {EXTERNAL LOCATION} | String | | key_paths.swift:80:40:80:46 | "10001" | | {EXTERNAL LOCATION} | String | | key_paths.swift:81:7:81:12 | person | | key_paths.swift:58:1:66:1 | Person | +| key_paths.swift:81:16:81:21 | Person | | key_paths.swift:58:1:66:1 | Person | | key_paths.swift:81:16:81:51 | Person(...) | | key_paths.swift:58:1:66:1 | Person | | key_paths.swift:81:29:81:35 | "Alice" | | {EXTERNAL LOCATION} | String | | key_paths.swift:81:47:81:50 | addr | | key_paths.swift:68:1:76:1 | Address | @@ -1759,19 +1855,19 @@ inferType | key_paths.swift:98:39:98:45 | keyPath | unknown type parameter 0 | key_paths.swift:98:19:98:19 | T | | key_paths.swift:98:39:98:45 | keyPath | unknown type parameter 1 | key_paths.swift:98:22:98:22 | V | | key_paths.swift:98:70:100:1 | Block | | {EXTERNAL LOCATION} | Array | -| key_paths.swift:98:70:100:1 | Block | Element | key_paths.swift:98:22:98:22 | V | | key_paths.swift:99:10:99:14 | items | | {EXTERNAL LOCATION} | Array | | key_paths.swift:99:10:99:14 | items | Element | key_paths.swift:98:19:98:19 | T | | key_paths.swift:99:10:99:43 | ... .map(...) | | {EXTERNAL LOCATION} | Array | -| key_paths.swift:99:10:99:43 | ... .map(...) | Element | key_paths.swift:98:22:98:22 | V | | key_paths.swift:99:20:99:43 | FunctionExpr | | {EXTERNAL LOCATION} | Function | | key_paths.swift:99:34:99:40 | keyPath | unknown type parameter 0 | key_paths.swift:98:19:98:19 | T | | key_paths.swift:99:34:99:40 | keyPath | unknown type parameter 1 | key_paths.swift:98:22:98:22 | V | | key_paths.swift:103:7:103:8 | e1 | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:103:12:103:19 | Employee | | key_paths.swift:88:1:96:1 | Employee | | key_paths.swift:103:12:103:47 | Employee(...) | | key_paths.swift:88:1:96:1 | Employee | | key_paths.swift:103:27:103:33 | "Alice" | | {EXTERNAL LOCATION} | String | | key_paths.swift:103:44:103:46 | 100 | | {EXTERNAL LOCATION} | Int | | key_paths.swift:104:7:104:8 | e2 | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:104:12:104:19 | Employee | | key_paths.swift:88:1:96:1 | Employee | | key_paths.swift:104:12:104:45 | Employee(...) | | key_paths.swift:88:1:96:1 | Employee | | key_paths.swift:104:27:104:31 | "Bob" | | {EXTERNAL LOCATION} | String | | key_paths.swift:104:42:104:44 | 200 | | {EXTERNAL LOCATION} | Int | @@ -1803,12 +1899,15 @@ inferType | key_paths.swift:118:17:118:20 | item | | key_paths.swift:114:19:114:19 | T | | key_paths.swift:124:7:124:7 | c | | key_paths.swift:114:1:120:1 | KPContainer | | key_paths.swift:124:7:124:7 | c | T | {EXTERNAL LOCATION} | Int | +| key_paths.swift:124:11:124:21 | KPContainer | | key_paths.swift:114:1:120:1 | KPContainer | +| key_paths.swift:124:11:124:21 | KPContainer | T | {EXTERNAL LOCATION} | Int | | key_paths.swift:124:11:124:31 | KPContainer(...) | | key_paths.swift:114:1:120:1 | KPContainer | | key_paths.swift:124:11:124:31 | KPContainer(...) | T | {EXTERNAL LOCATION} | Int | | key_paths.swift:124:29:124:30 | 42 | | {EXTERNAL LOCATION} | Int | | key_paths.swift:125:11:125:11 | c | | key_paths.swift:114:1:120:1 | KPContainer | | key_paths.swift:125:11:125:11 | c | T | {EXTERNAL LOCATION} | Int | | key_paths.swift:131:7:131:7 | p | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:131:11:131:15 | Point | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:131:11:131:31 | Point(...) | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:131:20:131:22 | 1.0 | | {EXTERNAL LOCATION} | Double | | key_paths.swift:131:28:131:30 | 2.0 | | {EXTERNAL LOCATION} | Double | @@ -1818,23 +1917,28 @@ inferType | key_paths.swift:133:21:133:24 | 10.0 | | {EXTERNAL LOCATION} | Double | | key_paths.swift:134:14:134:14 | p | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:144:7:144:7 | s | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:144:11:144:15 | Point | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:144:11:144:31 | Point(...) | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:144:20:144:22 | 5.0 | | {EXTERNAL LOCATION} | Double | | key_paths.swift:144:28:144:30 | 6.0 | | {EXTERNAL LOCATION} | Double | | key_paths.swift:145:7:145:7 | e | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:145:11:145:15 | Point | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:145:11:145:31 | Point(...) | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:145:20:145:22 | 7.0 | | {EXTERNAL LOCATION} | Double | | key_paths.swift:145:28:145:30 | 8.0 | | {EXTERNAL LOCATION} | Double | | key_paths.swift:146:7:146:10 | line | | key_paths.swift:17:1:25:1 | Line | +| key_paths.swift:146:14:146:17 | Line | | key_paths.swift:17:1:25:1 | Line | | key_paths.swift:146:14:146:35 | Line(...) | | key_paths.swift:17:1:25:1 | Line | | key_paths.swift:146:26:146:26 | s | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:146:34:146:34 | e | | key_paths.swift:3:1:15:1 | Point | | key_paths.swift:147:13:147:16 | line | | key_paths.swift:17:1:25:1 | Line | | key_paths.swift:153:7:153:8 | e1 | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:153:12:153:19 | Employee | | key_paths.swift:88:1:96:1 | Employee | | key_paths.swift:153:12:153:47 | Employee(...) | | key_paths.swift:88:1:96:1 | Employee | | key_paths.swift:153:27:153:33 | "Alice" | | {EXTERNAL LOCATION} | String | | key_paths.swift:153:44:153:46 | 100 | | {EXTERNAL LOCATION} | Int | | key_paths.swift:154:7:154:8 | e2 | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:154:12:154:19 | Employee | | key_paths.swift:88:1:96:1 | Employee | | key_paths.swift:154:12:154:45 | Employee(...) | | key_paths.swift:88:1:96:1 | Employee | | key_paths.swift:154:27:154:31 | "Bob" | | {EXTERNAL LOCATION} | String | | key_paths.swift:154:42:154:44 | 200 | | {EXTERNAL LOCATION} | Int | @@ -1875,6 +1979,7 @@ inferType | key_paths.swift:177:5:177:28 | ... .init(...) | | key_paths.swift:164:1:170:1 | Shape2 | | key_paths.swift:177:23:177:27 | color | | {EXTERNAL LOCATION} | String | | key_paths.swift:185:7:185:7 | c | | key_paths.swift:172:1:179:1 | Circle2 | +| key_paths.swift:185:11:185:17 | Circle2 | | key_paths.swift:172:1:179:1 | Circle2 | | key_paths.swift:185:11:185:44 | Circle2(...) | | key_paths.swift:172:1:179:1 | Circle2 | | key_paths.swift:185:26:185:30 | "red" | | {EXTERNAL LOCATION} | String | | key_paths.swift:185:41:185:43 | 5.0 | | {EXTERNAL LOCATION} | Double | @@ -1908,8 +2013,10 @@ inferType | key_paths.swift:208:23:208:25 | "y" | | {EXTERNAL LOCATION} | String | | key_paths.swift:208:28:208:28 | 2 | | {EXTERNAL LOCATION} | Int | | lub.swift:12:7:12:7 | b | | lub.swift:5:1:7:1 | B | +| lub.swift:12:11:12:11 | B | | lub.swift:5:1:7:1 | B | | lub.swift:12:11:12:13 | B(...) | | lub.swift:5:1:7:1 | B | | lub.swift:13:7:13:7 | c | | lub.swift:9:1:9:13 | C | +| lub.swift:13:11:13:11 | C | | lub.swift:9:1:9:13 | C | | lub.swift:13:11:13:13 | C(...) | | lub.swift:9:1:9:13 | C | | lub.swift:14:7:14:7 | x | | lub.swift:5:1:7:1 | B | | lub.swift:14:7:14:7 | x | | lub.swift:9:1:9:13 | C | @@ -1933,6 +2040,7 @@ inferType | overload_resolution.swift:16:36:18:3 | Block | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:17:12:17:17 | "bool" | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:22:7:22:7 | o | | overload_resolution.swift:3:1:19:1 | OverloadByType | +| overload_resolution.swift:22:11:22:24 | OverloadByType | | overload_resolution.swift:3:1:19:1 | OverloadByType | | overload_resolution.swift:22:11:22:26 | OverloadByType(...) | | overload_resolution.swift:3:1:19:1 | OverloadByType | | overload_resolution.swift:23:7:23:8 | r1 | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:23:12:23:12 | o | | overload_resolution.swift:3:1:19:1 | OverloadByType | @@ -1964,6 +2072,7 @@ inferType | overload_resolution.swift:44:39:46:3 | Block | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:45:12:45:17 | "size" | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:50:7:50:7 | o | | overload_resolution.swift:31:1:47:1 | OverloadByLabel | +| overload_resolution.swift:50:11:50:25 | OverloadByLabel | | overload_resolution.swift:31:1:47:1 | OverloadByLabel | | overload_resolution.swift:50:11:50:27 | OverloadByLabel(...) | | overload_resolution.swift:31:1:47:1 | OverloadByLabel | | overload_resolution.swift:51:7:51:8 | r1 | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:51:12:51:12 | o | | overload_resolution.swift:31:1:47:1 | OverloadByLabel | @@ -2003,6 +2112,7 @@ inferType | overload_resolution.swift:73:16:73:16 | y | | {EXTERNAL LOCATION} | Int | | overload_resolution.swift:73:20:73:20 | z | | {EXTERNAL LOCATION} | Int | | overload_resolution.swift:78:7:78:7 | o | | overload_resolution.swift:59:1:75:1 | OverloadByArity | +| overload_resolution.swift:78:11:78:25 | OverloadByArity | | overload_resolution.swift:59:1:75:1 | OverloadByArity | | overload_resolution.swift:78:11:78:27 | OverloadByArity(...) | | overload_resolution.swift:59:1:75:1 | OverloadByArity | | overload_resolution.swift:79:7:79:8 | r0 | | {EXTERNAL LOCATION} | Int | | overload_resolution.swift:79:12:79:12 | o | | overload_resolution.swift:59:1:75:1 | OverloadByArity | @@ -2029,6 +2139,7 @@ inferType | overload_resolution.swift:96:27:98:3 | Block | | {EXTERNAL LOCATION} | Double | | overload_resolution.swift:97:12:97:14 | 0.0 | | {EXTERNAL LOCATION} | Double | | overload_resolution.swift:102:7:102:7 | o | | overload_resolution.swift:87:1:99:1 | OverloadByReturn | +| overload_resolution.swift:102:11:102:26 | OverloadByReturn | | overload_resolution.swift:87:1:99:1 | OverloadByReturn | | overload_resolution.swift:102:11:102:28 | OverloadByReturn(...) | | overload_resolution.swift:87:1:99:1 | OverloadByReturn | | overload_resolution.swift:103:7:103:8 | r1 | | {EXTERNAL LOCATION} | Int | | overload_resolution.swift:103:17:103:17 | o | | overload_resolution.swift:87:1:99:1 | OverloadByReturn | @@ -2052,6 +2163,7 @@ inferType | overload_resolution.swift:115:37:117:3 | Block | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:116:12:116:20 | "generic" | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:121:7:121:7 | o | | overload_resolution.swift:110:1:118:1 | OverloadGenericVsConcrete | +| overload_resolution.swift:121:11:121:35 | OverloadGenericVsConcrete | | overload_resolution.swift:110:1:118:1 | OverloadGenericVsConcrete | | overload_resolution.swift:121:11:121:37 | OverloadGenericVsConcrete(...) | | overload_resolution.swift:110:1:118:1 | OverloadGenericVsConcrete | | overload_resolution.swift:122:7:122:8 | r1 | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:122:12:122:12 | o | | overload_resolution.swift:110:1:118:1 | OverloadGenericVsConcrete | @@ -2107,14 +2219,18 @@ inferType | overload_resolution.swift:168:29:170:3 | Block | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:169:12:169:16 | value | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:174:7:174:8 | m1 | | overload_resolution.swift:149:1:171:1 | MultiInit | +| overload_resolution.swift:174:12:174:20 | MultiInit | | overload_resolution.swift:149:1:171:1 | MultiInit | | overload_resolution.swift:174:12:174:22 | MultiInit(...) | | overload_resolution.swift:149:1:171:1 | MultiInit | | overload_resolution.swift:175:7:175:8 | m2 | | overload_resolution.swift:149:1:171:1 | MultiInit | +| overload_resolution.swift:175:12:175:20 | MultiInit | | overload_resolution.swift:149:1:171:1 | MultiInit | | overload_resolution.swift:175:12:175:28 | MultiInit(...) | | overload_resolution.swift:149:1:171:1 | MultiInit | | overload_resolution.swift:175:27:175:27 | 5 | | {EXTERNAL LOCATION} | Int | | overload_resolution.swift:176:7:176:8 | m3 | | overload_resolution.swift:149:1:171:1 | MultiInit | +| overload_resolution.swift:176:12:176:20 | MultiInit | | overload_resolution.swift:149:1:171:1 | MultiInit | | overload_resolution.swift:176:12:176:30 | MultiInit(...) | | overload_resolution.swift:149:1:171:1 | MultiInit | | overload_resolution.swift:176:27:176:29 | "x" | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:177:7:177:8 | m4 | | overload_resolution.swift:149:1:171:1 | MultiInit | +| overload_resolution.swift:177:12:177:20 | MultiInit | | overload_resolution.swift:149:1:171:1 | MultiInit | | overload_resolution.swift:177:12:177:32 | MultiInit(...) | | overload_resolution.swift:149:1:171:1 | MultiInit | | overload_resolution.swift:177:25:177:25 | 1 | | {EXTERNAL LOCATION} | Int | | overload_resolution.swift:177:31:177:31 | 2 | | {EXTERNAL LOCATION} | Int | @@ -2126,6 +2242,7 @@ inferType | overload_resolution.swift:188:34:190:3 | Block | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:189:12:189:19 | "static" | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:194:7:194:7 | o | | overload_resolution.swift:183:1:191:1 | StaticVsInstance | +| overload_resolution.swift:194:11:194:26 | StaticVsInstance | | overload_resolution.swift:183:1:191:1 | StaticVsInstance | | overload_resolution.swift:194:11:194:28 | StaticVsInstance(...) | | overload_resolution.swift:183:1:191:1 | StaticVsInstance | | overload_resolution.swift:195:7:195:8 | r1 | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:195:12:195:12 | o | | overload_resolution.swift:183:1:191:1 | StaticVsInstance | @@ -2139,6 +2256,7 @@ inferType | overload_resolution.swift:218:29:220:3 | Block | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:219:12:219:21 | "concrete" | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:224:7:224:7 | d | | overload_resolution.swift:215:1:221:1 | DescribableImpl | +| overload_resolution.swift:224:11:224:25 | DescribableImpl | | overload_resolution.swift:215:1:221:1 | DescribableImpl | | overload_resolution.swift:224:11:224:27 | DescribableImpl(...) | | overload_resolution.swift:215:1:221:1 | DescribableImpl | | overload_resolution.swift:225:7:225:8 | r1 | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:225:12:225:12 | d | | overload_resolution.swift:215:1:221:1 | DescribableImpl | @@ -2163,11 +2281,13 @@ inferType | overload_resolution.swift:262:36:264:3 | Block | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:263:12:263:19 | "subsub" | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:268:7:268:7 | b | | overload_resolution.swift:231:1:241:1 | Base | +| overload_resolution.swift:268:11:268:14 | Base | | overload_resolution.swift:231:1:241:1 | Base | | overload_resolution.swift:268:11:268:16 | Base(...) | | overload_resolution.swift:231:1:241:1 | Base | | overload_resolution.swift:269:7:269:8 | rb | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:269:12:269:12 | b | | overload_resolution.swift:231:1:241:1 | Base | | overload_resolution.swift:269:12:269:21 | ... .action(...) | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:271:7:271:7 | s | | overload_resolution.swift:243:1:255:1 | Sub | +| overload_resolution.swift:271:11:271:13 | Sub | | overload_resolution.swift:243:1:255:1 | Sub | | overload_resolution.swift:271:11:271:15 | Sub(...) | | overload_resolution.swift:243:1:255:1 | Sub | | overload_resolution.swift:272:7:272:8 | rs | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:272:12:272:12 | s | | overload_resolution.swift:243:1:255:1 | Sub | @@ -2179,6 +2299,7 @@ inferType | overload_resolution.swift:274:13:274:13 | s | | overload_resolution.swift:243:1:255:1 | Sub | | overload_resolution.swift:274:13:274:23 | ... .subOnly(...) | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:276:7:276:8 | ss | | overload_resolution.swift:257:1:265:1 | SubSub | +| overload_resolution.swift:276:12:276:17 | SubSub | | overload_resolution.swift:257:1:265:1 | SubSub | | overload_resolution.swift:276:12:276:19 | SubSub(...) | | overload_resolution.swift:257:1:265:1 | SubSub | | overload_resolution.swift:277:7:277:9 | rss | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:277:13:277:14 | ss | | overload_resolution.swift:257:1:265:1 | SubSub | @@ -2202,6 +2323,7 @@ inferType | overload_resolution.swift:294:12:294:26 | ... + ... | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:294:21:294:26 | source | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:299:7:299:7 | o | | overload_resolution.swift:284:1:296:1 | LabelVariants | +| overload_resolution.swift:299:11:299:23 | LabelVariants | | overload_resolution.swift:284:1:296:1 | LabelVariants | | overload_resolution.swift:299:11:299:25 | LabelVariants(...) | | overload_resolution.swift:284:1:296:1 | LabelVariants | | overload_resolution.swift:300:7:300:8 | r1 | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:300:12:300:12 | o | | overload_resolution.swift:284:1:296:1 | LabelVariants | @@ -2249,11 +2371,15 @@ inferType | overload_resolution.swift:346:12:346:18 | newItem | | overload_resolution.swift:334:11:334:11 | T | | overload_resolution.swift:351:7:351:12 | intBox | | overload_resolution.swift:334:1:348:1 | Box | | overload_resolution.swift:351:7:351:12 | intBox | T | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:351:16:351:18 | Box | | overload_resolution.swift:334:1:348:1 | Box | +| overload_resolution.swift:351:16:351:18 | Box | T | {EXTERNAL LOCATION} | Int | | overload_resolution.swift:351:16:351:22 | Box(...) | | overload_resolution.swift:334:1:348:1 | Box | | overload_resolution.swift:351:16:351:22 | Box(...) | T | {EXTERNAL LOCATION} | Int | | overload_resolution.swift:351:20:351:21 | 10 | | {EXTERNAL LOCATION} | Int | | overload_resolution.swift:352:7:352:12 | strBox | | overload_resolution.swift:334:1:348:1 | Box | | overload_resolution.swift:352:7:352:12 | strBox | T | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:352:16:352:18 | Box | | overload_resolution.swift:334:1:348:1 | Box | +| overload_resolution.swift:352:16:352:18 | Box | T | {EXTERNAL LOCATION} | String | | overload_resolution.swift:352:16:352:24 | Box(...) | | overload_resolution.swift:334:1:348:1 | Box | | overload_resolution.swift:352:16:352:24 | Box(...) | T | {EXTERNAL LOCATION} | String | | overload_resolution.swift:352:20:352:23 | "hi" | | {EXTERNAL LOCATION} | String | @@ -2297,13 +2423,16 @@ inferType | overload_resolution.swift:375:21:375:29 | "default" | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:375:38:375:41 | size | | {EXTERNAL LOCATION} | Int | | overload_resolution.swift:380:7:380:8 | w1 | | overload_resolution.swift:361:1:377:1 | Widget | +| overload_resolution.swift:380:12:380:17 | Widget | | overload_resolution.swift:361:1:377:1 | Widget | | overload_resolution.swift:380:12:380:37 | Widget(...) | | overload_resolution.swift:361:1:377:1 | Widget | | overload_resolution.swift:380:25:380:27 | "a" | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:380:36:380:36 | 5 | | {EXTERNAL LOCATION} | Int | | overload_resolution.swift:381:7:381:8 | w2 | | overload_resolution.swift:361:1:377:1 | Widget | +| overload_resolution.swift:381:12:381:17 | Widget | | overload_resolution.swift:361:1:377:1 | Widget | | overload_resolution.swift:381:12:381:28 | Widget(...) | | overload_resolution.swift:361:1:377:1 | Widget | | overload_resolution.swift:381:25:381:27 | "b" | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:382:7:382:8 | w3 | | overload_resolution.swift:361:1:377:1 | Widget | +| overload_resolution.swift:382:12:382:17 | Widget | | overload_resolution.swift:361:1:377:1 | Widget | | overload_resolution.swift:382:12:382:27 | Widget(...) | | overload_resolution.swift:361:1:377:1 | Widget | | overload_resolution.swift:382:25:382:26 | 10 | | {EXTERNAL LOCATION} | Int | | overload_resolution.swift:388:16:388:16 | f | | {EXTERNAL LOCATION} | Function | @@ -2343,6 +2472,7 @@ inferType | overload_resolution.swift:397:14:397:14 | 0 | | {EXTERNAL LOCATION} | Int | | overload_resolution.swift:397:17:397:17 | 0 | | {EXTERNAL LOCATION} | Int | | overload_resolution.swift:402:7:402:7 | p | | overload_resolution.swift:387:1:399:1 | Processor | +| overload_resolution.swift:402:11:402:19 | Processor | | overload_resolution.swift:387:1:399:1 | Processor | | overload_resolution.swift:402:11:402:21 | Processor(...) | | overload_resolution.swift:387:1:399:1 | Processor | | overload_resolution.swift:403:7:403:8 | r1 | | {EXTERNAL LOCATION} | Int | | overload_resolution.swift:403:7:403:8 | r1 | | {EXTERNAL LOCATION} | String | @@ -2417,6 +2547,7 @@ inferType | overload_resolution.swift:419:17:419:19 | key | | {EXTERNAL LOCATION} | String | | overload_resolution.swift:419:25:419:25 | 0 | | {EXTERNAL LOCATION} | Int | | overload_resolution.swift:424:7:424:8 | ms | | overload_resolution.swift:410:1:421:1 | MultiSubscript | +| overload_resolution.swift:424:12:424:25 | MultiSubscript | | overload_resolution.swift:410:1:421:1 | MultiSubscript | | overload_resolution.swift:424:12:424:27 | MultiSubscript(...) | | overload_resolution.swift:410:1:421:1 | MultiSubscript | | overload_resolution.swift:425:7:425:8 | r1 | | {EXTERNAL LOCATION} | Int | | overload_resolution.swift:425:12:425:13 | ms | | overload_resolution.swift:410:1:421:1 | MultiSubscript | @@ -2453,6 +2584,8 @@ inferType | pattern_matching.swift:29:42:33:1 | Block | T | {EXTERNAL LOCATION} | Bool | | pattern_matching.swift:30:7:30:7 | x | | pattern_matching.swift:7:1:11:1 | PatternMatch | | pattern_matching.swift:30:7:30:7 | x | T | {EXTERNAL LOCATION} | Int | +| pattern_matching.swift:30:11:30:28 | ... .value | | pattern_matching.swift:7:1:11:1 | PatternMatch | +| pattern_matching.swift:30:11:30:28 | ... .value | T | {EXTERNAL LOCATION} | Int | | pattern_matching.swift:30:11:30:32 | ... .value(...) | | pattern_matching.swift:7:1:11:1 | PatternMatch | | pattern_matching.swift:30:11:30:32 | ... .value(...) | T | {EXTERNAL LOCATION} | Int | | pattern_matching.swift:30:30:30:31 | 42 | | {EXTERNAL LOCATION} | Int | @@ -2493,12 +2626,14 @@ inferType | protocols.swift:29:12:29:25 | ... * ... | | {EXTERNAL LOCATION} | Double | | protocols.swift:29:20:29:25 | height | | {EXTERNAL LOCATION} | Double | | protocols.swift:34:7:34:7 | c | | protocols.swift:7:1:17:1 | Circle | +| protocols.swift:34:11:34:16 | Circle | | protocols.swift:7:1:17:1 | Circle | | protocols.swift:34:11:34:29 | Circle(...) | | protocols.swift:7:1:17:1 | Circle | | protocols.swift:34:26:34:28 | 5.0 | | {EXTERNAL LOCATION} | Double | | protocols.swift:35:7:35:8 | a1 | | {EXTERNAL LOCATION} | Double | | protocols.swift:35:12:35:12 | c | | protocols.swift:7:1:17:1 | Circle | | protocols.swift:35:12:35:19 | ... .area(...) | | {EXTERNAL LOCATION} | Double | | protocols.swift:37:7:37:7 | r | | protocols.swift:19:1:31:1 | Rectangle | +| protocols.swift:37:11:37:19 | Rectangle | | protocols.swift:19:1:31:1 | Rectangle | | protocols.swift:37:11:37:44 | Rectangle(...) | | protocols.swift:19:1:31:1 | Rectangle | | protocols.swift:37:28:37:30 | 3.0 | | {EXTERNAL LOCATION} | Double | | protocols.swift:37:41:37:43 | 4.0 | | {EXTERNAL LOCATION} | Double | @@ -2524,6 +2659,7 @@ inferType | protocols.swift:62:12:62:16 | items | | {EXTERNAL LOCATION} | Array | | protocols.swift:62:12:62:16 | items | Element | {EXTERNAL LOCATION} | Int | | protocols.swift:67:7:67:8 | ic | | protocols.swift:49:1:64:1 | IntContainer | +| protocols.swift:67:12:67:23 | IntContainer | | protocols.swift:49:1:64:1 | IntContainer | | protocols.swift:67:12:67:41 | IntContainer(...) | | protocols.swift:49:1:64:1 | IntContainer | | protocols.swift:67:32:67:40 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | | protocols.swift:67:32:67:40 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int | @@ -2554,6 +2690,7 @@ inferType | protocols.swift:95:20:97:3 | Block | | {EXTERNAL LOCATION} | Int | | protocols.swift:96:12:96:19 | entityId | | {EXTERNAL LOCATION} | Int | | protocols.swift:101:7:101:7 | e | | protocols.swift:82:1:98:1 | Entity | +| protocols.swift:101:11:101:16 | Entity | | protocols.swift:82:1:98:1 | Entity | | protocols.swift:101:11:101:44 | Entity(...) | | protocols.swift:82:1:98:1 | Entity | | protocols.swift:101:24:101:29 | "test" | | {EXTERNAL LOCATION} | String | | protocols.swift:101:42:101:43 | 42 | | {EXTERNAL LOCATION} | Int | @@ -2704,6 +2841,7 @@ inferType | type_constraints.swift:52:10:52:15 | ... == ... | | type_constraints.swift:50:25:50:25 | T | | type_constraints.swift:52:15:52:15 | b | | type_constraints.swift:50:25:50:25 | T | | type_constraints.swift:56:7:56:10 | item | | type_constraints.swift:28:1:44:1 | TaggedItem | +| type_constraints.swift:56:14:56:23 | TaggedItem | | type_constraints.swift:28:1:44:1 | TaggedItem | | type_constraints.swift:56:14:56:46 | TaggedItem(...) | | type_constraints.swift:28:1:44:1 | TaggedItem | | type_constraints.swift:56:30:56:32 | "x" | | {EXTERNAL LOCATION} | String | | type_constraints.swift:56:45:56:45 | 1 | | {EXTERNAL LOCATION} | Int | @@ -2744,6 +2882,9 @@ inferType | type_constraints.swift:82:7:82:8 | sp | | type_constraints.swift:63:1:79:1 | SortedPair | | type_constraints.swift:82:7:82:8 | sp | T | {EXTERNAL LOCATION} | Int | | type_constraints.swift:82:7:82:8 | sp | U | {EXTERNAL LOCATION} | String | +| type_constraints.swift:82:12:82:21 | SortedPair | | type_constraints.swift:63:1:79:1 | SortedPair | +| type_constraints.swift:82:12:82:21 | SortedPair | T | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:82:12:82:21 | SortedPair | U | {EXTERNAL LOCATION} | String | | type_constraints.swift:82:12:82:44 | SortedPair(...) | | type_constraints.swift:63:1:79:1 | SortedPair | | type_constraints.swift:82:12:82:44 | SortedPair(...) | T | {EXTERNAL LOCATION} | Int | | type_constraints.swift:82:12:82:44 | SortedPair(...) | U | {EXTERNAL LOCATION} | String | @@ -2798,12 +2939,14 @@ inferType | type_constraints.swift:124:45:124:53 | container | | type_constraints.swift:124:19:124:37 | C | | type_constraints.swift:125:10:125:18 | container | | type_constraints.swift:124:19:124:37 | C | | type_constraints.swift:129:7:129:8 | ia | | type_constraints.swift:94:1:105:1 | IntArray | +| type_constraints.swift:129:12:129:19 | IntArray | | type_constraints.swift:94:1:105:1 | IntArray | | type_constraints.swift:129:12:129:36 | IntArray(...) | | type_constraints.swift:94:1:105:1 | IntArray | | type_constraints.swift:129:28:129:35 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | | type_constraints.swift:129:28:129:35 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int | | type_constraints.swift:129:29:129:30 | 10 | | {EXTERNAL LOCATION} | Int | | type_constraints.swift:129:33:129:34 | 20 | | {EXTERNAL LOCATION} | Int | | type_constraints.swift:130:7:130:8 | sa | | type_constraints.swift:107:1:118:1 | StringArray | +| type_constraints.swift:130:12:130:22 | StringArray | | type_constraints.swift:107:1:118:1 | StringArray | | type_constraints.swift:130:12:130:46 | StringArray(...) | | type_constraints.swift:107:1:118:1 | StringArray | | type_constraints.swift:130:31:130:45 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | | type_constraints.swift:130:31:130:45 | ArrayLiteral | Element | {EXTERNAL LOCATION} | String | @@ -2841,9 +2984,11 @@ inferType | type_constraints.swift:177:36:177:36 | v | | type_constraints.swift:177:22:177:31 | T | | type_constraints.swift:178:10:178:10 | v | | type_constraints.swift:177:22:177:31 | T | | type_constraints.swift:182:7:182:9 | car | | type_constraints.swift:149:1:161:1 | Car | +| type_constraints.swift:182:13:182:15 | Car | | type_constraints.swift:149:1:161:1 | Car | | type_constraints.swift:182:13:182:27 | Car(...) | | type_constraints.swift:149:1:161:1 | Car | | type_constraints.swift:182:24:182:26 | 100 | | {EXTERNAL LOCATION} | Int | | type_constraints.swift:183:7:183:11 | truck | | type_constraints.swift:163:1:175:1 | Truck | +| type_constraints.swift:183:15:183:19 | Truck | | type_constraints.swift:163:1:175:1 | Truck | | type_constraints.swift:183:15:183:30 | Truck(...) | | type_constraints.swift:163:1:175:1 | Truck | | type_constraints.swift:183:28:183:29 | 60 | | {EXTERNAL LOCATION} | Int | | type_constraints.swift:184:7:184:8 | d1 | | {EXTERNAL LOCATION} | String | @@ -2884,6 +3029,8 @@ inferType | type_constraints.swift:220:35:222:5 | FunctionExpr | | {EXTERNAL LOCATION} | Function | | type_constraints.swift:227:7:227:12 | intAcc | | type_constraints.swift:200:1:210:1 | Accumulator | | type_constraints.swift:227:7:227:12 | intAcc | T | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:227:16:227:26 | Accumulator | | type_constraints.swift:200:1:210:1 | Accumulator | +| type_constraints.swift:227:16:227:26 | Accumulator | T | {EXTERNAL LOCATION} | Int | | type_constraints.swift:227:16:227:45 | Accumulator(...) | | type_constraints.swift:200:1:210:1 | Accumulator | | type_constraints.swift:227:16:227:45 | Accumulator(...) | T | {EXTERNAL LOCATION} | Int | | type_constraints.swift:227:36:227:44 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | @@ -2915,6 +3062,7 @@ inferType | type_constraints.swift:240:66:242:3 | Block | | {EXTERNAL LOCATION} | Bool | | type_constraints.swift:241:12:241:15 | true | | {EXTERNAL LOCATION} | Bool | | type_constraints.swift:246:7:246:7 | t | | type_constraints.swift:235:1:243:1 | Transformer | +| type_constraints.swift:246:11:246:21 | Transformer | | type_constraints.swift:235:1:243:1 | Transformer | | type_constraints.swift:246:11:246:23 | Transformer(...) | | type_constraints.swift:235:1:243:1 | Transformer | | type_constraints.swift:247:7:247:8 | r1 | | {EXTERNAL LOCATION} | Int | | type_constraints.swift:247:12:247:12 | t | | type_constraints.swift:235:1:243:1 | Transformer |