diff --git a/rust/ql/test/library-tests/type-inference/main.rs b/rust/ql/test/library-tests/type-inference/main.rs index 2c462aa114a7..006835b89188 100644 --- a/rust/ql/test/library-tests/type-inference/main.rs +++ b/rust/ql/test/library-tests/type-inference/main.rs @@ -2810,6 +2810,31 @@ fn empty_array() { pin_array(arr3, 1); // $ target=pin_array } +mod contextual_bound { + #[derive(Default)] + struct S(T); + struct MyThingA(A); + struct MyThingB(B); + + trait MyTrait {} + + impl MyTrait for MyThingA {} + + impl MyTrait<[T; 1]> for MyThingB {} + + fn bar>(x: T1, y: Option) {} + + fn test_bar() { + let x = S(0); + let y = MyThingA(Default::default()); // $ type=y@MyThingA.S:i32 target=default + bar(x, Some(y)); // $ target=bar + + let x = S(0); + let z = MyThingB(Default::default()); // $ type=z@MyThingB.S:i32 target=default + bar([x], Some(z)); // $ target=bar + } +} + fn main() { field_access::f(); // $ target=f method_impl::f(); // $ target=f diff --git a/rust/ql/test/library-tests/type-inference/type-inference.expected b/rust/ql/test/library-tests/type-inference/type-inference.expected index 1663b7871cd7..b519e18357b3 100644 --- a/rust/ql/test/library-tests/type-inference/type-inference.expected +++ b/rust/ql/test/library-tests/type-inference/type-inference.expected @@ -3763,10 +3763,16 @@ inferCertainType | main.rs:2809:34:2809:34 | x | | main.rs:2809:18:2809:18 | T | | main.rs:2809:40:2809:41 | { ... } | | {EXTERNAL LOCATION} | () | | main.rs:2810:15:2810:18 | arr3 | | {EXTERNAL LOCATION} | [;] | -| main.rs:2813:11:2849:1 | { ... } | | {EXTERNAL LOCATION} | () | -| main.rs:2816:20:2816:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | -| main.rs:2816:41:2816:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | -| main.rs:2846:16:2846:19 | true | | {EXTERNAL LOCATION} | bool | +| main.rs:2825:33:2825:33 | x | | main.rs:2825:12:2825:13 | T1 | +| main.rs:2825:40:2825:40 | y | | {EXTERNAL LOCATION} | Option | +| main.rs:2825:40:2825:40 | y | T | main.rs:2825:16:2825:30 | T2 | +| main.rs:2825:55:2825:56 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2827:19:2835:5 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2834:13:2834:15 | [...] | | {EXTERNAL LOCATION} | [;] | +| main.rs:2838:11:2874:1 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2841:20:2841:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | +| main.rs:2841:41:2841:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | +| main.rs:2871:16:2871:19 | true | | {EXTERNAL LOCATION} | bool | | overloading.rs:4:19:4:23 | SelfParam | | {EXTERNAL LOCATION} | & | | overloading.rs:4:19:4:23 | SelfParam | TRef | overloading.rs:2:5:11:5 | Self [trait FirstTrait] | | overloading.rs:4:34:6:9 | { ... } | | {EXTERNAL LOCATION} | bool | @@ -12773,49 +12779,104 @@ inferType | main.rs:2810:15:2810:18 | arr3 | | {EXTERNAL LOCATION} | [;] | | main.rs:2810:15:2810:18 | arr3 | TArray | {EXTERNAL LOCATION} | i32 | | main.rs:2810:21:2810:21 | 1 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2813:11:2849:1 | { ... } | | {EXTERNAL LOCATION} | () | -| main.rs:2814:5:2814:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2815:5:2815:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo | -| main.rs:2816:5:2816:60 | ...::g(...) | | main.rs:72:5:72:21 | Foo | -| main.rs:2816:20:2816:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | -| main.rs:2816:41:2816:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | -| main.rs:2817:5:2817:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2818:5:2818:41 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2819:5:2819:45 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2820:5:2820:30 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2821:5:2821:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2822:5:2822:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2823:5:2823:32 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2824:5:2824:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2825:5:2825:36 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2826:5:2826:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2827:5:2827:29 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2828:5:2828:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2829:5:2829:24 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2830:5:2830:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2831:5:2831:18 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2832:5:2832:15 | ...::f(...) | | {EXTERNAL LOCATION} | dyn Future | -| main.rs:2832:5:2832:15 | ...::f(...) | dyn(Output) | {EXTERNAL LOCATION} | () | -| main.rs:2833:5:2833:19 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2834:5:2834:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2835:5:2835:14 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2836:5:2836:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2837:5:2837:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2838:5:2838:43 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2839:5:2839:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2840:5:2840:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2841:5:2841:28 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2842:5:2842:23 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2843:5:2843:41 | ...::test_all_patterns(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2844:5:2844:49 | ...::box_patterns(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2845:5:2845:20 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2846:5:2846:20 | ...::f(...) | | {EXTERNAL LOCATION} | Box | -| main.rs:2846:5:2846:20 | ...::f(...) | A | {EXTERNAL LOCATION} | Global | -| main.rs:2846:5:2846:20 | ...::f(...) | T | main.rs:2564:5:2566:5 | dyn MyTrait | -| main.rs:2846:5:2846:20 | ...::f(...) | T.dyn(T) | {EXTERNAL LOCATION} | i32 | -| main.rs:2846:16:2846:19 | true | | {EXTERNAL LOCATION} | bool | -| main.rs:2847:5:2847:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2848:5:2848:17 | empty_array(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2823:25:2823:25 | 1 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2825:33:2825:33 | x | | main.rs:2825:12:2825:13 | T1 | +| main.rs:2825:40:2825:40 | y | | {EXTERNAL LOCATION} | Option | +| main.rs:2825:40:2825:40 | y | T | main.rs:2825:16:2825:30 | T2 | +| main.rs:2825:55:2825:56 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2827:19:2835:5 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2828:13:2828:13 | x | | main.rs:2814:5:2815:19 | S | +| main.rs:2828:13:2828:13 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2828:17:2828:20 | S(...) | | main.rs:2814:5:2815:19 | S | +| main.rs:2828:17:2828:20 | S(...) | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2828:19:2828:19 | 0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2829:13:2829:13 | y | | main.rs:2816:5:2816:26 | MyThingA | +| main.rs:2829:13:2829:13 | y | A | main.rs:2814:5:2815:19 | S | +| main.rs:2829:13:2829:13 | y | A.T | {EXTERNAL LOCATION} | i32 | +| main.rs:2829:17:2829:44 | MyThingA(...) | | main.rs:2816:5:2816:26 | MyThingA | +| main.rs:2829:17:2829:44 | MyThingA(...) | A | main.rs:2814:5:2815:19 | S | +| main.rs:2829:17:2829:44 | MyThingA(...) | A.T | {EXTERNAL LOCATION} | i32 | +| main.rs:2829:26:2829:43 | ...::default(...) | | main.rs:2814:5:2815:19 | S | +| main.rs:2829:26:2829:43 | ...::default(...) | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2830:9:2830:23 | bar(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2830:13:2830:13 | x | | main.rs:2814:5:2815:19 | S | +| main.rs:2830:13:2830:13 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2830:16:2830:22 | Some(...) | | {EXTERNAL LOCATION} | Option | +| main.rs:2830:16:2830:22 | Some(...) | T | main.rs:2816:5:2816:26 | MyThingA | +| main.rs:2830:16:2830:22 | Some(...) | T.A | main.rs:2814:5:2815:19 | S | +| main.rs:2830:16:2830:22 | Some(...) | T.A.T | {EXTERNAL LOCATION} | i32 | +| main.rs:2830:21:2830:21 | y | | main.rs:2816:5:2816:26 | MyThingA | +| main.rs:2830:21:2830:21 | y | A | main.rs:2814:5:2815:19 | S | +| main.rs:2830:21:2830:21 | y | A.T | {EXTERNAL LOCATION} | i32 | +| main.rs:2832:13:2832:13 | x | | main.rs:2814:5:2815:19 | S | +| main.rs:2832:13:2832:13 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2832:17:2832:20 | S(...) | | main.rs:2814:5:2815:19 | S | +| main.rs:2832:17:2832:20 | S(...) | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2832:19:2832:19 | 0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2833:13:2833:13 | z | | main.rs:2817:5:2817:26 | MyThingB | +| main.rs:2833:13:2833:13 | z | B | main.rs:2814:5:2815:19 | S | +| main.rs:2833:13:2833:13 | z | B.T | {EXTERNAL LOCATION} | i32 | +| main.rs:2833:17:2833:44 | MyThingB(...) | | main.rs:2817:5:2817:26 | MyThingB | +| main.rs:2833:17:2833:44 | MyThingB(...) | B | main.rs:2814:5:2815:19 | S | +| main.rs:2833:17:2833:44 | MyThingB(...) | B.T | {EXTERNAL LOCATION} | i32 | +| main.rs:2833:26:2833:43 | ...::default(...) | | main.rs:2814:5:2815:19 | S | +| main.rs:2833:26:2833:43 | ...::default(...) | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2834:9:2834:25 | bar(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2834:13:2834:15 | [...] | | {EXTERNAL LOCATION} | [;] | +| main.rs:2834:13:2834:15 | [...] | TArray | main.rs:2814:5:2815:19 | S | +| main.rs:2834:13:2834:15 | [...] | TArray.T | {EXTERNAL LOCATION} | i32 | +| main.rs:2834:14:2834:14 | x | | main.rs:2814:5:2815:19 | S | +| main.rs:2834:14:2834:14 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2834:18:2834:24 | Some(...) | | {EXTERNAL LOCATION} | Option | +| main.rs:2834:18:2834:24 | Some(...) | T | main.rs:2817:5:2817:26 | MyThingB | +| main.rs:2834:18:2834:24 | Some(...) | T.B | main.rs:2814:5:2815:19 | S | +| main.rs:2834:18:2834:24 | Some(...) | T.B.T | {EXTERNAL LOCATION} | i32 | +| main.rs:2834:23:2834:23 | z | | main.rs:2817:5:2817:26 | MyThingB | +| main.rs:2834:23:2834:23 | z | B | main.rs:2814:5:2815:19 | S | +| main.rs:2834:23:2834:23 | z | B.T | {EXTERNAL LOCATION} | i32 | +| main.rs:2838:11:2874:1 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2839:5:2839:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2840:5:2840:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo | +| main.rs:2841:5:2841:60 | ...::g(...) | | main.rs:72:5:72:21 | Foo | +| main.rs:2841:20:2841:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | +| main.rs:2841:41:2841:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | +| main.rs:2842:5:2842:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2843:5:2843:41 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2844:5:2844:45 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2845:5:2845:30 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2846:5:2846:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2847:5:2847:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2848:5:2848:32 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2849:5:2849:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2850:5:2850:36 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2851:5:2851:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2852:5:2852:29 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2853:5:2853:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2854:5:2854:24 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2855:5:2855:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2856:5:2856:18 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2857:5:2857:15 | ...::f(...) | | {EXTERNAL LOCATION} | dyn Future | +| main.rs:2857:5:2857:15 | ...::f(...) | dyn(Output) | {EXTERNAL LOCATION} | () | +| main.rs:2858:5:2858:19 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2859:5:2859:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2860:5:2860:14 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2861:5:2861:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2862:5:2862:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2863:5:2863:43 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2864:5:2864:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2865:5:2865:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2866:5:2866:28 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2867:5:2867:23 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2868:5:2868:41 | ...::test_all_patterns(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2869:5:2869:49 | ...::box_patterns(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2870:5:2870:20 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2871:5:2871:20 | ...::f(...) | | {EXTERNAL LOCATION} | Box | +| main.rs:2871:5:2871:20 | ...::f(...) | A | {EXTERNAL LOCATION} | Global | +| main.rs:2871:5:2871:20 | ...::f(...) | T | main.rs:2564:5:2566:5 | dyn MyTrait | +| main.rs:2871:5:2871:20 | ...::f(...) | T.dyn(T) | {EXTERNAL LOCATION} | i32 | +| main.rs:2871:16:2871:19 | true | | {EXTERNAL LOCATION} | bool | +| main.rs:2872:5:2872:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2873:5:2873:17 | empty_array(...) | | {EXTERNAL LOCATION} | () | | overloading.rs:4:19:4:23 | SelfParam | | {EXTERNAL LOCATION} | & | | overloading.rs:4:19:4:23 | SelfParam | TRef | overloading.rs:2:5:11:5 | Self [trait FirstTrait] | | overloading.rs:4:34:6:9 | { ... } | | {EXTERNAL LOCATION} | bool | diff --git a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll index 749e6ce600cf..506629292ff7 100644 --- a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll +++ b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll @@ -1504,6 +1504,80 @@ module Make1 Input1> { hasNotTypeArgument(a, target, tp) ) } + + predicate baseTypeMatchAtTypeParameter( + Access a, AccessEnvironment e, AccessPosition apos, Declaration target, TypeParameter tp, + TypePath prefix, TypePath requiredPrefix + ) { + exists( + TypePath pathToTypeParamInConstraint, TypePath pathToTp, TypePath pathToTypeParamInSub + | + argRootTypeSatisfiesTargetTypeCand(_, target, pragma[only_bind_into](apos), tp, pathToTp) and + SatisfiesParameterConstraint::satisfiesConstraintAtTypeParameter(MkRelevantAccess(a, + pragma[only_bind_into](apos), e), + MkRelevantTarget(target, pragma[only_bind_into](apos)), pathToTypeParamInConstraint, + pathToTypeParamInSub) and + hasNotTypeArgument(a, target, tp) + | + /* + * Example: + * + * ```swift + * class Base { + * init(_ value: B) {} + * } + * + * class Derived: Base<[D]> { + * init(_ value: D) { super.init([value]) } + * } + * + * func foo(_ value: T, _ base: Base) { } + * + * foo([2], Derived()) + * ``` + * + * - tp = T (bound by `foo`) + * - prefix = pathToTypeParamInSub = "D" + * - requiredPrefix = "Element" + * - pathToTypeParamInConstraint = "B.Element" + * - pathToTp = "B" + */ + + pathToTypeParamInConstraint = pathToTp.appendInverse(requiredPrefix) and + prefix = pathToTypeParamInSub + or + /* + * Example: + * + * ```swift + * class Base { + * init(_ value: B) {} + * } + * + * class Derived: Base { + * override init(_ value: D) { super.init(value) } + * } + * + * func foo(_ value: T, _ base: Base) {} + * + * foo(2, Derived2(Optional.none)) + * ``` + * + * - tp = T (bound by `foo`) + * - prefix = "D.Wrapped" + * - pathToTypeParamInSub = "D" + * - requiredPrefix = "" + * - pathToTypeParamInConstraint = "B" + * - pathToTp = "B.Wrapped" + */ + + exists(TypePath path0 | + pathToTp = pathToTypeParamInConstraint.appendInverse(path0) and + prefix = pathToTypeParamInSub.append(path0) and + requiredPrefix = TypePath::nil() + ) + ) + } } private module AccessConstraint { @@ -1745,6 +1819,16 @@ module Make1 Input1> { ) ) or + exists( + Declaration target, TypePath prefix, TypePath requiredPrefix, TypePath suffix, + TypeParameter tp + | + AccessBaseType::baseTypeMatchAtTypeParameter(a, e, apos, target, tp, prefix, + requiredPrefix) and + typeMatch(a, e, target, requiredPrefix.appendInverse(suffix), result, tp) and + path = prefix.append(suffix) + ) + or exists( Declaration target, TypePath prefix, TypeMention constraint, TypePath pathToTypeParamInConstraint, TypePath pathToTypeParamInSub @@ -1785,44 +1869,86 @@ module Make1 Input1> { ) or exists(TypeParameter tp, TypePath suffix, TypePath mid, TypePath pathToTp | + exists(TypeParameter constrainedTp, DeclarationPosition dpos | + typeParameterConstraintHasTypeParameter(target, constrainedTp, constraint, pathToTp, + tp) and + accessDeclarationPositionMatch(apos, dpos) and + constrainedTp = target.getDeclaredType(dpos, _) + ) + | /* * Example: * * ```rust + * struct S { ... } + * * struct MyThing { ... } * * trait MyTrait { ... } * * impl MyTrait for MyThing { ... } * - * fn bar>(x: T1, y: T2) {} + * fn bar>(x: T1, y: Option) {} * - * let x: i32 = ...; + * let x: S = ...; * let y = MyThing(Default::default()); - * bar(x, y); + * bar(x, Some(y)); * ``` * - * At `term` = `bar(x, y)`, we have + * At `term` = `bar([x], Some(y))`, we have * - `constraint = MyTrait`, - * - `pathToTypeParamInConstraint` = `"B"`, - * - `pathToTypeParamInSub` = `"A"`, - * - `prefix` = `suffix` = `mid` = `""`, + * - `pathToTypeParamInConstraint` = `"MyTrait"`, + * - `pathToTypeParamInSub` = `"MyThing"`, + * - `prefix` = `"Option"` + * - `mid` = `""`, * - `tp = T1`, - * - `pathToTp` = `"B"`, and - * - `result` = `i32`. + * - `pathToTp` = `"MyTrait"`, and + * - `suffix` = `""` and `result` = `S`, or + * - `suffix` = `"S"` and `result` = `i32`. * - * That is, it allows us to infer that the type of `y` is `MyThing`. + * That is, it allows us to infer that the type of `y` is `MyThing>`. */ typeMatch(a, e, target, suffix, result, tp) and - exists(TypeParameter constrainedTp, DeclarationPosition dpos | - typeParameterConstraintHasTypeParameter(target, constrainedTp, constraint, pathToTp, - tp) and - accessDeclarationPositionMatch(apos, dpos) and - constrainedTp = target.getDeclaredType(dpos, _) - ) and pathToTp = pathToTypeParamInConstraint.appendInverse(mid) and path = prefix.append(pathToTypeParamInSub.append(mid).append(suffix)) + or + /* + * Example: + * + * ```rust + * struct S { ... } + * + * struct MyThing { ... } + * + * trait MyTrait { ... } + * + * impl MyTrait<[T;1]> for MyThing { ... } + * + * fn bar>(x: T1, y: Option) {} + * + * let x: S = ...; + * let y = MyThing(Default::default()); + * bar([x], Some(y)); + * ``` + * + * At `term` = `bar([x], Some(y))`, we have + * - `constraint = MyTrait`, + * - `pathToTypeParamInConstraint` = `"MyTrait.[;]"`, + * - `pathToTypeParamInSub` = `"MyThing"`, + * - `prefix` = `"Option"` + * - `mid` = `"[;]"`, + * - `tp = T1`, + * - `pathToTp` = `"MyTrait"`, and + * - `suffix` = `""` and `result` = `S`, or + * - `suffix` = `"S"` and `result` = `i32`. + * + * That is, it allows us to infer that the type of `y` is `MyThing>`. + */ + + pathToTypeParamInConstraint = pathToTp.appendInverse(mid) and + typeMatch(a, e, target, mid.appendInverse(suffix), result, tp) and + path = prefix.append(pathToTypeParamInSub.append(suffix)) ) ) } diff --git a/unified/ql/test/library-tests/type-inference/generics.swift b/unified/ql/test/library-tests/type-inference/generics.swift index b193da96ddad..c06f324856e1 100644 --- a/unified/ql/test/library-tests/type-inference/generics.swift +++ b/unified/ql/test/library-tests/type-inference/generics.swift @@ -155,14 +155,48 @@ class Derived: Base { init(_ v1: T1, _ v2: T2) { super.init(v2, v1) // $ type=v2:T2 type=v1:T1 target=Base.init } + + convenience init(_ v1: T1) { + fatalError() + } } -class DerivedDerived: Derived { +class DerivedDerived: Derived<[D], Bool> { init(_ v: D) { - super.init(v, true) // $ type=v:D target=Derived.init + super.init([v], true) // $ type=v:D target=Derived.init + } + + convenience init() { + fatalError() } } +func foo>(_ value1: T1, _ value2: T2, _ base: T3) -> T3 { + return base +} + +func foo2(_ value1: T1, _ value2: T2, _ base: Base) { + +} + +func bar>(_ value1: A, _ value2: B, _ base: C) -> C { + return base + +} + +func bar2(_ value1: A, _ value2: B, _ base: Base) {} + +func baz>(_ value1: A, _ value2: B, _ base: C) -> C { + return base + +} + +func baz2(_ value1: A, _ value2: B, _ base: Base) {} + +func unknown() -> Unknown { // a hack to obtain an `UnknownType` + fatalError() +} + func testDerived() { let d = Derived(1, "x") // $ type=d@Derived:Int type=d@Derived:String target=Derived.init let v1 = d.getValue1() // $ type=v1:String target=Base.getValue1 @@ -170,7 +204,19 @@ func testDerived() { let dd = DerivedDerived("hello") // $ type=dd@DerivedDerived:String target=DerivedDerived.init let vv1 = dd.getValue1() // $ type=vv1:Bool target=Base.getValue1 - let vv2 = dd.getValue2() // $ type=vv2:String target=Base.getValue2 + let vv2 = dd.getValue2() // $ type=vv2@Array:String target=Base.getValue2 + + let x = foo(false, [2], DerivedDerived(unknown())) // $ target=foo target=DerivedDerived.init target=unknown type=x@DerivedDerived:Int + + foo2(false, [2], DerivedDerived(unknown())) // $ target=foo2 target=DerivedDerived.init target=unknown type=DerivedDerived(...)@DerivedDerived:Int + + let y = bar(false, 2, DerivedDerived(unknown())) // $ type=y@DerivedDerived:Int target=bar target=DerivedDerived.init target=unknown + + bar2(false, 2, DerivedDerived(unknown())) // $ target=bar2 target=DerivedDerived.init target=unknown type=DerivedDerived(...)@DerivedDerived:Int + + let w = baz(false, 2, Derived(Optional.none)) // $ type=w@Derived.Optional:Int target=baz target=Derived.init field=Optional.none + + baz2(false, 2, Derived(Optional.none)) // $ target=baz2 target=Derived.init field=Optional.none type=Derived(...)@Derived.Optional:Int } // --- Generics and protocols --- 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 bd5536e6963a..e0dedc578659 100644 --- a/unified/ql/test/library-tests/type-inference/type-inference.expected +++ b/unified/ql/test/library-tests/type-inference/type-inference.expected @@ -207,20 +207,54 @@ inferCertainType | generics.swift:155:20:155:21 | v2 | | generics.swift:154:19:154:20 | T2 | | generics.swift:156:16:156:17 | v2 | | generics.swift:154:19:154:20 | T2 | | generics.swift:156:20:156:21 | v1 | | generics.swift:154:15:154:16 | T1 | -| generics.swift:161:10:161:10 | v | | generics.swift:160:22:160:22 | D | -| generics.swift:162:16:162:16 | v | | generics.swift:160:22:160:22 | D | -| generics.swift:186:12:186:15 | self | | generics.swift:178:1:182:1 | MyProtocol2 | -| generics.swift:191:7:191:11 | value | | generics.swift:190:15:190:15 | T | -| generics.swift:193:10:193:14 | value | | generics.swift:190:15:190:15 | T | -| generics.swift:194:5:194:8 | self | | generics.swift:190:1:196:1 | MyClass | -| generics.swift:194:5:194:8 | self | T | generics.swift:190:15:190:15 | T | -| generics.swift:194:18:194:22 | value | | generics.swift:190:15:190:15 | T | -| generics.swift:206:32:206:32 | c | | generics.swift:206:14:206:27 | T | -| generics.swift:207:10:207:10 | c | | generics.swift:206:14:206:27 | T | -| generics.swift:210:32:210:32 | c | | generics.swift:210:14:210:27 | T | -| generics.swift:211:10:211:10 | c | | generics.swift:210:14:210:27 | T | -| generics.swift:245:65:245:69 | value | | generics.swift:245:33:245:60 | T | -| generics.swift:246:10:246:14 | value | | generics.swift:245:33:245:60 | T | +| generics.swift:159:22:159:23 | v1 | | generics.swift:154:15:154:16 | T1 | +| generics.swift:165:10:165:10 | v | | generics.swift:164:22:164:22 | D | +| generics.swift:166:16:166:18 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| generics.swift:166:16:166:18 | ArrayLiteral | Element | generics.swift:164:22:164:22 | D | +| generics.swift:166:17:166:17 | v | | generics.swift:164:22:164:22 | D | +| generics.swift:174:38:174:43 | value1 | | generics.swift:174:10:174:11 | T1 | +| generics.swift:174:52:174:57 | value2 | | generics.swift:174:14:174:15 | T2 | +| generics.swift:174:66:174:69 | base | | generics.swift:174:18:174:33 | T3 | +| generics.swift:175:10:175:13 | base | | generics.swift:174:18:174:33 | T3 | +| generics.swift:178:21:178:26 | value1 | | generics.swift:178:11:178:12 | T1 | +| generics.swift:178:35:178:40 | value2 | | generics.swift:178:15:178:16 | T2 | +| generics.swift:178:49:178:52 | base | | generics.swift:136:1:152:1 | Base | +| generics.swift:178:49:178:52 | base | T1 | generics.swift:178:11:178:12 | T1 | +| generics.swift:178:49:178:52 | base | T2 | generics.swift:178:15:178:16 | T2 | +| generics.swift:182:35:182:40 | value1 | | generics.swift:182:10:182:10 | A | +| generics.swift:182:48:182:53 | value2 | | generics.swift:182:13:182:13 | B | +| generics.swift:182:61:182:64 | base | | generics.swift:182:16:182:30 | C | +| generics.swift:183:10:183:13 | base | | generics.swift:182:16:182:30 | C | +| generics.swift:187:19:187:24 | value1 | | generics.swift:187:11:187:11 | A | +| generics.swift:187:32:187:37 | value2 | | generics.swift:187:14:187:14 | B | +| generics.swift:187:45:187:48 | base | | generics.swift:136:1:152:1 | Base | +| generics.swift:187:45:187:48 | base | T1 | generics.swift:187:11:187:11 | A | +| generics.swift:187:45:187:48 | base | T2 | {EXTERNAL LOCATION} | Array | +| generics.swift:187:45:187:48 | base | T2.Element | generics.swift:187:14:187:14 | B | +| generics.swift:189:34:189:39 | value1 | | generics.swift:189:10:189:10 | A | +| generics.swift:189:47:189:52 | value2 | | generics.swift:189:13:189:13 | B | +| generics.swift:189:60:189:63 | base | | generics.swift:189:16:189:29 | C | +| generics.swift:190:10:190:13 | base | | generics.swift:189:16:189:29 | C | +| generics.swift:194:19:194:24 | value1 | | generics.swift:194:11:194:11 | A | +| generics.swift:194:32:194:37 | value2 | | generics.swift:194:14:194:14 | B | +| generics.swift:194:45:194:48 | base | | generics.swift:136:1:152:1 | Base | +| generics.swift:194:45:194:48 | base | T1 | generics.swift:194:11:194:11 | A | +| generics.swift:194:45:194:48 | base | T2 | {EXTERNAL LOCATION} | Optional | +| generics.swift:194:45:194:48 | base | T2.Wrapped | generics.swift:194:14:194:14 | B | +| generics.swift:209:22:209:24 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| generics.swift:211:15:211:17 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| generics.swift:232:12:232:15 | self | | generics.swift:224:1:228:1 | MyProtocol2 | +| generics.swift:237:7:237:11 | value | | generics.swift:236:15:236:15 | T | +| generics.swift:239:10:239:14 | value | | generics.swift:236:15:236:15 | T | +| generics.swift:240:5:240:8 | self | | generics.swift:236:1:242:1 | MyClass | +| generics.swift:240:5:240:8 | self | T | generics.swift:236:15:236:15 | T | +| generics.swift:240:18:240:22 | value | | generics.swift:236:15:236:15 | T | +| generics.swift:252:32:252:32 | c | | generics.swift:252:14:252:27 | T | +| generics.swift:253:10:253:10 | c | | generics.swift:252:14:252:27 | T | +| generics.swift:256:32:256:32 | c | | generics.swift:256:14:256:27 | T | +| generics.swift:257:10:257:10 | c | | generics.swift:256:14:256:27 | T | +| generics.swift:291:65:291:69 | value | | generics.swift:291:33:291:60 | T | +| generics.swift:292:10:292:14 | value | | generics.swift:291:33:291:60 | T | | key_paths.swift:4:7:4:7 | x | | {EXTERNAL LOCATION} | Double | | key_paths.swift:5:7:5:7 | y | | {EXTERNAL LOCATION} | Double | | key_paths.swift:7:8:7:8 | x | | {EXTERNAL LOCATION} | Double | @@ -1292,86 +1326,180 @@ inferType | generics.swift:156:5:156:22 | ... .init(...) | T2 | generics.swift:154:15:154:16 | T1 | | generics.swift:156:16:156:17 | v2 | | generics.swift:154:19:154:20 | T2 | | generics.swift:156:20:156:21 | v1 | | generics.swift:154:15:154:16 | T1 | -| generics.swift:161:10:161:10 | v | | generics.swift:160:22:160:22 | D | -| generics.swift:161:16:163:3 | Block | | generics.swift:154:1:158:1 | Derived | -| generics.swift:161:16:163:3 | Block | T1 | generics.swift:160:22:160:22 | D | -| generics.swift:161:16:163:3 | Block | T2 | {EXTERNAL LOCATION} | Bool | -| generics.swift:162:5:162:9 | super | | generics.swift:154:1:158:1 | Derived | -| generics.swift:162:5:162:9 | super | T1 | generics.swift:160:22:160:22 | D | -| generics.swift:162:5:162:9 | super | T2 | {EXTERNAL LOCATION} | Bool | -| generics.swift:162:5:162:23 | ... .init(...) | | generics.swift:154:1:158:1 | Derived | -| generics.swift:162:5:162:23 | ... .init(...) | T1 | generics.swift:160:22:160:22 | D | -| generics.swift:162:5:162:23 | ... .init(...) | T2 | {EXTERNAL LOCATION} | Bool | -| generics.swift:162:16:162:16 | v | | generics.swift:160:22:160:22 | D | -| generics.swift:162:19:162:22 | true | | {EXTERNAL LOCATION} | Bool | -| generics.swift:167:7:167:7 | d | | generics.swift:154:1:158:1 | Derived | -| generics.swift:167:7:167:7 | d | T1 | {EXTERNAL LOCATION} | Int | -| generics.swift:167:7:167:7 | d | T2 | {EXTERNAL LOCATION} | String | -| generics.swift:167:11:167:25 | Derived(...) | | generics.swift:154:1:158:1 | Derived | -| generics.swift:167:11:167:25 | Derived(...) | T1 | {EXTERNAL LOCATION} | Int | -| generics.swift:167:11:167:25 | Derived(...) | T2 | {EXTERNAL LOCATION} | String | -| generics.swift:167:19:167:19 | 1 | | {EXTERNAL LOCATION} | Int | -| generics.swift:167:22:167:24 | "x" | | {EXTERNAL LOCATION} | String | -| generics.swift:168:7:168:8 | v1 | | {EXTERNAL LOCATION} | String | -| generics.swift:168:12:168:12 | d | | generics.swift:154:1:158:1 | Derived | -| generics.swift:168:12:168:12 | d | T1 | {EXTERNAL LOCATION} | Int | -| generics.swift:168:12:168:12 | d | T2 | {EXTERNAL LOCATION} | String | -| generics.swift:168:12:168:24 | ... .getValue1(...) | | {EXTERNAL LOCATION} | String | -| generics.swift:169:7:169:8 | v2 | | {EXTERNAL LOCATION} | Int | -| generics.swift:169:12:169:12 | d | | generics.swift:154:1:158:1 | Derived | -| generics.swift:169:12:169:12 | d | T1 | {EXTERNAL LOCATION} | Int | -| generics.swift:169:12:169:12 | d | T2 | {EXTERNAL LOCATION} | String | -| generics.swift:169:12:169:24 | ... .getValue2(...) | | {EXTERNAL LOCATION} | Int | -| generics.swift:171:7:171:8 | dd | | generics.swift:160:1:164:1 | DerivedDerived | -| generics.swift:171:7:171:8 | dd | D | {EXTERNAL LOCATION} | String | -| generics.swift:171:12:171:34 | DerivedDerived(...) | | generics.swift:160:1:164:1 | DerivedDerived | -| generics.swift:171:12:171:34 | DerivedDerived(...) | D | {EXTERNAL LOCATION} | String | -| generics.swift:171:27:171:33 | "hello" | | {EXTERNAL LOCATION} | String | -| generics.swift:172:7:172:9 | vv1 | | {EXTERNAL LOCATION} | Bool | -| generics.swift:172:13:172:14 | dd | | generics.swift:160:1:164:1 | DerivedDerived | -| generics.swift:172:13:172:14 | dd | D | {EXTERNAL LOCATION} | String | -| generics.swift:172:13:172:26 | ... .getValue1(...) | | {EXTERNAL LOCATION} | Bool | -| generics.swift:173:7:173:9 | vv2 | | {EXTERNAL LOCATION} | String | -| generics.swift:173:13:173:14 | dd | | generics.swift:160:1:164:1 | DerivedDerived | -| generics.swift:173:13:173:14 | dd | D | {EXTERNAL LOCATION} | String | -| generics.swift:173:13:173:26 | ... .getValue2(...) | | {EXTERNAL LOCATION} | String | -| generics.swift:185:22:187:3 | Block | | generics.swift:178:1:182:1 | MyProtocol2 | -| generics.swift:186:12:186:15 | self | | generics.swift:178:1:182:1 | MyProtocol2 | -| generics.swift:191:7:191:11 | value | | generics.swift:190:15:190:15 | T | -| generics.swift:193:10:193:14 | value | | generics.swift:190:15:190:15 | T | -| generics.swift:193:20:195:3 | Block | | generics.swift:190:15:190:15 | T | -| generics.swift:194:5:194:8 | self | | generics.swift:190:1:196:1 | MyClass | -| generics.swift:194:5:194:8 | self | T | generics.swift:190:15:190:15 | T | -| generics.swift:194:5:194:14 | ... .value | | generics.swift:190:15:190:15 | T | -| generics.swift:194:5:194:22 | ... = ... | | generics.swift:190:15:190:15 | T | -| generics.swift:194:18:194:22 | value | | generics.swift:190:15:190:15 | T | -| generics.swift:206:32:206:32 | c | | generics.swift:206:14:206:27 | T | -| generics.swift:207:10:207:10 | c | | generics.swift:206:14:206:27 | T | -| generics.swift:210:32:210:32 | c | | generics.swift:210:14:210:27 | T | -| generics.swift:211:10:211:10 | c | | generics.swift:210:14:210:27 | T | -| generics.swift:215:7:215:7 | c | | generics.swift:190:1:196:1 | MyClass | -| generics.swift:215:7:215:7 | c | T | {EXTERNAL LOCATION} | Int | -| generics.swift:215:11:215:21 | MyClass(...) | | generics.swift:190:1:196:1 | MyClass | -| generics.swift:215:11:215:21 | MyClass(...) | T | {EXTERNAL LOCATION} | Int | -| generics.swift:215:19:215:20 | 42 | | {EXTERNAL LOCATION} | Int | -| generics.swift:216:11:216:11 | c | | generics.swift:190:1:196:1 | MyClass | -| generics.swift:216:11:216:11 | c | T | {EXTERNAL LOCATION} | Int | -| generics.swift:217:11:217:11 | c | | generics.swift:190:1:196:1 | MyClass | -| generics.swift:217:11:217:11 | c | T | {EXTERNAL LOCATION} | Int | -| generics.swift:218:20:218:20 | c | | generics.swift:190:1:196:1 | MyClass | -| generics.swift:218:20:218:20 | c | T | {EXTERNAL LOCATION} | Int | -| generics.swift:236:30:238:3 | Block | | {EXTERNAL LOCATION} | String | -| generics.swift:237:12:237:17 | "base" | | {EXTERNAL LOCATION} | String | -| generics.swift:240:29:242:3 | Block | | {EXTERNAL LOCATION} | String | -| generics.swift:241:12:241:16 | "sub" | | {EXTERNAL LOCATION} | String | -| generics.swift:245:65:245:69 | value | | generics.swift:245:33:245:60 | T | -| generics.swift:246:10:246:14 | value | | generics.swift:245:33:245:60 | T | -| generics.swift:250:42:250:63 | StringAssociatedType(...) | | generics.swift:233:1:243:1 | StringAssociatedType | -| generics.swift:264:25:266:3 | Block | | {EXTERNAL LOCATION} | Int | -| generics.swift:265:12:265:13 | 42 | | {EXTERNAL LOCATION} | Int | -| generics.swift:274:7:274:11 | value | | {EXTERNAL LOCATION} | Int | -| generics.swift:274:15:274:66 | getPrimaryAssociatedType(...) | | {EXTERNAL LOCATION} | Int | -| generics.swift:274:40:274:65 | IntPrimaryAssociatedType(...) | | generics.swift:261:1:267:1 | IntPrimaryAssociatedType | +| generics.swift:159:22:159:23 | v1 | | generics.swift:154:15:154:16 | T1 | +| generics.swift:165:10:165:10 | v | | generics.swift:164:22:164:22 | D | +| generics.swift:165:16:167:3 | Block | | generics.swift:154:1:162:1 | Derived | +| generics.swift:165:16:167:3 | Block | T1 | {EXTERNAL LOCATION} | Array | +| generics.swift:165:16:167:3 | Block | T1.Element | generics.swift:164:22:164:22 | D | +| generics.swift:165:16:167:3 | Block | T2 | {EXTERNAL LOCATION} | Bool | +| generics.swift:166:5:166:9 | super | | generics.swift:154:1:162:1 | Derived | +| generics.swift:166:5:166:9 | super | T1 | {EXTERNAL LOCATION} | Array | +| generics.swift:166:5:166:9 | super | T1.Element | generics.swift:164:22:164:22 | D | +| generics.swift:166:5:166:9 | super | T2 | {EXTERNAL LOCATION} | Bool | +| generics.swift:166:5:166:25 | ... .init(...) | | generics.swift:154:1:162:1 | Derived | +| generics.swift:166:5:166:25 | ... .init(...) | T1 | {EXTERNAL LOCATION} | Array | +| generics.swift:166:5:166:25 | ... .init(...) | T1.Element | generics.swift:164:22:164:22 | D | +| generics.swift:166:5:166:25 | ... .init(...) | T2 | {EXTERNAL LOCATION} | Bool | +| generics.swift:166:16:166:18 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| generics.swift:166:16:166:18 | ArrayLiteral | Element | generics.swift:164:22:164:22 | D | +| generics.swift:166:17:166:17 | v | | generics.swift:164:22:164:22 | D | +| generics.swift:166:21:166:24 | true | | {EXTERNAL LOCATION} | Bool | +| generics.swift:174:38:174:43 | value1 | | generics.swift:174:10:174:11 | T1 | +| generics.swift:174:52:174:57 | value2 | | generics.swift:174:14:174:15 | T2 | +| generics.swift:174:66:174:69 | base | | generics.swift:174:18:174:33 | T3 | +| generics.swift:174:82:176:1 | Block | | generics.swift:174:18:174:33 | T3 | +| generics.swift:175:10:175:13 | base | | generics.swift:174:18:174:33 | T3 | +| generics.swift:178:21:178:26 | value1 | | generics.swift:178:11:178:12 | T1 | +| generics.swift:178:35:178:40 | value2 | | generics.swift:178:15:178:16 | T2 | +| generics.swift:178:49:178:52 | base | | generics.swift:136:1:152:1 | Base | +| generics.swift:178:49:178:52 | base | T1 | generics.swift:178:11:178:12 | T1 | +| generics.swift:178:49:178:52 | base | T2 | generics.swift:178:15:178:16 | T2 | +| generics.swift:182:35:182:40 | value1 | | generics.swift:182:10:182:10 | A | +| generics.swift:182:48:182:53 | value2 | | generics.swift:182:13:182:13 | B | +| generics.swift:182:61:182:64 | base | | generics.swift:182:16:182:30 | C | +| generics.swift:182:75:185:1 | Block | | generics.swift:182:16:182:30 | C | +| generics.swift:183:10:183:13 | base | | generics.swift:182:16:182:30 | C | +| generics.swift:187:19:187:24 | value1 | | generics.swift:187:11:187:11 | A | +| generics.swift:187:32:187:37 | value2 | | generics.swift:187:14:187:14 | B | +| generics.swift:187:45:187:48 | base | | generics.swift:136:1:152:1 | Base | +| generics.swift:187:45:187:48 | base | T1 | generics.swift:187:11:187:11 | A | +| generics.swift:187:45:187:48 | base | T2 | {EXTERNAL LOCATION} | Array | +| generics.swift:187:45:187:48 | base | T2.Element | generics.swift:187:14:187:14 | B | +| generics.swift:189:34:189:39 | value1 | | generics.swift:189:10:189:10 | A | +| generics.swift:189:47:189:52 | value2 | | generics.swift:189:13:189:13 | B | +| generics.swift:189:60:189:63 | base | | generics.swift:189:16:189:29 | C | +| generics.swift:189:74:192:1 | Block | | generics.swift:189:16:189:29 | C | +| generics.swift:190:10:190:13 | base | | generics.swift:189:16:189:29 | C | +| generics.swift:194:19:194:24 | value1 | | generics.swift:194:11:194:11 | A | +| generics.swift:194:32:194:37 | value2 | | generics.swift:194:14:194:14 | B | +| generics.swift:194:45:194:48 | base | | generics.swift:136:1:152:1 | Base | +| generics.swift:194:45:194:48 | base | T1 | generics.swift:194:11:194:11 | A | +| generics.swift:194:45:194:48 | base | T2 | {EXTERNAL LOCATION} | Optional | +| generics.swift:194:45:194:48 | base | T2.Wrapped | generics.swift:194:14:194:14 | B | +| generics.swift:201:7:201:7 | d | | generics.swift:154:1:162:1 | Derived | +| generics.swift:201:7:201:7 | d | T1 | {EXTERNAL LOCATION} | Int | +| generics.swift:201:7:201:7 | d | T2 | {EXTERNAL LOCATION} | String | +| generics.swift:201:11:201:25 | Derived(...) | | generics.swift:154:1:162:1 | Derived | +| generics.swift:201:11:201:25 | Derived(...) | T1 | {EXTERNAL LOCATION} | Int | +| generics.swift:201:11:201:25 | Derived(...) | T2 | {EXTERNAL LOCATION} | String | +| generics.swift:201:19:201:19 | 1 | | {EXTERNAL LOCATION} | Int | +| generics.swift:201:22:201:24 | "x" | | {EXTERNAL LOCATION} | String | +| generics.swift:202:7:202:8 | v1 | | {EXTERNAL LOCATION} | String | +| generics.swift:202:12:202:12 | d | | generics.swift:154:1:162:1 | Derived | +| generics.swift:202:12:202:12 | d | T1 | {EXTERNAL LOCATION} | Int | +| generics.swift:202:12:202:12 | d | T2 | {EXTERNAL LOCATION} | String | +| generics.swift:202:12:202:24 | ... .getValue1(...) | | {EXTERNAL LOCATION} | String | +| generics.swift:203:7:203:8 | v2 | | {EXTERNAL LOCATION} | Int | +| generics.swift:203:12:203:12 | d | | generics.swift:154:1:162:1 | Derived | +| generics.swift:203:12:203:12 | d | T1 | {EXTERNAL LOCATION} | Int | +| generics.swift:203:12:203:12 | d | T2 | {EXTERNAL LOCATION} | String | +| generics.swift:203:12:203:24 | ... .getValue2(...) | | {EXTERNAL LOCATION} | Int | +| generics.swift:205:7:205:8 | dd | | generics.swift:164:1:172:1 | DerivedDerived | +| generics.swift:205:7:205:8 | dd | D | {EXTERNAL LOCATION} | String | +| generics.swift:205:12:205:34 | DerivedDerived(...) | | generics.swift:164:1:172:1 | DerivedDerived | +| generics.swift:205:12:205:34 | DerivedDerived(...) | D | {EXTERNAL LOCATION} | String | +| generics.swift:205:27:205:33 | "hello" | | {EXTERNAL LOCATION} | String | +| generics.swift:206:7:206:9 | vv1 | | {EXTERNAL LOCATION} | Bool | +| generics.swift:206:13:206:14 | dd | | generics.swift:164:1:172:1 | DerivedDerived | +| generics.swift:206:13:206:14 | dd | D | {EXTERNAL LOCATION} | String | +| generics.swift:206:13:206:26 | ... .getValue1(...) | | {EXTERNAL LOCATION} | Bool | +| generics.swift:207:7:207:9 | vv2 | | {EXTERNAL LOCATION} | Array | +| generics.swift:207:7:207:9 | vv2 | Element | {EXTERNAL LOCATION} | String | +| generics.swift:207:13:207:14 | dd | | generics.swift:164:1:172:1 | DerivedDerived | +| generics.swift:207:13:207:14 | dd | D | {EXTERNAL LOCATION} | String | +| generics.swift:207:13:207:26 | ... .getValue2(...) | | {EXTERNAL LOCATION} | Array | +| generics.swift:207:13:207:26 | ... .getValue2(...) | Element | {EXTERNAL LOCATION} | String | +| generics.swift:209:7:209:7 | x | | generics.swift:164:1:172:1 | DerivedDerived | +| generics.swift:209:7:209:7 | x | D | {EXTERNAL LOCATION} | Int | +| generics.swift:209:11:209:52 | foo(...) | | generics.swift:164:1:172:1 | DerivedDerived | +| generics.swift:209:11:209:52 | foo(...) | D | {EXTERNAL LOCATION} | Int | +| generics.swift:209:15:209:19 | false | | {EXTERNAL LOCATION} | Bool | +| generics.swift:209:22:209:24 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| generics.swift:209:22:209:24 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int | +| generics.swift:209:23:209:23 | 2 | | {EXTERNAL LOCATION} | Int | +| generics.swift:209:27:209:51 | DerivedDerived(...) | | generics.swift:164:1:172:1 | DerivedDerived | +| generics.swift:209:27:209:51 | DerivedDerived(...) | D | {EXTERNAL LOCATION} | Int | +| generics.swift:209:42:209:50 | unknown(...) | | {EXTERNAL LOCATION} | Int | +| generics.swift:211:8:211:12 | false | | {EXTERNAL LOCATION} | Bool | +| generics.swift:211:15:211:17 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| generics.swift:211:15:211:17 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int | +| generics.swift:211:16:211:16 | 2 | | {EXTERNAL LOCATION} | Int | +| generics.swift:211:20:211:44 | DerivedDerived(...) | | generics.swift:164:1:172:1 | DerivedDerived | +| generics.swift:211:20:211:44 | DerivedDerived(...) | D | {EXTERNAL LOCATION} | Int | +| generics.swift:211:35:211:43 | unknown(...) | | {EXTERNAL LOCATION} | Int | +| generics.swift:213:7:213:7 | y | | generics.swift:164:1:172:1 | DerivedDerived | +| generics.swift:213:7:213:7 | y | D | {EXTERNAL LOCATION} | Int | +| generics.swift:213:11:213:50 | bar(...) | | generics.swift:164:1:172:1 | DerivedDerived | +| generics.swift:213:11:213:50 | bar(...) | D | {EXTERNAL LOCATION} | Int | +| 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:49 | DerivedDerived(...) | | generics.swift:164:1:172:1 | DerivedDerived | +| generics.swift:213:25:213:49 | DerivedDerived(...) | D | {EXTERNAL LOCATION} | Int | +| generics.swift:213:40:213:48 | unknown(...) | | {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:42 | DerivedDerived(...) | | generics.swift:164:1:172:1 | DerivedDerived | +| generics.swift:215:18:215:42 | DerivedDerived(...) | D | {EXTERNAL LOCATION} | Int | +| generics.swift:215:33:215:41 | unknown(...) | | {EXTERNAL LOCATION} | Int | +| generics.swift:217:7:217:7 | w | | generics.swift:154:1:162:1 | Derived | +| generics.swift:217:7:217:7 | w | T1 | {EXTERNAL LOCATION} | Optional | +| generics.swift:217:7:217:7 | w | T1.Wrapped | {EXTERNAL LOCATION} | Int | +| generics.swift:217:7:217:7 | w | T2 | {EXTERNAL LOCATION} | Bool | +| generics.swift:217:11:217:47 | baz(...) | | generics.swift:154:1:162:1 | Derived | +| generics.swift:217:11:217:47 | baz(...) | T1 | {EXTERNAL LOCATION} | Optional | +| generics.swift:217:11:217:47 | baz(...) | T1.Wrapped | {EXTERNAL LOCATION} | Int | +| generics.swift:217:11:217:47 | baz(...) | T2 | {EXTERNAL LOCATION} | Bool | +| generics.swift:217:15:217:19 | false | | {EXTERNAL LOCATION} | Bool | +| generics.swift:217:22:217:22 | 2 | | {EXTERNAL LOCATION} | Int | +| generics.swift:217:25:217:46 | Derived(...) | | generics.swift:154:1:162:1 | Derived | +| generics.swift:217:25:217:46 | Derived(...) | T1 | {EXTERNAL LOCATION} | Optional | +| generics.swift:217:25:217:46 | Derived(...) | T1.Wrapped | {EXTERNAL LOCATION} | Int | +| generics.swift:217:33:217:45 | ... .none | | {EXTERNAL LOCATION} | Optional | +| generics.swift:217:33:217:45 | ... .none | Wrapped | {EXTERNAL LOCATION} | Int | +| generics.swift:219:8:219:12 | false | | {EXTERNAL LOCATION} | Bool | +| generics.swift:219:15:219:15 | 2 | | {EXTERNAL LOCATION} | Int | +| generics.swift:219:18:219:39 | Derived(...) | | generics.swift:154:1:162:1 | Derived | +| generics.swift:219:18:219:39 | Derived(...) | T1 | {EXTERNAL LOCATION} | Optional | +| generics.swift:219:18:219:39 | Derived(...) | T1.Wrapped | {EXTERNAL LOCATION} | Int | +| generics.swift:219:26:219:38 | ... .none | | {EXTERNAL LOCATION} | Optional | +| generics.swift:219:26:219:38 | ... .none | Wrapped | {EXTERNAL LOCATION} | Int | +| generics.swift:231:22:233:3 | Block | | generics.swift:224:1:228:1 | MyProtocol2 | +| generics.swift:232:12:232:15 | self | | generics.swift:224:1:228:1 | MyProtocol2 | +| generics.swift:237:7:237:11 | value | | generics.swift:236:15:236:15 | T | +| generics.swift:239:10:239:14 | value | | generics.swift:236:15:236:15 | T | +| generics.swift:239:20:241:3 | Block | | generics.swift:236:15:236:15 | T | +| generics.swift:240:5:240:8 | self | | generics.swift:236:1:242:1 | MyClass | +| generics.swift:240:5:240:8 | self | T | generics.swift:236:15:236:15 | T | +| generics.swift:240:5:240:14 | ... .value | | generics.swift:236:15:236:15 | T | +| generics.swift:240:5:240:22 | ... = ... | | generics.swift:236:15:236:15 | T | +| generics.swift:240:18:240:22 | value | | generics.swift:236:15:236:15 | T | +| generics.swift:252:32:252:32 | c | | generics.swift:252:14:252:27 | T | +| generics.swift:253:10:253:10 | c | | generics.swift:252:14:252:27 | T | +| generics.swift:256:32:256:32 | c | | generics.swift:256:14:256:27 | T | +| generics.swift:257:10:257:10 | c | | generics.swift:256:14:256:27 | T | +| generics.swift:261:7:261:7 | c | | generics.swift:236:1:242:1 | MyClass | +| generics.swift:261:7:261:7 | c | T | {EXTERNAL LOCATION} | Int | +| generics.swift:261:11:261:21 | MyClass(...) | | generics.swift:236:1:242:1 | MyClass | +| generics.swift:261:11:261:21 | MyClass(...) | T | {EXTERNAL LOCATION} | Int | +| generics.swift:261:19:261:20 | 42 | | {EXTERNAL LOCATION} | Int | +| generics.swift:262:11:262:11 | c | | generics.swift:236:1:242:1 | MyClass | +| generics.swift:262:11:262:11 | c | T | {EXTERNAL LOCATION} | Int | +| generics.swift:263:11:263:11 | c | | generics.swift:236:1:242:1 | MyClass | +| generics.swift:263:11:263:11 | c | T | {EXTERNAL LOCATION} | Int | +| generics.swift:264:20:264:20 | c | | generics.swift:236:1:242:1 | MyClass | +| generics.swift:264:20:264:20 | c | T | {EXTERNAL LOCATION} | Int | +| generics.swift:282:30:284:3 | Block | | {EXTERNAL LOCATION} | String | +| generics.swift:283:12:283:17 | "base" | | {EXTERNAL LOCATION} | String | +| generics.swift:286:29:288:3 | Block | | {EXTERNAL LOCATION} | String | +| generics.swift:287:12:287:16 | "sub" | | {EXTERNAL LOCATION} | String | +| generics.swift:291:65:291:69 | value | | generics.swift:291:33:291:60 | T | +| generics.swift:292:10:292:14 | value | | generics.swift:291:33:291:60 | T | +| generics.swift:296:42:296:63 | StringAssociatedType(...) | | generics.swift:279:1:289:1 | StringAssociatedType | +| generics.swift:310:25:312:3 | Block | | {EXTERNAL LOCATION} | Int | +| generics.swift:311:12:311:13 | 42 | | {EXTERNAL LOCATION} | Int | +| generics.swift:320:7:320:11 | value | | {EXTERNAL LOCATION} | Int | +| generics.swift:320:15:320:66 | getPrimaryAssociatedType(...) | | {EXTERNAL LOCATION} | Int | +| generics.swift:320:40:320:65 | IntPrimaryAssociatedType(...) | | generics.swift:307:1:313:1 | IntPrimaryAssociatedType | | key_paths.swift:4:7:4:7 | x | | {EXTERNAL LOCATION} | Double | | key_paths.swift:5:7:5:7 | y | | {EXTERNAL LOCATION} | Double | | key_paths.swift:7:8:7:8 | x | | {EXTERNAL LOCATION} | Double |