From b439222d5eeabedcb67c49eff823d41af65f98be Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 6 Oct 2026 13:08:34 +0200 Subject: [PATCH 1/2] Rust: More type inference tests --- .../test/library-tests/type-inference/main.rs | 25 +++ .../type-inference/type-inference.expected | 145 ++++++++++++------ 2 files changed, 123 insertions(+), 47 deletions(-) diff --git a/rust/ql/test/library-tests/type-inference/main.rs b/rust/ql/test/library-tests/type-inference/main.rs index 2c462aa114a7..476e388d8e0a 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()); // $ MISSING: 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..14114f42f6cf 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,94 @@ 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:17:2833:44 | MyThingB(...) | | main.rs:2817:5:2817:26 | MyThingB | +| 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:23:2834:23 | z | | main.rs:2817:5:2817:26 | MyThingB | +| 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 | From 10f6b3b6d1a8ac52d8268b63d945b7e15f87a51b Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 6 Oct 2026 13:09:09 +0200 Subject: [PATCH 2/2] Type inference: Improve constraint matching --- .../test/library-tests/type-inference/main.rs | 2 +- .../type-inference/type-inference.expected | 10 +++ .../typeinference/internal/TypeInference.qll | 74 +++++++++++++++---- 3 files changed, 69 insertions(+), 17 deletions(-) diff --git a/rust/ql/test/library-tests/type-inference/main.rs b/rust/ql/test/library-tests/type-inference/main.rs index 476e388d8e0a..006835b89188 100644 --- a/rust/ql/test/library-tests/type-inference/main.rs +++ b/rust/ql/test/library-tests/type-inference/main.rs @@ -2830,7 +2830,7 @@ mod contextual_bound { bar(x, Some(y)); // $ target=bar let x = S(0); - let z = MyThingB(Default::default()); // $ MISSING: type=z@MyThingB.S:i32 target=default + let z = MyThingB(Default::default()); // $ type=z@MyThingB.S:i32 target=default bar([x], Some(z)); // $ target=bar } } 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 14114f42f6cf..b519e18357b3 100644 --- a/rust/ql/test/library-tests/type-inference/type-inference.expected +++ b/rust/ql/test/library-tests/type-inference/type-inference.expected @@ -12814,7 +12814,13 @@ inferType | 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 | @@ -12823,7 +12829,11 @@ inferType | 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 | diff --git a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll index 749e6ce600cf..dd548f54de13 100644 --- a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll +++ b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll @@ -1785,44 +1785,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)) ) ) }