From 21c030fa46c42b7c0fee1faa3cf769aa94f89408 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Mon, 14 Jul 2025 15:58:16 +0200 Subject: [PATCH 1/8] Rust: Expand on type inference test for tuples --- .../test/library-tests/type-inference/main.rs | 19 +- .../type-inference/type-inference.expected | 184 +++++++++--------- 2 files changed, 108 insertions(+), 95 deletions(-) diff --git a/rust/ql/test/library-tests/type-inference/main.rs b/rust/ql/test/library-tests/type-inference/main.rs index a4a37e27794c..2be80169aa4e 100644 --- a/rust/ql/test/library-tests/type-inference/main.rs +++ b/rust/ql/test/library-tests/type-inference/main.rs @@ -2334,11 +2334,11 @@ mod tuples { } pub fn f() { - let a = S1::get_pair(); // $ target=get_pair MISSING: type=a:? - let mut b = S1::get_pair(); // $ target=get_pair MISSING: type=b:? - let (c, d) = S1::get_pair(); // $ target=get_pair MISSING: type=c:? type=d:? - let (mut e, f) = S1::get_pair(); // $ target=get_pair MISSING: type=e: type=f: - let (mut g, mut h) = S1::get_pair(); // $ target=get_pair MISSING: type=g:? type=h:? + let a = S1::get_pair(); // $ target=get_pair MISSING: type=a:(T_2) + let mut b = S1::get_pair(); // $ target=get_pair MISSING: type=b:(T_2) + let (c, d) = S1::get_pair(); // $ target=get_pair MISSING: type=c:S1 type=d:S1 + let (mut e, f) = S1::get_pair(); // $ target=get_pair MISSING: type=e:S1 type=f:S1 + let (mut g, mut h) = S1::get_pair(); // $ target=get_pair MISSING: type=g:S1 type=h:S1 a.0.foo(); // $ MISSING: target=foo b.1.foo(); // $ MISSING: target=foo @@ -2348,6 +2348,15 @@ mod tuples { f.foo(); // $ MISSING: target=foo g.foo(); // $ MISSING: target=foo h.foo(); // $ MISSING: target=foo + + // Here type information must flow from `pair.0` and `pair.1` into + // `pair` and from `(a, b)` into `a` and `b` in order for the types of + // `a` and `b` to be inferred. + let a = Default::default(); // $ MISSING: target=default type=a:i64 + let b = Default::default(); // $ MISSING: target=default MISSING: type=b:bool + let pair = (a, b); // $ MISSING: type=pair:0.i64 type=pair:1.bool + let i: i64 = pair.0; + let j: bool = pair.1; } } 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 e4da3d0dd168..f19cfbfe8363 100644 --- a/rust/ql/test/library-tests/type-inference/type-inference.expected +++ b/rust/ql/test/library-tests/type-inference/type-inference.expected @@ -4059,96 +4059,100 @@ inferType | main.rs:2331:14:2331:18 | S1 {...} | | main.rs:2327:5:2327:16 | S1 | | main.rs:2331:21:2331:25 | S1 {...} | | main.rs:2327:5:2327:16 | S1 | | main.rs:2333:16:2333:19 | SelfParam | | main.rs:2327:5:2327:16 | S1 | -| main.rs:2357:13:2357:23 | boxed_value | | {EXTERNAL LOCATION} | Box | -| main.rs:2357:13:2357:23 | boxed_value | A | {EXTERNAL LOCATION} | Global | -| main.rs:2357:13:2357:23 | boxed_value | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2357:27:2357:42 | ...::new(...) | | {EXTERNAL LOCATION} | Box | -| main.rs:2357:27:2357:42 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | -| main.rs:2357:27:2357:42 | ...::new(...) | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2357:36:2357:41 | 100i32 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2360:15:2360:25 | boxed_value | | {EXTERNAL LOCATION} | Box | -| main.rs:2360:15:2360:25 | boxed_value | A | {EXTERNAL LOCATION} | Global | -| main.rs:2360:15:2360:25 | boxed_value | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2361:13:2361:19 | box 100 | | {EXTERNAL LOCATION} | Box | -| main.rs:2361:13:2361:19 | box 100 | A | {EXTERNAL LOCATION} | Global | -| main.rs:2361:13:2361:19 | box 100 | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2361:17:2361:19 | 100 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2362:26:2362:36 | "Boxed 100\\n" | | file://:0:0:0:0 | & | -| main.rs:2362:26:2362:36 | "Boxed 100\\n" | &T | {EXTERNAL LOCATION} | str | -| main.rs:2362:26:2362:36 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | -| main.rs:2362:26:2362:36 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | -| main.rs:2364:13:2364:17 | box ... | | {EXTERNAL LOCATION} | Box | -| main.rs:2364:13:2364:17 | box ... | A | {EXTERNAL LOCATION} | Global | -| main.rs:2364:13:2364:17 | box ... | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2366:26:2366:42 | "Boxed value: {}\\n" | | file://:0:0:0:0 | & | -| main.rs:2366:26:2366:42 | "Boxed value: {}\\n" | &T | {EXTERNAL LOCATION} | str | -| main.rs:2366:26:2366:51 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | -| main.rs:2366:26:2366:51 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | -| main.rs:2371:13:2371:22 | nested_box | | {EXTERNAL LOCATION} | Box | -| main.rs:2371:13:2371:22 | nested_box | A | {EXTERNAL LOCATION} | Global | -| main.rs:2371:13:2371:22 | nested_box | T | {EXTERNAL LOCATION} | Box | -| main.rs:2371:13:2371:22 | nested_box | T.A | {EXTERNAL LOCATION} | Global | -| main.rs:2371:13:2371:22 | nested_box | T.T | {EXTERNAL LOCATION} | i32 | -| main.rs:2371:26:2371:50 | ...::new(...) | | {EXTERNAL LOCATION} | Box | -| main.rs:2371:26:2371:50 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | -| main.rs:2371:26:2371:50 | ...::new(...) | T | {EXTERNAL LOCATION} | Box | -| main.rs:2371:26:2371:50 | ...::new(...) | T.A | {EXTERNAL LOCATION} | Global | -| main.rs:2371:26:2371:50 | ...::new(...) | T.T | {EXTERNAL LOCATION} | i32 | -| main.rs:2371:35:2371:49 | ...::new(...) | | {EXTERNAL LOCATION} | Box | -| main.rs:2371:35:2371:49 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | -| main.rs:2371:35:2371:49 | ...::new(...) | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2371:44:2371:48 | 42i32 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2372:15:2372:24 | nested_box | | {EXTERNAL LOCATION} | Box | -| main.rs:2372:15:2372:24 | nested_box | A | {EXTERNAL LOCATION} | Global | -| main.rs:2372:15:2372:24 | nested_box | T | {EXTERNAL LOCATION} | Box | -| main.rs:2372:15:2372:24 | nested_box | T.A | {EXTERNAL LOCATION} | Global | -| main.rs:2372:15:2372:24 | nested_box | T.T | {EXTERNAL LOCATION} | i32 | -| main.rs:2373:13:2373:21 | box ... | | {EXTERNAL LOCATION} | Box | -| main.rs:2373:13:2373:21 | box ... | A | {EXTERNAL LOCATION} | Global | -| main.rs:2373:13:2373:21 | box ... | T | {EXTERNAL LOCATION} | Box | -| main.rs:2373:13:2373:21 | box ... | T.A | {EXTERNAL LOCATION} | Global | -| main.rs:2373:13:2373:21 | box ... | T.T | {EXTERNAL LOCATION} | i32 | -| main.rs:2375:26:2375:43 | "Nested boxed: {}\\n" | | file://:0:0:0:0 | & | -| main.rs:2375:26:2375:43 | "Nested boxed: {}\\n" | &T | {EXTERNAL LOCATION} | str | -| main.rs:2375:26:2375:59 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | -| main.rs:2375:26:2375:59 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | -| main.rs:2387:16:2387:20 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:2387:16:2387:20 | SelfParam | &T | main.rs:2382:5:2384:5 | Row | -| main.rs:2387:30:2389:9 | { ... } | | {EXTERNAL LOCATION} | i64 | -| main.rs:2388:13:2388:16 | self | | file://:0:0:0:0 | & | -| main.rs:2388:13:2388:16 | self | &T | main.rs:2382:5:2384:5 | Row | -| main.rs:2388:13:2388:21 | self.data | | {EXTERNAL LOCATION} | i64 | -| main.rs:2397:26:2399:9 | { ... } | | main.rs:2392:5:2394:5 | Table | -| main.rs:2398:13:2398:38 | Table {...} | | main.rs:2392:5:2394:5 | Table | -| main.rs:2398:27:2398:36 | ...::new(...) | | {EXTERNAL LOCATION} | Vec | -| main.rs:2398:27:2398:36 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | -| main.rs:2398:27:2398:36 | ...::new(...) | T | main.rs:2382:5:2384:5 | Row | -| main.rs:2401:23:2401:27 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:2401:23:2401:27 | SelfParam | &T | main.rs:2392:5:2394:5 | Table | -| main.rs:2401:30:2401:37 | property | | main.rs:2401:40:2401:59 | ImplTraitTypeRepr | -| main.rs:2401:69:2403:9 | { ... } | | {EXTERNAL LOCATION} | i32 | -| main.rs:2401:69:2403:9 | { ... } | | {EXTERNAL LOCATION} | i64 | -| main.rs:2402:13:2402:13 | 0 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2402:13:2402:13 | 0 | | {EXTERNAL LOCATION} | i64 | -| main.rs:2407:9:2407:15 | Some(...) | | {EXTERNAL LOCATION} | Option | -| main.rs:2407:9:2407:15 | Some(...) | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2407:9:2410:10 | ... .map(...) | | {EXTERNAL LOCATION} | Option | -| main.rs:2407:14:2407:14 | 1 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2409:22:2409:26 | "{x}\\n" | | file://:0:0:0:0 | & | -| main.rs:2409:22:2409:26 | "{x}\\n" | &T | {EXTERNAL LOCATION} | str | -| main.rs:2409:22:2409:26 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | -| main.rs:2409:22:2409:26 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | -| main.rs:2412:13:2412:17 | table | | main.rs:2392:5:2394:5 | Table | -| main.rs:2412:21:2412:32 | ...::new(...) | | main.rs:2392:5:2394:5 | Table | -| main.rs:2413:13:2413:18 | result | | {EXTERNAL LOCATION} | i64 | -| main.rs:2413:22:2413:26 | table | | main.rs:2392:5:2394:5 | Table | -| main.rs:2413:22:2417:14 | table.count_with(...) | | {EXTERNAL LOCATION} | i64 | -| main.rs:2416:21:2416:21 | 0 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2423:5:2423:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo | -| main.rs:2424:5:2424:60 | ...::g(...) | | main.rs:72:5:72:21 | Foo | -| main.rs:2424:20:2424:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | -| main.rs:2424:41:2424:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | -| main.rs:2440:5:2440:15 | ...::f(...) | | {EXTERNAL LOCATION} | trait Future | +| main.rs:2358:13:2358:13 | i | | {EXTERNAL LOCATION} | i64 | +| main.rs:2358:22:2358:27 | pair.0 | | {EXTERNAL LOCATION} | i64 | +| main.rs:2359:13:2359:13 | j | | {EXTERNAL LOCATION} | bool | +| main.rs:2359:23:2359:28 | pair.1 | | {EXTERNAL LOCATION} | bool | +| main.rs:2366:13:2366:23 | boxed_value | | {EXTERNAL LOCATION} | Box | +| main.rs:2366:13:2366:23 | boxed_value | A | {EXTERNAL LOCATION} | Global | +| main.rs:2366:13:2366:23 | boxed_value | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2366:27:2366:42 | ...::new(...) | | {EXTERNAL LOCATION} | Box | +| main.rs:2366:27:2366:42 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | +| main.rs:2366:27:2366:42 | ...::new(...) | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2366:36:2366:41 | 100i32 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2369:15:2369:25 | boxed_value | | {EXTERNAL LOCATION} | Box | +| main.rs:2369:15:2369:25 | boxed_value | A | {EXTERNAL LOCATION} | Global | +| main.rs:2369:15:2369:25 | boxed_value | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2370:13:2370:19 | box 100 | | {EXTERNAL LOCATION} | Box | +| main.rs:2370:13:2370:19 | box 100 | A | {EXTERNAL LOCATION} | Global | +| main.rs:2370:13:2370:19 | box 100 | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2370:17:2370:19 | 100 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2371:26:2371:36 | "Boxed 100\\n" | | file://:0:0:0:0 | & | +| main.rs:2371:26:2371:36 | "Boxed 100\\n" | &T | {EXTERNAL LOCATION} | str | +| main.rs:2371:26:2371:36 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2371:26:2371:36 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2373:13:2373:17 | box ... | | {EXTERNAL LOCATION} | Box | +| main.rs:2373:13:2373:17 | box ... | A | {EXTERNAL LOCATION} | Global | +| main.rs:2373:13:2373:17 | box ... | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2375:26:2375:42 | "Boxed value: {}\\n" | | file://:0:0:0:0 | & | +| main.rs:2375:26:2375:42 | "Boxed value: {}\\n" | &T | {EXTERNAL LOCATION} | str | +| main.rs:2375:26:2375:51 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2375:26:2375:51 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2380:13:2380:22 | nested_box | | {EXTERNAL LOCATION} | Box | +| main.rs:2380:13:2380:22 | nested_box | A | {EXTERNAL LOCATION} | Global | +| main.rs:2380:13:2380:22 | nested_box | T | {EXTERNAL LOCATION} | Box | +| main.rs:2380:13:2380:22 | nested_box | T.A | {EXTERNAL LOCATION} | Global | +| main.rs:2380:13:2380:22 | nested_box | T.T | {EXTERNAL LOCATION} | i32 | +| main.rs:2380:26:2380:50 | ...::new(...) | | {EXTERNAL LOCATION} | Box | +| main.rs:2380:26:2380:50 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | +| main.rs:2380:26:2380:50 | ...::new(...) | T | {EXTERNAL LOCATION} | Box | +| main.rs:2380:26:2380:50 | ...::new(...) | T.A | {EXTERNAL LOCATION} | Global | +| main.rs:2380:26:2380:50 | ...::new(...) | T.T | {EXTERNAL LOCATION} | i32 | +| main.rs:2380:35:2380:49 | ...::new(...) | | {EXTERNAL LOCATION} | Box | +| main.rs:2380:35:2380:49 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | +| main.rs:2380:35:2380:49 | ...::new(...) | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2380:44:2380:48 | 42i32 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2381:15:2381:24 | nested_box | | {EXTERNAL LOCATION} | Box | +| main.rs:2381:15:2381:24 | nested_box | A | {EXTERNAL LOCATION} | Global | +| main.rs:2381:15:2381:24 | nested_box | T | {EXTERNAL LOCATION} | Box | +| main.rs:2381:15:2381:24 | nested_box | T.A | {EXTERNAL LOCATION} | Global | +| main.rs:2381:15:2381:24 | nested_box | T.T | {EXTERNAL LOCATION} | i32 | +| main.rs:2382:13:2382:21 | box ... | | {EXTERNAL LOCATION} | Box | +| main.rs:2382:13:2382:21 | box ... | A | {EXTERNAL LOCATION} | Global | +| main.rs:2382:13:2382:21 | box ... | T | {EXTERNAL LOCATION} | Box | +| main.rs:2382:13:2382:21 | box ... | T.A | {EXTERNAL LOCATION} | Global | +| main.rs:2382:13:2382:21 | box ... | T.T | {EXTERNAL LOCATION} | i32 | +| main.rs:2384:26:2384:43 | "Nested boxed: {}\\n" | | file://:0:0:0:0 | & | +| main.rs:2384:26:2384:43 | "Nested boxed: {}\\n" | &T | {EXTERNAL LOCATION} | str | +| main.rs:2384:26:2384:59 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2384:26:2384:59 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2396:16:2396:20 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:2396:16:2396:20 | SelfParam | &T | main.rs:2391:5:2393:5 | Row | +| main.rs:2396:30:2398:9 | { ... } | | {EXTERNAL LOCATION} | i64 | +| main.rs:2397:13:2397:16 | self | | file://:0:0:0:0 | & | +| main.rs:2397:13:2397:16 | self | &T | main.rs:2391:5:2393:5 | Row | +| main.rs:2397:13:2397:21 | self.data | | {EXTERNAL LOCATION} | i64 | +| main.rs:2406:26:2408:9 | { ... } | | main.rs:2401:5:2403:5 | Table | +| main.rs:2407:13:2407:38 | Table {...} | | main.rs:2401:5:2403:5 | Table | +| main.rs:2407:27:2407:36 | ...::new(...) | | {EXTERNAL LOCATION} | Vec | +| main.rs:2407:27:2407:36 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | +| main.rs:2407:27:2407:36 | ...::new(...) | T | main.rs:2391:5:2393:5 | Row | +| main.rs:2410:23:2410:27 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:2410:23:2410:27 | SelfParam | &T | main.rs:2401:5:2403:5 | Table | +| main.rs:2410:30:2410:37 | property | | main.rs:2410:40:2410:59 | ImplTraitTypeRepr | +| main.rs:2410:69:2412:9 | { ... } | | {EXTERNAL LOCATION} | i32 | +| main.rs:2410:69:2412:9 | { ... } | | {EXTERNAL LOCATION} | i64 | +| main.rs:2411:13:2411:13 | 0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2411:13:2411:13 | 0 | | {EXTERNAL LOCATION} | i64 | +| main.rs:2416:9:2416:15 | Some(...) | | {EXTERNAL LOCATION} | Option | +| main.rs:2416:9:2416:15 | Some(...) | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2416:9:2419:10 | ... .map(...) | | {EXTERNAL LOCATION} | Option | +| main.rs:2416:14:2416:14 | 1 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2418:22:2418:26 | "{x}\\n" | | file://:0:0:0:0 | & | +| main.rs:2418:22:2418:26 | "{x}\\n" | &T | {EXTERNAL LOCATION} | str | +| main.rs:2418:22:2418:26 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2418:22:2418:26 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2421:13:2421:17 | table | | main.rs:2401:5:2403:5 | Table | +| main.rs:2421:21:2421:32 | ...::new(...) | | main.rs:2401:5:2403:5 | Table | +| main.rs:2422:13:2422:18 | result | | {EXTERNAL LOCATION} | i64 | +| main.rs:2422:22:2422:26 | table | | main.rs:2401:5:2403:5 | Table | +| main.rs:2422:22:2426:14 | table.count_with(...) | | {EXTERNAL LOCATION} | i64 | +| main.rs:2425:21:2425:21 | 0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2432:5:2432:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo | +| main.rs:2433:5:2433:60 | ...::g(...) | | main.rs:72:5:72:21 | Foo | +| main.rs:2433:20:2433:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | +| main.rs:2433:41:2433:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | +| main.rs:2449:5:2449:15 | ...::f(...) | | {EXTERNAL LOCATION} | trait Future | | pattern_matching.rs:13:26:133:1 | { ... } | | {EXTERNAL LOCATION} | Option | | pattern_matching.rs:14:9:14:13 | value | | {EXTERNAL LOCATION} | Option | | pattern_matching.rs:14:9:14:13 | value | T | {EXTERNAL LOCATION} | i32 | From 03a9a1688e18e6c77d4309c0fe7f4bd57bfd3547 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Mon, 14 Jul 2025 16:37:05 +0200 Subject: [PATCH 2/8] Rust: Add type inference for tuples --- rust/ql/lib/codeql/rust/internal/Type.qll | 45 +- .../codeql/rust/internal/TypeInference.qll | 51 +- .../lib/codeql/rust/internal/TypeMention.qll | 12 + .../test/library-tests/type-inference/main.rs | 34 +- .../type-inference/pattern_matching.rs | 34 +- .../type-inference/type-inference.expected | 434 ++++++++++++++++++ 6 files changed, 571 insertions(+), 39 deletions(-) diff --git a/rust/ql/lib/codeql/rust/internal/Type.qll b/rust/ql/lib/codeql/rust/internal/Type.qll index 77337138a84f..ca49f3c258df 100644 --- a/rust/ql/lib/codeql/rust/internal/Type.qll +++ b/rust/ql/lib/codeql/rust/internal/Type.qll @@ -9,14 +9,17 @@ private import codeql.rust.elements.internal.generated.Synth cached newtype TType = - TUnit() or - TStruct(Struct s) { Stages::TypeInferenceStage::ref() } or + TTuple(int arity) { + exists(any(TupleTypeRepr t).getField(arity)) and Stages::TypeInferenceStage::ref() + } or + TStruct(Struct s) or TEnum(Enum e) or TTrait(Trait t) or TArrayType() or // todo: add size? TRefType() or // todo: add mut? TImplTraitType(ImplTraitTypeRepr impl) or TSliceType() or + TTupleTypeParameter(int i) { exists(TTuple(i)) } or TTypeParamTypeParameter(TypeParam t) or TAssociatedTypeTypeParameter(TypeAlias t) { any(TraitItemNode trait).getAnAssocItem() = t } or TArrayTypeParameter() or @@ -56,8 +59,8 @@ abstract class Type extends TType { } /** The unit type `()`. */ -class UnitType extends Type, TUnit { - UnitType() { this = TUnit() } +class UnitType extends Type, TTuple { + UnitType() { this = TTuple(0) } override StructField getStructField(string name) { none() } @@ -70,6 +73,25 @@ class UnitType extends Type, TUnit { override Location getLocation() { result instanceof EmptyLocation } } +/** A tuple type `(T, ...)`. */ +class TupleType extends Type, TTuple { + private int arity; + + TupleType() { this = TTuple(arity) and arity > 0 } + + override StructField getStructField(string name) { none() } + + override TupleField getTupleField(int i) { none() } + + override TypeParameter getTypeParameter(int i) { result = TTupleTypeParameter(i) and i < arity } + + int getArity() { result = arity } + + override string toString() { result = "(T_" + arity + ")" } + + override Location getLocation() { result instanceof EmptyLocation } +} + abstract private class StructOrEnumType extends Type { abstract ItemNode asItemNode(); } @@ -329,6 +351,21 @@ class AssociatedTypeTypeParameter extends TypeParameter, TAssociatedTypeTypePara override Location getLocation() { result = typeAlias.getLocation() } } +/** + * A tuple type parameter. For instance the `T` in `(T, U)`. + * + * Since tuples are structural their parameters can be represented simply as + * their positional index. + */ +class TupleTypeParameter extends TypeParameter, TTupleTypeParameter { + override string toString() { result = this.getIndex().toString() } + + override Location getLocation() { result instanceof EmptyLocation } + + /** Gets the index of this tuple type parameter. */ + int getIndex() { this = TTupleTypeParameter(result) } +} + /** An implicit array type parameter. */ class ArrayTypeParameter extends TypeParameter, TArrayTypeParameter { override string toString() { result = "[T;...]" } diff --git a/rust/ql/lib/codeql/rust/internal/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/TypeInference.qll index 5ebb8eaa3175..1d2e7ee02de8 100644 --- a/rust/ql/lib/codeql/rust/internal/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/TypeInference.qll @@ -103,6 +103,9 @@ private module Input1 implements InputSig1 { node = tp0.(SelfTypeParameter).getTrait() or node = tp0.(ImplTraitTypeTypeParameter).getImplTraitTypeRepr() ) + or + kind = 2 and + id = tp0.(TupleTypeParameter).getIndex() | tp0 order by kind, id ) @@ -229,7 +232,7 @@ private Type inferLogicalOperationType(AstNode n, TypePath path) { private Type inferAssignmentOperationType(AstNode n, TypePath path) { n instanceof AssignmentOperation and path.isEmpty() and - result = TUnit() + result instanceof UnitType } pragma[nomagic] @@ -321,6 +324,14 @@ private predicate typeEquality(AstNode n1, TypePath prefix1, AstNode n2, TypePat prefix1.isEmpty() and prefix2 = TypePath::singleton(TRefTypeParameter()) or + exists(int i | + prefix1.isEmpty() and + prefix2 = TypePath::singleton(TTupleTypeParameter(i)) + | + n1 = n2.(TupleExpr).getField(i) or + n1 = n2.(TuplePat).getField(i) + ) + or exists(BlockExpr be | n1 = be and n2 = be.getStmtList().getTailExpr() and @@ -534,6 +545,12 @@ private Type inferStructExprType(AstNode n, TypePath path) { ) } +pragma[nomagic] +private Type inferTupleExprRootType(TupleExpr te) { + // `typeEquality` handles the non-root case + result = TTuple(te.getNumberOfFields()) +} + pragma[nomagic] private Type inferPathExprType(PathExpr pe, TypePath path) { // nullary struct/variant constructors @@ -1055,6 +1072,31 @@ private Type inferFieldExprType(AstNode n, TypePath path) { ) } +pragma[nomagic] +private Type inferTupleIndexExprType(FieldExpr fe, TypePath path) { + exists(int i, TypePath path0 | + fe.getIdentifier().getText() = i.toString() and + result = inferType(fe.getContainer(), path0) and + path0.isCons(TTupleTypeParameter(i), path) and + fe.getIdentifier().getText() = i.toString() + ) +} + +/** Infers the type of `t` in `t.n` when `t` is a tuple. */ +private Type inferTupleContainerExprType(Expr e, TypePath path) { + // NOTE: For a field expression `t.n` where `n` is a number `t` might both be + // a tuple struct or a tuple. It is only correct to let type information flow + // from `t.n` to tuple type parameters of `t` in the latter case. Hence we + // include the condition that the root type of `t` must be a tuple type. + exists(int i, TypePath path0, FieldExpr fe | + e = fe.getContainer() and + fe.getIdentifier().getText() = i.toString() and + inferType(fe.getContainer()) instanceof TupleType and + result = inferType(fe, path0) and + path = TypePath::cons(TTupleTypeParameter(i), path0) + ) +} + /** Gets the root type of the reference node `ref`. */ pragma[nomagic] private Type inferRefNodeType(AstNode ref) { @@ -1943,12 +1985,19 @@ private module Cached { or result = inferStructExprType(n, path) or + result = inferTupleExprRootType(n) and + path.isEmpty() + or result = inferPathExprType(n, path) or result = inferCallExprBaseType(n, path) or result = inferFieldExprType(n, path) or + result = inferTupleIndexExprType(n, path) + or + result = inferTupleContainerExprType(n, path) + or result = inferRefNodeType(n) and path.isEmpty() or diff --git a/rust/ql/lib/codeql/rust/internal/TypeMention.qll b/rust/ql/lib/codeql/rust/internal/TypeMention.qll index 6dd69ef49fc5..a40c068b4894 100644 --- a/rust/ql/lib/codeql/rust/internal/TypeMention.qll +++ b/rust/ql/lib/codeql/rust/internal/TypeMention.qll @@ -14,6 +14,18 @@ abstract class TypeMention extends AstNode { final Type resolveType() { result = this.resolveTypeAt(TypePath::nil()) } } +class TupleTypeReprMention extends TypeMention instanceof TupleTypeRepr { + override Type resolveTypeAt(TypePath path) { + path.isEmpty() and + result = TTuple(super.getNumberOfFields()) + or + exists(TypePath suffix, int i | + result = super.getField(i).(TypeMention).resolveTypeAt(suffix) and + path = TypePath::cons(TTupleTypeParameter(i), suffix) + ) + } +} + class ArrayTypeReprMention extends TypeMention instanceof ArrayTypeRepr { override Type resolveTypeAt(TypePath path) { path.isEmpty() and diff --git a/rust/ql/test/library-tests/type-inference/main.rs b/rust/ql/test/library-tests/type-inference/main.rs index 2be80169aa4e..583f4349df6f 100644 --- a/rust/ql/test/library-tests/type-inference/main.rs +++ b/rust/ql/test/library-tests/type-inference/main.rs @@ -2334,27 +2334,27 @@ mod tuples { } pub fn f() { - let a = S1::get_pair(); // $ target=get_pair MISSING: type=a:(T_2) - let mut b = S1::get_pair(); // $ target=get_pair MISSING: type=b:(T_2) - let (c, d) = S1::get_pair(); // $ target=get_pair MISSING: type=c:S1 type=d:S1 - let (mut e, f) = S1::get_pair(); // $ target=get_pair MISSING: type=e:S1 type=f:S1 - let (mut g, mut h) = S1::get_pair(); // $ target=get_pair MISSING: type=g:S1 type=h:S1 - - a.0.foo(); // $ MISSING: target=foo - b.1.foo(); // $ MISSING: target=foo - c.foo(); // $ MISSING: target=foo - d.foo(); // $ MISSING: target=foo - e.foo(); // $ MISSING: target=foo - f.foo(); // $ MISSING: target=foo - g.foo(); // $ MISSING: target=foo - h.foo(); // $ MISSING: target=foo + let a = S1::get_pair(); // $ target=get_pair type=a:(T_2) + let mut b = S1::get_pair(); // $ target=get_pair type=b:(T_2) + let (c, d) = S1::get_pair(); // $ target=get_pair type=c:S1 type=d:S1 + let (mut e, f) = S1::get_pair(); // $ target=get_pair type=e:S1 type=f:S1 + let (mut g, mut h) = S1::get_pair(); // $ target=get_pair type=g:S1 type=h:S1 + + a.0.foo(); // $ target=foo + b.1.foo(); // $ target=foo + c.foo(); // $ target=foo + d.foo(); // $ target=foo + e.foo(); // $ target=foo + f.foo(); // $ target=foo + g.foo(); // $ target=foo + h.foo(); // $ target=foo // Here type information must flow from `pair.0` and `pair.1` into // `pair` and from `(a, b)` into `a` and `b` in order for the types of // `a` and `b` to be inferred. - let a = Default::default(); // $ MISSING: target=default type=a:i64 - let b = Default::default(); // $ MISSING: target=default MISSING: type=b:bool - let pair = (a, b); // $ MISSING: type=pair:0.i64 type=pair:1.bool + let a = Default::default(); // $ target=default type=a:i64 + let b = Default::default(); // $ target=default type=b:bool + let pair = (a, b); // $ type=pair:0.i64 type=pair:1.bool let i: i64 = pair.0; let j: bool = pair.1; } diff --git a/rust/ql/test/library-tests/type-inference/pattern_matching.rs b/rust/ql/test/library-tests/type-inference/pattern_matching.rs index 9da38e6ea57d..91774706c46f 100755 --- a/rust/ql/test/library-tests/type-inference/pattern_matching.rs +++ b/rust/ql/test/library-tests/type-inference/pattern_matching.rs @@ -446,13 +446,13 @@ pub fn tuple_patterns() { // TuplePat - Tuple patterns match tuple { (1, 2, 3.0) => { - let exact_tuple = tuple; // $ MISSING: type=exact_tuple:? + let exact_tuple = tuple; // $ type=exact_tuple:(T_3) println!("Exact tuple: {:?}", exact_tuple); } (a, b, c) => { - let first_elem = a; // $ MISSING: type=first_elem:i32 - let second_elem = b; // $ MISSING: type=second_elem:i64 - let third_elem = c; // $ MISSING: type=third_elem:f32 + let first_elem = a; // $ type=first_elem:i32 + let second_elem = b; // $ type=second_elem:i64 + let third_elem = c; // $ type=third_elem:f32 println!("Tuple: ({}, {}, {})", first_elem, second_elem, third_elem); } } @@ -460,7 +460,7 @@ pub fn tuple_patterns() { // With rest pattern match tuple { (first, ..) => { - let tuple_first = first; // $ MISSING: type=tuple_first:i32 + let tuple_first = first; // $ type=tuple_first:i32 println!("First element: {}", tuple_first); } } @@ -469,7 +469,7 @@ pub fn tuple_patterns() { let unit = (); match unit { () => { - let unit_value = unit; // $ MISSING: type=unit_value:? + let unit_value = unit; // $ type=unit_value:() println!("Unit value: {:?}", unit_value); } } @@ -478,7 +478,7 @@ pub fn tuple_patterns() { let single = (42i32,); match single { (x,) => { - let single_elem = x; // $ MISSING: type=single_elem:i32 + let single_elem = x; // $ type=single_elem:i32 println!("Single element tuple: {}", single_elem); } } @@ -499,8 +499,8 @@ pub fn parenthesized_patterns() { let tuple = (1i32, 2i32); match tuple { (x, (y)) => { - let paren_x = x; // $ MISSING: type=paren_x:i32 - let paren_y = y; // $ MISSING: type=paren_y:i32 + let paren_x = x; // $ type=paren_x:i32 + let paren_y = y; // $ type=paren_y:i32 println!("Parenthesized in tuple: {}, {}", paren_x, paren_y); } } @@ -630,7 +630,7 @@ pub fn rest_patterns() { // RestPat - Rest patterns (..) match tuple { (first, ..) => { - let rest_first = first; // $ MISSING: type=rest_first:i32 + let rest_first = first; // $ type=rest_first:i32 println!("First with rest: {}", rest_first); } } @@ -644,7 +644,7 @@ pub fn rest_patterns() { match tuple { (first, .., last) => { - let rest_start = first; // $ MISSING: type=rest_start:i32 + let rest_start = first; // $ type=rest_start:i32 let rest_end = last; // $ MISSING: type=rest_end:u8 println!("First and last: {}, {}", rest_start, rest_end); } @@ -719,9 +719,9 @@ pub fn patterns_in_let_statements() { let tuple = (1i32, 2i64, 3.0f32); let (a, b, c) = tuple; // TuplePat in let - let let_a = a; // $ MISSING: type=let_a:i32 - let let_b = b; // $ MISSING: type=let_b:i64 - let let_c = c; // $ MISSING: type=let_c:f32 + let let_a = a; // $ type=let_a:i32 + let let_b = b; // $ type=let_b:i64 + let let_c = c; // $ type=let_c:f32 let array = [1i32, 2, 3, 4, 5]; let [first, .., last] = array; // SlicePat in let @@ -759,8 +759,8 @@ pub fn patterns_in_function_parameters() { } fn extract_tuple((first, _, third): (i32, f64, bool)) -> (i32, bool) { - let param_first = first; // $ MISSING: type=param_first:i32 - let param_third = third; // $ MISSING: type=param_third:bool + let param_first = first; // $ type=param_first:i32 + let param_third = third; // $ type=param_third:bool (param_first, param_third) } @@ -772,7 +772,7 @@ pub fn patterns_in_function_parameters() { let red = extract_color(color); // $ target=extract_color type=red:u8 let tuple = (42i32, 3.14f64, true); - let tuple_extracted = extract_tuple(tuple); // $ target=extract_tuple MISSING: type=tuple_extracted:? + let tuple_extracted = extract_tuple(tuple); // $ target=extract_tuple type=tuple_extracted:0.i32 type=tuple_extracted:1.bool } #[rustfmt::skip] 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 f19cfbfe8363..6a9776d9d705 100644 --- a/rust/ql/test/library-tests/type-inference/type-inference.expected +++ b/rust/ql/test/library-tests/type-inference/type-inference.expected @@ -3409,9 +3409,11 @@ inferType | main.rs:2066:31:2066:31 | x | | main.rs:2064:5:2067:5 | Self [trait MyFrom2] | | main.rs:2071:21:2071:25 | value | | {EXTERNAL LOCATION} | i64 | | main.rs:2071:33:2071:33 | _ | | {EXTERNAL LOCATION} | i64 | +| main.rs:2071:48:2073:9 | { ... } | | file://:0:0:0:0 | () | | main.rs:2072:13:2072:17 | value | | {EXTERNAL LOCATION} | i64 | | main.rs:2078:21:2078:25 | value | | {EXTERNAL LOCATION} | bool | | main.rs:2078:34:2078:34 | _ | | {EXTERNAL LOCATION} | i64 | +| main.rs:2078:49:2084:9 | { ... } | | file://:0:0:0:0 | () | | main.rs:2079:13:2083:13 | if value {...} else {...} | | {EXTERNAL LOCATION} | i32 | | main.rs:2079:16:2079:20 | value | | {EXTERNAL LOCATION} | bool | | main.rs:2079:22:2081:13 | { ... } | | {EXTERNAL LOCATION} | i32 | @@ -3483,10 +3485,13 @@ inferType | main.rs:2131:13:2131:13 | z | | {EXTERNAL LOCATION} | i64 | | main.rs:2131:22:2131:43 | ...::my_from(...) | | {EXTERNAL LOCATION} | i64 | | main.rs:2131:38:2131:42 | 73i64 | | {EXTERNAL LOCATION} | i64 | +| main.rs:2132:9:2132:34 | ...::my_from2(...) | | file://:0:0:0:0 | () | | main.rs:2132:23:2132:27 | 73i64 | | {EXTERNAL LOCATION} | i64 | | main.rs:2132:30:2132:33 | 0i64 | | {EXTERNAL LOCATION} | i64 | +| main.rs:2133:9:2133:33 | ...::my_from2(...) | | file://:0:0:0:0 | () | | main.rs:2133:23:2133:26 | true | | {EXTERNAL LOCATION} | bool | | main.rs:2133:29:2133:32 | 0i64 | | {EXTERNAL LOCATION} | i64 | +| main.rs:2134:9:2134:38 | ...::my_from2(...) | | file://:0:0:0:0 | () | | main.rs:2134:27:2134:31 | 73i64 | | {EXTERNAL LOCATION} | i64 | | main.rs:2134:34:2134:37 | 0i64 | | {EXTERNAL LOCATION} | i64 | | main.rs:2136:9:2136:22 | ...::f1(...) | | {EXTERNAL LOCATION} | i64 | @@ -3921,6 +3926,21 @@ inferType | main.rs:2253:22:2253:34 | map1.values() | V.T | file://:0:0:0:0 | & | | main.rs:2253:22:2253:34 | map1.values() | V.T.&T | {EXTERNAL LOCATION} | str | | main.rs:2254:13:2254:24 | TuplePat | | {EXTERNAL LOCATION} | Item | +| main.rs:2254:13:2254:24 | TuplePat | | file://:0:0:0:0 | (T_2) | +| main.rs:2254:13:2254:24 | TuplePat | 0 | file://:0:0:0:0 | & | +| main.rs:2254:13:2254:24 | TuplePat | 0.&T | {EXTERNAL LOCATION} | i32 | +| main.rs:2254:13:2254:24 | TuplePat | 1 | file://:0:0:0:0 | & | +| main.rs:2254:13:2254:24 | TuplePat | 1.&T | {EXTERNAL LOCATION} | Box | +| main.rs:2254:13:2254:24 | TuplePat | 1.&T.A | {EXTERNAL LOCATION} | Global | +| main.rs:2254:13:2254:24 | TuplePat | 1.&T.T | file://:0:0:0:0 | & | +| main.rs:2254:13:2254:24 | TuplePat | 1.&T.T.&T | {EXTERNAL LOCATION} | str | +| main.rs:2254:14:2254:16 | key | | file://:0:0:0:0 | & | +| main.rs:2254:14:2254:16 | key | &T | {EXTERNAL LOCATION} | i32 | +| main.rs:2254:19:2254:23 | value | | file://:0:0:0:0 | & | +| main.rs:2254:19:2254:23 | value | &T | {EXTERNAL LOCATION} | Box | +| main.rs:2254:19:2254:23 | value | &T.A | {EXTERNAL LOCATION} | Global | +| main.rs:2254:19:2254:23 | value | &T.T | file://:0:0:0:0 | & | +| main.rs:2254:19:2254:23 | value | &T.T.&T | {EXTERNAL LOCATION} | str | | main.rs:2254:29:2254:32 | map1 | | {EXTERNAL LOCATION} | HashMap | | main.rs:2254:29:2254:32 | map1 | K | {EXTERNAL LOCATION} | i32 | | main.rs:2254:29:2254:32 | map1 | S | {EXTERNAL LOCATION} | RandomState | @@ -3935,6 +3955,21 @@ inferType | main.rs:2254:29:2254:39 | map1.iter() | V.T | file://:0:0:0:0 | & | | main.rs:2254:29:2254:39 | map1.iter() | V.T.&T | {EXTERNAL LOCATION} | str | | main.rs:2255:13:2255:24 | TuplePat | | {EXTERNAL LOCATION} | Item | +| main.rs:2255:13:2255:24 | TuplePat | | file://:0:0:0:0 | (T_2) | +| main.rs:2255:13:2255:24 | TuplePat | 0 | file://:0:0:0:0 | & | +| main.rs:2255:13:2255:24 | TuplePat | 0.&T | {EXTERNAL LOCATION} | i32 | +| main.rs:2255:13:2255:24 | TuplePat | 1 | file://:0:0:0:0 | & | +| main.rs:2255:13:2255:24 | TuplePat | 1.&T | {EXTERNAL LOCATION} | Box | +| main.rs:2255:13:2255:24 | TuplePat | 1.&T.A | {EXTERNAL LOCATION} | Global | +| main.rs:2255:13:2255:24 | TuplePat | 1.&T.T | file://:0:0:0:0 | & | +| main.rs:2255:13:2255:24 | TuplePat | 1.&T.T.&T | {EXTERNAL LOCATION} | str | +| main.rs:2255:14:2255:16 | key | | file://:0:0:0:0 | & | +| main.rs:2255:14:2255:16 | key | &T | {EXTERNAL LOCATION} | i32 | +| main.rs:2255:19:2255:23 | value | | file://:0:0:0:0 | & | +| main.rs:2255:19:2255:23 | value | &T | {EXTERNAL LOCATION} | Box | +| main.rs:2255:19:2255:23 | value | &T.A | {EXTERNAL LOCATION} | Global | +| main.rs:2255:19:2255:23 | value | &T.T | file://:0:0:0:0 | & | +| main.rs:2255:19:2255:23 | value | &T.T.&T | {EXTERNAL LOCATION} | str | | main.rs:2255:29:2255:33 | &map1 | | file://:0:0:0:0 | & | | main.rs:2255:29:2255:33 | &map1 | &T | {EXTERNAL LOCATION} | HashMap | | main.rs:2255:29:2255:33 | &map1 | &T.K | {EXTERNAL LOCATION} | i32 | @@ -4056,12 +4091,86 @@ inferType | main.rs:2322:13:2322:15 | x14 | | {EXTERNAL LOCATION} | i32 | | main.rs:2322:19:2322:48 | foo::<...>(...) | | {EXTERNAL LOCATION} | i32 | | main.rs:2322:30:2322:47 | ...::default(...) | | {EXTERNAL LOCATION} | i32 | +| main.rs:2330:35:2332:9 | { ... } | | file://:0:0:0:0 | (T_2) | +| main.rs:2330:35:2332:9 | { ... } | 0 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2330:35:2332:9 | { ... } | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2331:13:2331:26 | TupleExpr | | file://:0:0:0:0 | (T_2) | +| main.rs:2331:13:2331:26 | TupleExpr | 0 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2331:13:2331:26 | TupleExpr | 1 | main.rs:2327:5:2327:16 | S1 | | main.rs:2331:14:2331:18 | S1 {...} | | main.rs:2327:5:2327:16 | S1 | | main.rs:2331:21:2331:25 | S1 {...} | | main.rs:2327:5:2327:16 | S1 | | main.rs:2333:16:2333:19 | SelfParam | | main.rs:2327:5:2327:16 | S1 | +| main.rs:2337:13:2337:13 | a | | file://:0:0:0:0 | (T_2) | +| main.rs:2337:13:2337:13 | a | 0 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2337:13:2337:13 | a | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2337:17:2337:30 | ...::get_pair(...) | | file://:0:0:0:0 | (T_2) | +| main.rs:2337:17:2337:30 | ...::get_pair(...) | 0 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2337:17:2337:30 | ...::get_pair(...) | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2338:17:2338:17 | b | | file://:0:0:0:0 | (T_2) | +| main.rs:2338:17:2338:17 | b | 0 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2338:17:2338:17 | b | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2338:21:2338:34 | ...::get_pair(...) | | file://:0:0:0:0 | (T_2) | +| main.rs:2338:21:2338:34 | ...::get_pair(...) | 0 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2338:21:2338:34 | ...::get_pair(...) | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2339:13:2339:18 | TuplePat | | file://:0:0:0:0 | (T_2) | +| main.rs:2339:13:2339:18 | TuplePat | 0 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2339:13:2339:18 | TuplePat | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2339:14:2339:14 | c | | main.rs:2327:5:2327:16 | S1 | +| main.rs:2339:17:2339:17 | d | | main.rs:2327:5:2327:16 | S1 | +| main.rs:2339:22:2339:35 | ...::get_pair(...) | | file://:0:0:0:0 | (T_2) | +| main.rs:2339:22:2339:35 | ...::get_pair(...) | 0 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2339:22:2339:35 | ...::get_pair(...) | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2340:13:2340:22 | TuplePat | | file://:0:0:0:0 | (T_2) | +| main.rs:2340:13:2340:22 | TuplePat | 0 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2340:13:2340:22 | TuplePat | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2340:18:2340:18 | e | | main.rs:2327:5:2327:16 | S1 | +| main.rs:2340:21:2340:21 | f | | main.rs:2327:5:2327:16 | S1 | +| main.rs:2340:26:2340:39 | ...::get_pair(...) | | file://:0:0:0:0 | (T_2) | +| main.rs:2340:26:2340:39 | ...::get_pair(...) | 0 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2340:26:2340:39 | ...::get_pair(...) | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2341:13:2341:26 | TuplePat | | file://:0:0:0:0 | (T_2) | +| main.rs:2341:13:2341:26 | TuplePat | 0 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2341:13:2341:26 | TuplePat | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2341:18:2341:18 | g | | main.rs:2327:5:2327:16 | S1 | +| main.rs:2341:25:2341:25 | h | | main.rs:2327:5:2327:16 | S1 | +| main.rs:2341:30:2341:43 | ...::get_pair(...) | | file://:0:0:0:0 | (T_2) | +| main.rs:2341:30:2341:43 | ...::get_pair(...) | 0 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2341:30:2341:43 | ...::get_pair(...) | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2343:9:2343:9 | a | | file://:0:0:0:0 | (T_2) | +| main.rs:2343:9:2343:9 | a | 0 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2343:9:2343:9 | a | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2343:9:2343:11 | a.0 | | main.rs:2327:5:2327:16 | S1 | +| main.rs:2344:9:2344:9 | b | | file://:0:0:0:0 | (T_2) | +| main.rs:2344:9:2344:9 | b | 0 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2344:9:2344:9 | b | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2344:9:2344:11 | b.1 | | main.rs:2327:5:2327:16 | S1 | +| main.rs:2345:9:2345:9 | c | | main.rs:2327:5:2327:16 | S1 | +| main.rs:2346:9:2346:9 | d | | main.rs:2327:5:2327:16 | S1 | +| main.rs:2347:9:2347:9 | e | | main.rs:2327:5:2327:16 | S1 | +| main.rs:2348:9:2348:9 | f | | main.rs:2327:5:2327:16 | S1 | +| main.rs:2349:9:2349:9 | g | | main.rs:2327:5:2327:16 | S1 | +| main.rs:2350:9:2350:9 | h | | main.rs:2327:5:2327:16 | S1 | +| main.rs:2355:13:2355:13 | a | | {EXTERNAL LOCATION} | i64 | +| main.rs:2355:17:2355:34 | ...::default(...) | | {EXTERNAL LOCATION} | i64 | +| main.rs:2356:13:2356:13 | b | | {EXTERNAL LOCATION} | bool | +| main.rs:2356:17:2356:34 | ...::default(...) | | {EXTERNAL LOCATION} | bool | +| main.rs:2357:13:2357:16 | pair | | file://:0:0:0:0 | (T_2) | +| main.rs:2357:13:2357:16 | pair | 0 | {EXTERNAL LOCATION} | i64 | +| main.rs:2357:13:2357:16 | pair | 1 | {EXTERNAL LOCATION} | bool | +| main.rs:2357:20:2357:25 | TupleExpr | | file://:0:0:0:0 | (T_2) | +| main.rs:2357:20:2357:25 | TupleExpr | 0 | {EXTERNAL LOCATION} | i64 | +| main.rs:2357:20:2357:25 | TupleExpr | 1 | {EXTERNAL LOCATION} | bool | +| main.rs:2357:21:2357:21 | a | | {EXTERNAL LOCATION} | i64 | +| main.rs:2357:24:2357:24 | b | | {EXTERNAL LOCATION} | bool | | main.rs:2358:13:2358:13 | i | | {EXTERNAL LOCATION} | i64 | +| main.rs:2358:22:2358:25 | pair | | file://:0:0:0:0 | (T_2) | +| main.rs:2358:22:2358:25 | pair | 0 | {EXTERNAL LOCATION} | i64 | +| main.rs:2358:22:2358:25 | pair | 1 | {EXTERNAL LOCATION} | bool | | main.rs:2358:22:2358:27 | pair.0 | | {EXTERNAL LOCATION} | i64 | | main.rs:2359:13:2359:13 | j | | {EXTERNAL LOCATION} | bool | +| main.rs:2359:23:2359:26 | pair | | file://:0:0:0:0 | (T_2) | +| main.rs:2359:23:2359:26 | pair | 0 | {EXTERNAL LOCATION} | i64 | +| main.rs:2359:23:2359:26 | pair | 1 | {EXTERNAL LOCATION} | bool | | main.rs:2359:23:2359:28 | pair.1 | | {EXTERNAL LOCATION} | bool | | main.rs:2366:13:2366:23 | boxed_value | | {EXTERNAL LOCATION} | Box | | main.rs:2366:13:2366:23 | boxed_value | A | {EXTERNAL LOCATION} | Global | @@ -4154,6 +4263,7 @@ inferType | main.rs:2433:41:2433:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | | main.rs:2449:5:2449:15 | ...::f(...) | | {EXTERNAL LOCATION} | trait Future | | pattern_matching.rs:13:26:133:1 | { ... } | | {EXTERNAL LOCATION} | Option | +| pattern_matching.rs:13:26:133:1 | { ... } | T | file://:0:0:0:0 | () | | pattern_matching.rs:14:9:14:13 | value | | {EXTERNAL LOCATION} | Option | | pattern_matching.rs:14:9:14:13 | value | T | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:14:17:14:24 | Some(...) | | {EXTERNAL LOCATION} | Option | @@ -4171,11 +4281,13 @@ inferType | pattern_matching.rs:17:18:17:25 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:17:18:17:25 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:17:20:17:23 | mesg | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:19:5:25:5 | match value { ... } | | file://:0:0:0:0 | () | | pattern_matching.rs:19:11:19:15 | value | | {EXTERNAL LOCATION} | Option | | pattern_matching.rs:19:11:19:15 | value | T | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:20:9:20:18 | Some(...) | | {EXTERNAL LOCATION} | Option | | pattern_matching.rs:20:9:20:18 | Some(...) | T | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:20:14:20:17 | mesg | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:20:23:23:9 | { ... } | | file://:0:0:0:0 | () | | pattern_matching.rs:21:17:21:20 | mesg | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:21:24:21:27 | mesg | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:22:22:22:29 | "{mesg}\\n" | | file://:0:0:0:0 | & | @@ -4185,6 +4297,7 @@ inferType | pattern_matching.rs:22:24:22:27 | mesg | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:24:9:24:12 | None | | {EXTERNAL LOCATION} | Option | | pattern_matching.rs:24:9:24:12 | None | T | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:24:17:24:18 | TupleExpr | | file://:0:0:0:0 | () | | pattern_matching.rs:26:9:26:12 | mesg | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:26:16:26:20 | value | | {EXTERNAL LOCATION} | Option | | pattern_matching.rs:26:16:26:20 | value | T | {EXTERNAL LOCATION} | i32 | @@ -4293,6 +4406,7 @@ inferType | pattern_matching.rs:58:17:58:22 | value1 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:59:13:59:13 | y | | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:59:17:59:22 | value2 | | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:60:9:60:10 | TupleExpr | | file://:0:0:0:0 | () | | pattern_matching.rs:63:9:63:23 | my_tuple_struct | | pattern_matching.rs:6:1:6:37 | MyTupleStruct | | pattern_matching.rs:63:9:63:23 | my_tuple_struct | T1 | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:63:9:63:23 | my_tuple_struct | T2 | {EXTERNAL LOCATION} | bool | @@ -4313,6 +4427,7 @@ inferType | pattern_matching.rs:65:17:65:22 | value1 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:66:13:66:13 | y | | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:66:17:66:22 | value2 | | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:67:9:67:10 | TupleExpr | | file://:0:0:0:0 | () | | pattern_matching.rs:70:9:70:16 | my_enum1 | | pattern_matching.rs:8:1:11:1 | MyEnum | | pattern_matching.rs:70:9:70:16 | my_enum1 | T1 | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:70:9:70:16 | my_enum1 | T2 | {EXTERNAL LOCATION} | bool | @@ -4333,6 +4448,7 @@ inferType | pattern_matching.rs:76:21:76:26 | value1 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:77:17:77:17 | y | | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:77:21:77:26 | value2 | | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:78:13:78:14 | TupleExpr | | file://:0:0:0:0 | () | | pattern_matching.rs:80:9:80:40 | ...::Variant2(...) | | pattern_matching.rs:8:1:11:1 | MyEnum | | pattern_matching.rs:80:9:80:40 | ...::Variant2(...) | T1 | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:80:9:80:40 | ...::Variant2(...) | T2 | {EXTERNAL LOCATION} | bool | @@ -4342,6 +4458,7 @@ inferType | pattern_matching.rs:81:21:81:26 | value1 | | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:82:17:82:17 | y | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:82:21:82:26 | value2 | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:83:13:83:14 | TupleExpr | | file://:0:0:0:0 | () | | pattern_matching.rs:87:9:87:22 | my_nested_enum | | pattern_matching.rs:8:1:11:1 | MyEnum | | pattern_matching.rs:87:9:87:22 | my_nested_enum | T1 | pattern_matching.rs:1:1:4:1 | MyRecordStruct | | pattern_matching.rs:87:9:87:22 | my_nested_enum | T1.T1 | {EXTERNAL LOCATION} | i32 | @@ -4362,6 +4479,7 @@ inferType | pattern_matching.rs:90:21:90:22 | 42 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:91:21:91:28 | "string" | | file://:0:0:0:0 | & | | pattern_matching.rs:91:21:91:28 | "string" | &T | {EXTERNAL LOCATION} | str | +| pattern_matching.rs:95:5:109:5 | match my_nested_enum { ... } | | file://:0:0:0:0 | () | | pattern_matching.rs:95:11:95:24 | my_nested_enum | | pattern_matching.rs:8:1:11:1 | MyEnum | | pattern_matching.rs:95:11:95:24 | my_nested_enum | T1 | pattern_matching.rs:1:1:4:1 | MyRecordStruct | | pattern_matching.rs:95:11:95:24 | my_nested_enum | T1.T1 | {EXTERNAL LOCATION} | i32 | @@ -4382,6 +4500,7 @@ inferType | pattern_matching.rs:99:25:99:25 | x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:100:25:100:25 | y | | file://:0:0:0:0 | & | | pattern_matching.rs:100:25:100:25 | y | &T | {EXTERNAL LOCATION} | str | +| pattern_matching.rs:102:14:107:9 | { ... } | | file://:0:0:0:0 | () | | pattern_matching.rs:103:17:103:17 | a | | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:103:21:103:26 | value1 | | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:104:17:104:17 | b | | {EXTERNAL LOCATION} | i32 | @@ -4390,12 +4509,14 @@ inferType | pattern_matching.rs:105:17:105:17 | c | &T | {EXTERNAL LOCATION} | str | | pattern_matching.rs:105:21:105:21 | y | | file://:0:0:0:0 | & | | pattern_matching.rs:105:21:105:21 | y | &T | {EXTERNAL LOCATION} | str | +| pattern_matching.rs:106:13:106:14 | TupleExpr | | file://:0:0:0:0 | () | | pattern_matching.rs:108:9:108:9 | _ | | pattern_matching.rs:8:1:11:1 | MyEnum | | pattern_matching.rs:108:9:108:9 | _ | T1 | pattern_matching.rs:1:1:4:1 | MyRecordStruct | | pattern_matching.rs:108:9:108:9 | _ | T1.T1 | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:108:9:108:9 | _ | T1.T2 | file://:0:0:0:0 | & | | pattern_matching.rs:108:9:108:9 | _ | T1.T2.&T | {EXTERNAL LOCATION} | str | | pattern_matching.rs:108:9:108:9 | _ | T2 | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:108:14:108:15 | TupleExpr | | file://:0:0:0:0 | () | | pattern_matching.rs:111:9:111:12 | opt1 | | {EXTERNAL LOCATION} | Option | | pattern_matching.rs:111:9:111:12 | opt1 | T | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:111:16:111:39 | Some(...) | | {EXTERNAL LOCATION} | Option | @@ -4430,6 +4551,7 @@ inferType | pattern_matching.rs:127:45:127:48 | opt3 | T | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:129:9:129:9 | x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:132:5:132:8 | None | | {EXTERNAL LOCATION} | Option | +| pattern_matching.rs:132:5:132:8 | None | T | file://:0:0:0:0 | () | | pattern_matching.rs:169:9:169:13 | value | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:169:17:169:21 | 42i32 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:171:11:171:15 | value | | {EXTERNAL LOCATION} | i32 | @@ -4910,33 +5032,142 @@ inferType | pattern_matching.rs:438:22:438:49 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:438:22:438:49 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:438:37:438:49 | wrapped_value | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:444:9:444:13 | tuple | | file://:0:0:0:0 | (T_3) | +| pattern_matching.rs:444:9:444:13 | tuple | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:444:9:444:13 | tuple | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:444:9:444:13 | tuple | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:444:9:444:13 | tuple | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:444:9:444:13 | tuple | 2 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:444:17:444:36 | TupleExpr | | file://:0:0:0:0 | (T_3) | +| pattern_matching.rs:444:17:444:36 | TupleExpr | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:444:17:444:36 | TupleExpr | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:444:17:444:36 | TupleExpr | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:444:17:444:36 | TupleExpr | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:444:17:444:36 | TupleExpr | 2 | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:444:18:444:21 | 1i32 | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:444:24:444:27 | 2i64 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:444:24:444:27 | 2i64 | | {EXTERNAL LOCATION} | i64 | | pattern_matching.rs:444:30:444:35 | 3.0f32 | | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:444:30:444:35 | 3.0f32 | | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:447:11:447:15 | tuple | | file://:0:0:0:0 | (T_3) | +| pattern_matching.rs:447:11:447:15 | tuple | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:447:11:447:15 | tuple | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:447:11:447:15 | tuple | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:447:11:447:15 | tuple | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:447:11:447:15 | tuple | 2 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:448:9:448:19 | TuplePat | | file://:0:0:0:0 | (T_3) | +| pattern_matching.rs:448:9:448:19 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:448:9:448:19 | TuplePat | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:448:9:448:19 | TuplePat | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:448:9:448:19 | TuplePat | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:448:9:448:19 | TuplePat | 2 | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:448:10:448:10 | 1 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:448:13:448:13 | 2 | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:448:13:448:13 | 2 | | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:448:16:448:18 | 3.0 | | {EXTERNAL LOCATION} | f32 | | pattern_matching.rs:448:16:448:18 | 3.0 | | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:449:17:449:27 | exact_tuple | | file://:0:0:0:0 | (T_3) | +| pattern_matching.rs:449:17:449:27 | exact_tuple | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:449:17:449:27 | exact_tuple | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:449:17:449:27 | exact_tuple | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:449:17:449:27 | exact_tuple | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:449:17:449:27 | exact_tuple | 2 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:449:31:449:35 | tuple | | file://:0:0:0:0 | (T_3) | +| pattern_matching.rs:449:31:449:35 | tuple | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:449:31:449:35 | tuple | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:449:31:449:35 | tuple | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:449:31:449:35 | tuple | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:449:31:449:35 | tuple | 2 | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:450:22:450:40 | "Exact tuple: {:?}\\n" | | file://:0:0:0:0 | & | | pattern_matching.rs:450:22:450:40 | "Exact tuple: {:?}\\n" | &T | {EXTERNAL LOCATION} | str | | pattern_matching.rs:450:22:450:53 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:450:22:450:53 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| pattern_matching.rs:450:43:450:53 | exact_tuple | | file://:0:0:0:0 | (T_3) | +| pattern_matching.rs:450:43:450:53 | exact_tuple | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:450:43:450:53 | exact_tuple | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:450:43:450:53 | exact_tuple | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:450:43:450:53 | exact_tuple | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:450:43:450:53 | exact_tuple | 2 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:452:9:452:17 | TuplePat | | file://:0:0:0:0 | (T_3) | +| pattern_matching.rs:452:9:452:17 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:452:9:452:17 | TuplePat | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:452:9:452:17 | TuplePat | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:452:9:452:17 | TuplePat | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:452:9:452:17 | TuplePat | 2 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:452:10:452:10 | a | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:452:13:452:13 | b | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:452:13:452:13 | b | | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:452:16:452:16 | c | | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:452:16:452:16 | c | | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:453:17:453:26 | first_elem | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:453:30:453:30 | a | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:454:17:454:27 | second_elem | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:454:17:454:27 | second_elem | | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:454:31:454:31 | b | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:454:31:454:31 | b | | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:455:17:455:26 | third_elem | | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:455:17:455:26 | third_elem | | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:455:30:455:30 | c | | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:455:30:455:30 | c | | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:456:22:456:42 | "Tuple: ({}, {}, {})\\n" | | file://:0:0:0:0 | & | | pattern_matching.rs:456:22:456:42 | "Tuple: ({}, {}, {})\\n" | &T | {EXTERNAL LOCATION} | str | | pattern_matching.rs:456:22:456:79 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:456:22:456:79 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| pattern_matching.rs:456:45:456:54 | first_elem | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:456:57:456:67 | second_elem | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:456:57:456:67 | second_elem | | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:456:70:456:79 | third_elem | | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:456:70:456:79 | third_elem | | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:461:11:461:15 | tuple | | file://:0:0:0:0 | (T_3) | +| pattern_matching.rs:461:11:461:15 | tuple | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:461:11:461:15 | tuple | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:461:11:461:15 | tuple | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:461:11:461:15 | tuple | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:461:11:461:15 | tuple | 2 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:462:9:462:19 | TuplePat | | file://:0:0:0:0 | (T_3) | +| pattern_matching.rs:462:9:462:19 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:462:9:462:19 | TuplePat | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:462:9:462:19 | TuplePat | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:462:9:462:19 | TuplePat | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:462:9:462:19 | TuplePat | 2 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:462:10:462:14 | first | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:462:17:462:18 | .. | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:462:17:462:18 | .. | | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:463:17:463:27 | tuple_first | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:463:31:463:35 | first | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:464:22:464:40 | "First element: {}\\n" | | file://:0:0:0:0 | & | | pattern_matching.rs:464:22:464:40 | "First element: {}\\n" | &T | {EXTERNAL LOCATION} | str | | pattern_matching.rs:464:22:464:53 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:464:22:464:53 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| pattern_matching.rs:464:43:464:53 | tuple_first | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:469:9:469:12 | unit | | file://:0:0:0:0 | () | +| pattern_matching.rs:469:16:469:17 | TupleExpr | | file://:0:0:0:0 | () | +| pattern_matching.rs:470:11:470:14 | unit | | file://:0:0:0:0 | () | +| pattern_matching.rs:471:9:471:10 | TuplePat | | file://:0:0:0:0 | () | +| pattern_matching.rs:472:17:472:26 | unit_value | | file://:0:0:0:0 | () | +| pattern_matching.rs:472:30:472:33 | unit | | file://:0:0:0:0 | () | | pattern_matching.rs:473:22:473:39 | "Unit value: {:?}\\n" | | file://:0:0:0:0 | & | | pattern_matching.rs:473:22:473:39 | "Unit value: {:?}\\n" | &T | {EXTERNAL LOCATION} | str | | pattern_matching.rs:473:22:473:51 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:473:22:473:51 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| pattern_matching.rs:473:42:473:51 | unit_value | | file://:0:0:0:0 | () | +| pattern_matching.rs:478:9:478:14 | single | | file://:0:0:0:0 | (T_1) | +| pattern_matching.rs:478:9:478:14 | single | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:478:18:478:25 | TupleExpr | | file://:0:0:0:0 | (T_1) | +| pattern_matching.rs:478:18:478:25 | TupleExpr | 0 | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:478:19:478:23 | 42i32 | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:479:11:479:16 | single | | file://:0:0:0:0 | (T_1) | +| pattern_matching.rs:479:11:479:16 | single | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:480:9:480:12 | TuplePat | | file://:0:0:0:0 | (T_1) | +| pattern_matching.rs:480:9:480:12 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:480:10:480:10 | x | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:481:17:481:27 | single_elem | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:481:31:481:31 | x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:482:22:482:47 | "Single element tuple: {}\\n" | | file://:0:0:0:0 | & | | pattern_matching.rs:482:22:482:47 | "Single element tuple: {}\\n" | &T | {EXTERNAL LOCATION} | str | | pattern_matching.rs:482:22:482:60 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:482:22:482:60 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| pattern_matching.rs:482:50:482:60 | single_elem | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:488:9:488:13 | value | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:488:17:488:21 | 42i32 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:491:11:491:15 | value | | {EXTERNAL LOCATION} | i32 | @@ -4949,12 +5180,33 @@ inferType | pattern_matching.rs:494:22:494:61 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:494:22:494:61 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:494:51:494:61 | paren_bound | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:499:9:499:13 | tuple | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:499:9:499:13 | tuple | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:499:9:499:13 | tuple | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:499:17:499:28 | TupleExpr | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:499:17:499:28 | TupleExpr | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:499:17:499:28 | TupleExpr | 1 | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:499:18:499:21 | 1i32 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:499:24:499:27 | 2i32 | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:500:11:500:15 | tuple | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:500:11:500:15 | tuple | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:500:11:500:15 | tuple | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:501:9:501:16 | TuplePat | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:501:9:501:16 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:501:9:501:16 | TuplePat | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:501:10:501:10 | x | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:501:13:501:15 | (...) | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:501:14:501:14 | y | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:502:17:502:23 | paren_x | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:502:27:502:27 | x | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:503:17:503:23 | paren_y | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:503:27:503:27 | y | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:504:22:504:53 | "Parenthesized in tuple: {}, {... | | file://:0:0:0:0 | & | | pattern_matching.rs:504:22:504:53 | "Parenthesized in tuple: {}, {... | &T | {EXTERNAL LOCATION} | str | | pattern_matching.rs:504:22:504:71 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:504:22:504:71 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| pattern_matching.rs:504:56:504:62 | paren_x | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:504:65:504:71 | paren_y | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:510:9:510:13 | slice | | file://:0:0:0:0 | & | | pattern_matching.rs:510:9:510:13 | slice | &T | file://:0:0:0:0 | [] | | pattern_matching.rs:510:9:510:13 | slice | &T | file://:0:0:0:0 | [] | @@ -5173,22 +5425,81 @@ inferType | pattern_matching.rs:621:22:621:51 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:621:38:621:51 | range_or_value | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:623:9:623:9 | _ | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:628:9:628:13 | tuple | | file://:0:0:0:0 | (T_4) | +| pattern_matching.rs:628:9:628:13 | tuple | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:628:9:628:13 | tuple | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:628:9:628:13 | tuple | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:628:9:628:13 | tuple | 3 | {EXTERNAL LOCATION} | u8 | +| pattern_matching.rs:628:17:628:41 | TupleExpr | | file://:0:0:0:0 | (T_4) | +| pattern_matching.rs:628:17:628:41 | TupleExpr | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:628:17:628:41 | TupleExpr | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:628:17:628:41 | TupleExpr | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:628:17:628:41 | TupleExpr | 3 | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:628:18:628:21 | 1i32 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:628:24:628:27 | 2i64 | | {EXTERNAL LOCATION} | i64 | | pattern_matching.rs:628:30:628:35 | 3.0f32 | | {EXTERNAL LOCATION} | f32 | | pattern_matching.rs:628:38:628:40 | 4u8 | | {EXTERNAL LOCATION} | u8 | +| pattern_matching.rs:631:11:631:15 | tuple | | file://:0:0:0:0 | (T_4) | +| pattern_matching.rs:631:11:631:15 | tuple | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:631:11:631:15 | tuple | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:631:11:631:15 | tuple | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:631:11:631:15 | tuple | 3 | {EXTERNAL LOCATION} | u8 | +| pattern_matching.rs:632:9:632:19 | TuplePat | | file://:0:0:0:0 | (T_4) | +| pattern_matching.rs:632:9:632:19 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:632:9:632:19 | TuplePat | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:632:9:632:19 | TuplePat | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:632:9:632:19 | TuplePat | 3 | {EXTERNAL LOCATION} | u8 | +| pattern_matching.rs:632:10:632:14 | first | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:632:17:632:18 | .. | | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:633:17:633:26 | rest_first | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:633:30:633:34 | first | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:634:22:634:42 | "First with rest: {}\\n" | | file://:0:0:0:0 | & | | pattern_matching.rs:634:22:634:42 | "First with rest: {}\\n" | &T | {EXTERNAL LOCATION} | str | | pattern_matching.rs:634:22:634:54 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:634:22:634:54 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| pattern_matching.rs:634:45:634:54 | rest_first | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:638:11:638:15 | tuple | | file://:0:0:0:0 | (T_4) | +| pattern_matching.rs:638:11:638:15 | tuple | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:638:11:638:15 | tuple | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:638:11:638:15 | tuple | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:638:11:638:15 | tuple | 3 | {EXTERNAL LOCATION} | u8 | +| pattern_matching.rs:639:9:639:18 | TuplePat | | file://:0:0:0:0 | (T_4) | +| pattern_matching.rs:639:9:639:18 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:639:9:639:18 | TuplePat | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:639:9:639:18 | TuplePat | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:639:9:639:18 | TuplePat | 3 | {EXTERNAL LOCATION} | u8 | +| pattern_matching.rs:639:10:639:11 | .. | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:639:14:639:17 | last | | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:640:17:640:25 | rest_last | | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:640:29:640:32 | last | | {EXTERNAL LOCATION} | i64 | | pattern_matching.rs:641:22:641:41 | "Last with rest: {}\\n" | | file://:0:0:0:0 | & | | pattern_matching.rs:641:22:641:41 | "Last with rest: {}\\n" | &T | {EXTERNAL LOCATION} | str | | pattern_matching.rs:641:22:641:52 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:641:22:641:52 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| pattern_matching.rs:641:44:641:52 | rest_last | | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:645:11:645:15 | tuple | | file://:0:0:0:0 | (T_4) | +| pattern_matching.rs:645:11:645:15 | tuple | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:645:11:645:15 | tuple | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:645:11:645:15 | tuple | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:645:11:645:15 | tuple | 3 | {EXTERNAL LOCATION} | u8 | +| pattern_matching.rs:646:9:646:25 | TuplePat | | file://:0:0:0:0 | (T_4) | +| pattern_matching.rs:646:9:646:25 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:646:9:646:25 | TuplePat | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:646:9:646:25 | TuplePat | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:646:9:646:25 | TuplePat | 3 | {EXTERNAL LOCATION} | u8 | +| pattern_matching.rs:646:10:646:14 | first | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:646:17:646:18 | .. | | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:646:21:646:24 | last | | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:647:17:647:26 | rest_start | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:647:30:647:34 | first | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:648:17:648:24 | rest_end | | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:648:28:648:31 | last | | {EXTERNAL LOCATION} | f32 | | pattern_matching.rs:649:22:649:45 | "First and last: {}, {}\\n" | | file://:0:0:0:0 | & | | pattern_matching.rs:649:22:649:45 | "First and last: {}, {}\\n" | &T | {EXTERNAL LOCATION} | str | | pattern_matching.rs:649:22:649:67 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:649:22:649:67 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| pattern_matching.rs:649:48:649:57 | rest_start | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:649:60:649:67 | rest_end | | {EXTERNAL LOCATION} | f32 | | pattern_matching.rs:654:9:654:13 | point | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:654:17:654:38 | Point {...} | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:654:28:654:29 | 10 | | {EXTERNAL LOCATION} | i32 | @@ -5211,6 +5522,14 @@ inferType | pattern_matching.rs:682:21:682:25 | 10i32 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:682:21:682:25 | 10i32 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:682:28:682:28 | x | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:687:9:687:20 | complex_data | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:687:9:687:20 | complex_data | 0 | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:687:9:687:20 | complex_data | 1 | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:687:9:687:20 | complex_data | 1.T | pattern_matching.rs:142:1:143:25 | Color | +| pattern_matching.rs:687:24:687:79 | TupleExpr | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:687:24:687:79 | TupleExpr | 0 | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:687:24:687:79 | TupleExpr | 1 | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:687:24:687:79 | TupleExpr | 1.T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:687:25:687:44 | Point {...} | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:687:36:687:36 | 1 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:687:42:687:42 | 2 | | {EXTERNAL LOCATION} | i32 | @@ -5223,6 +5542,14 @@ inferType | pattern_matching.rs:687:73:687:73 | 0 | | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:687:76:687:76 | 0 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:687:76:687:76 | 0 | | {EXTERNAL LOCATION} | u8 | +| pattern_matching.rs:689:11:689:22 | complex_data | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:689:11:689:22 | complex_data | 0 | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:689:11:689:22 | complex_data | 1 | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:689:11:689:22 | complex_data | 1.T | pattern_matching.rs:142:1:143:25 | Color | +| pattern_matching.rs:691:9:691:61 | TuplePat | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:691:9:691:61 | TuplePat | 0 | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:691:9:691:61 | TuplePat | 1 | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:691:9:691:61 | TuplePat | 1.T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:691:10:691:26 | Point {...} | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:691:21:691:21 | 1 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:691:24:691:24 | y | | {EXTERNAL LOCATION} | i32 | @@ -5246,11 +5573,27 @@ inferType | pattern_matching.rs:697:17:697:24 | nested_y | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:697:27:697:34 | nested_g | | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:697:37:697:44 | nested_b | | {EXTERNAL LOCATION} | u8 | +| pattern_matching.rs:701:9:701:41 | TuplePat | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:701:9:701:41 | TuplePat | 0 | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:701:9:701:41 | TuplePat | 1 | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:701:9:701:41 | TuplePat | 1.T | pattern_matching.rs:142:1:143:25 | Color | +| pattern_matching.rs:701:9:701:71 | ... \| ... | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:701:9:701:71 | ... \| ... | 0 | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:701:9:701:71 | ... \| ... | 1 | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:701:9:701:71 | ... \| ... | 1.T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:701:10:701:24 | Point {...} | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:701:18:701:18 | x | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:701:27:701:40 | ...::None | | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:701:27:701:40 | ...::None | T | pattern_matching.rs:142:1:143:25 | Color | +| pattern_matching.rs:701:45:701:71 | TuplePat | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:701:45:701:71 | TuplePat | 0 | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:701:45:701:71 | TuplePat | 1 | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:701:45:701:71 | TuplePat | 1.T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:701:46:701:67 | Point {...} | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:701:57:701:57 | x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:701:61:701:61 | 0 | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:701:70:701:70 | _ | | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:701:70:701:70 | _ | T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:702:17:702:29 | alt_complex_x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:702:33:702:33 | x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:703:22:703:50 | "Alternative complex: x={:?}\\n... | | file://:0:0:0:0 | & | @@ -5258,10 +5601,26 @@ inferType | pattern_matching.rs:703:22:703:65 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:703:22:703:65 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:703:53:703:65 | alt_complex_x | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:706:9:706:13 | other | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:706:9:706:13 | other | 0 | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:706:9:706:13 | other | 1 | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:706:9:706:13 | other | 1.T | pattern_matching.rs:142:1:143:25 | Color | +| pattern_matching.rs:707:17:707:29 | other_complex | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:707:17:707:29 | other_complex | 0 | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:707:17:707:29 | other_complex | 1 | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:707:17:707:29 | other_complex | 1.T | pattern_matching.rs:142:1:143:25 | Color | +| pattern_matching.rs:707:33:707:37 | other | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:707:33:707:37 | other | 0 | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:707:33:707:37 | other | 1 | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:707:33:707:37 | other | 1.T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:708:22:708:47 | "Other complex data: {:?}\\n" | | file://:0:0:0:0 | & | | pattern_matching.rs:708:22:708:47 | "Other complex data: {:?}\\n" | &T | {EXTERNAL LOCATION} | str | | pattern_matching.rs:708:22:708:62 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:708:22:708:62 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| pattern_matching.rs:708:50:708:62 | other_complex | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:708:50:708:62 | other_complex | 0 | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:708:50:708:62 | other_complex | 1 | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:708:50:708:62 | other_complex | 1.T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:715:9:715:13 | point | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:715:17:715:38 | Point {...} | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:715:28:715:29 | 10 | | {EXTERNAL LOCATION} | i32 | @@ -5274,9 +5633,34 @@ inferType | pattern_matching.rs:717:17:717:17 | x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:718:9:718:13 | let_y | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:718:17:718:17 | y | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:720:9:720:13 | tuple | | file://:0:0:0:0 | (T_3) | +| pattern_matching.rs:720:9:720:13 | tuple | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:720:9:720:13 | tuple | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:720:9:720:13 | tuple | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:720:17:720:36 | TupleExpr | | file://:0:0:0:0 | (T_3) | +| pattern_matching.rs:720:17:720:36 | TupleExpr | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:720:17:720:36 | TupleExpr | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:720:17:720:36 | TupleExpr | 2 | {EXTERNAL LOCATION} | f32 | | pattern_matching.rs:720:18:720:21 | 1i32 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:720:24:720:27 | 2i64 | | {EXTERNAL LOCATION} | i64 | | pattern_matching.rs:720:30:720:35 | 3.0f32 | | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:721:9:721:17 | TuplePat | | file://:0:0:0:0 | (T_3) | +| pattern_matching.rs:721:9:721:17 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:721:9:721:17 | TuplePat | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:721:9:721:17 | TuplePat | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:721:10:721:10 | a | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:721:13:721:13 | b | | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:721:16:721:16 | c | | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:721:21:721:25 | tuple | | file://:0:0:0:0 | (T_3) | +| pattern_matching.rs:721:21:721:25 | tuple | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:721:21:721:25 | tuple | 1 | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:721:21:721:25 | tuple | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:722:9:722:13 | let_a | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:722:17:722:17 | a | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:723:9:723:13 | let_b | | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:723:17:723:17 | b | | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:724:9:724:13 | let_c | | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:724:17:724:17 | c | | {EXTERNAL LOCATION} | f32 | | pattern_matching.rs:726:9:726:13 | array | | file://:0:0:0:0 | [] | | pattern_matching.rs:726:9:726:13 | array | [T;...] | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:726:17:726:34 | [...] | | file://:0:0:0:0 | [] | @@ -5325,10 +5709,16 @@ inferType | pattern_matching.rs:750:22:750:35 | Point {...} | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:750:30:750:30 | x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:750:33:750:33 | y | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:750:59:754:5 | { ... } | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:750:59:754:5 | { ... } | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:750:59:754:5 | { ... } | 1 | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:751:13:751:19 | param_x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:751:23:751:23 | x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:752:13:752:19 | param_y | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:752:23:752:23 | y | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:753:9:753:26 | TupleExpr | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:753:9:753:26 | TupleExpr | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:753:9:753:26 | TupleExpr | 1 | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:753:10:753:16 | param_x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:753:19:753:25 | param_y | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:756:22:756:35 | Color(...) | | pattern_matching.rs:142:1:143:25 | Color | @@ -5339,10 +5729,35 @@ inferType | pattern_matching.rs:757:13:757:19 | param_r | | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:757:23:757:23 | r | | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:758:9:758:15 | param_r | | {EXTERNAL LOCATION} | u8 | +| pattern_matching.rs:761:22:761:38 | TuplePat | | file://:0:0:0:0 | (T_3) | +| pattern_matching.rs:761:22:761:38 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:761:22:761:38 | TuplePat | 1 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:761:22:761:38 | TuplePat | 2 | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:761:23:761:27 | first | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:761:30:761:30 | _ | | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:761:33:761:37 | third | | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:761:74:765:5 | { ... } | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:761:74:765:5 | { ... } | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:761:74:765:5 | { ... } | 1 | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:762:13:762:23 | param_first | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:762:27:762:31 | first | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:763:13:763:23 | param_third | | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:763:27:763:31 | third | | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:764:9:764:34 | TupleExpr | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:764:9:764:34 | TupleExpr | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:764:9:764:34 | TupleExpr | 1 | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:764:10:764:20 | param_first | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:764:23:764:33 | param_third | | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:768:9:768:13 | point | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:768:17:768:37 | Point {...} | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:768:28:768:28 | 5 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:768:34:768:35 | 10 | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:769:9:769:17 | extracted | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:769:9:769:17 | extracted | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:769:9:769:17 | extracted | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:769:21:769:40 | extract_point(...) | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:769:21:769:40 | extract_point(...) | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:769:21:769:40 | extract_point(...) | 1 | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:769:35:769:39 | point | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:771:9:771:13 | color | | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:771:17:771:35 | Color(...) | | pattern_matching.rs:142:1:143:25 | Color | @@ -5355,9 +5770,27 @@ inferType | pattern_matching.rs:772:9:772:11 | red | | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:772:15:772:34 | extract_color(...) | | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:772:29:772:33 | color | | pattern_matching.rs:142:1:143:25 | Color | +| pattern_matching.rs:774:9:774:13 | tuple | | file://:0:0:0:0 | (T_3) | +| pattern_matching.rs:774:9:774:13 | tuple | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:774:9:774:13 | tuple | 1 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:774:9:774:13 | tuple | 2 | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:774:17:774:38 | TupleExpr | | file://:0:0:0:0 | (T_3) | +| pattern_matching.rs:774:17:774:38 | TupleExpr | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:774:17:774:38 | TupleExpr | 1 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:774:17:774:38 | TupleExpr | 2 | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:774:18:774:22 | 42i32 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:774:25:774:31 | 3.14f64 | | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:774:34:774:37 | true | | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:775:9:775:23 | tuple_extracted | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:775:9:775:23 | tuple_extracted | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:775:9:775:23 | tuple_extracted | 1 | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:775:27:775:46 | extract_tuple(...) | | file://:0:0:0:0 | (T_2) | +| pattern_matching.rs:775:27:775:46 | extract_tuple(...) | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:775:27:775:46 | extract_tuple(...) | 1 | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:775:41:775:45 | tuple | | file://:0:0:0:0 | (T_3) | +| pattern_matching.rs:775:41:775:45 | tuple | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:775:41:775:45 | tuple | 1 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:775:41:775:45 | tuple | 2 | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:781:23:781:42 | (...) | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:781:23:781:42 | Point {...} | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:781:34:781:34 | 1 | | {EXTERNAL LOCATION} | i32 | @@ -5437,4 +5870,5 @@ inferType | pattern_matching.rs:807:38:807:44 | guard_x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:809:9:809:9 | _ | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:814:5:814:7 | f(...) | | {EXTERNAL LOCATION} | Option | +| pattern_matching.rs:814:5:814:7 | f(...) | T | file://:0:0:0:0 | () | testFailures From 7c04c9f969ccfc85d03e938d2d44bd436a4d7b90 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Tue, 15 Jul 2025 09:50:15 +0200 Subject: [PATCH 3/8] Rust: Store arity in tuple type parameters Type parameters are required to belong to a single type only. Since we store the arity for tuple types, we need to store the arity in tuple type parameters as well such that we can associate them to the tuple type of the same arity. --- rust/ql/lib/codeql/rust/internal/Type.qll | 19 +- .../codeql/rust/internal/TypeInference.qll | 25 +- .../lib/codeql/rust/internal/TypeMention.qll | 2 +- .../test/library-tests/type-inference/main.rs | 2 +- .../type-inference/pattern_matching.rs | 8 +- .../type-inference/type-inference.expected | 459 +++++++++--------- 6 files changed, 253 insertions(+), 262 deletions(-) diff --git a/rust/ql/lib/codeql/rust/internal/Type.qll b/rust/ql/lib/codeql/rust/internal/Type.qll index ca49f3c258df..f9db78035348 100644 --- a/rust/ql/lib/codeql/rust/internal/Type.qll +++ b/rust/ql/lib/codeql/rust/internal/Type.qll @@ -10,7 +10,8 @@ private import codeql.rust.elements.internal.generated.Synth cached newtype TType = TTuple(int arity) { - exists(any(TupleTypeRepr t).getField(arity)) and Stages::TypeInferenceStage::ref() + arity = any(TupleTypeRepr t).getNumberOfFields() and + Stages::TypeInferenceStage::ref() } or TStruct(Struct s) or TEnum(Enum e) or @@ -19,7 +20,7 @@ newtype TType = TRefType() or // todo: add mut? TImplTraitType(ImplTraitTypeRepr impl) or TSliceType() or - TTupleTypeParameter(int i) { exists(TTuple(i)) } or + TTupleTypeParameter(int arity, int i) { exists(TTuple(arity)) and i in [0 .. arity - 1] } or TTypeParamTypeParameter(TypeParam t) or TAssociatedTypeTypeParameter(TypeAlias t) { any(TraitItemNode trait).getAnAssocItem() = t } or TArrayTypeParameter() or @@ -83,7 +84,7 @@ class TupleType extends Type, TTuple { override TupleField getTupleField(int i) { none() } - override TypeParameter getTypeParameter(int i) { result = TTupleTypeParameter(i) and i < arity } + override TypeParameter getTypeParameter(int i) { result = TTupleTypeParameter(arity, i) } int getArity() { result = arity } @@ -358,12 +359,20 @@ class AssociatedTypeTypeParameter extends TypeParameter, TAssociatedTypeTypePara * their positional index. */ class TupleTypeParameter extends TypeParameter, TTupleTypeParameter { - override string toString() { result = this.getIndex().toString() } + private int arity; + private int index; + + TupleTypeParameter() { this = TTupleTypeParameter(arity, index) } + + override string toString() { result = index.toString() + "(" + arity + ")" } override Location getLocation() { result instanceof EmptyLocation } /** Gets the index of this tuple type parameter. */ - int getIndex() { this = TTupleTypeParameter(result) } + int getIndex() { result = index } + + /** Gets the arity of this tuple type parameter. */ + int getArity() { result = arity } } /** An implicit array type parameter. */ diff --git a/rust/ql/lib/codeql/rust/internal/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/TypeInference.qll index 1d2e7ee02de8..8f2a2ca2ae1c 100644 --- a/rust/ql/lib/codeql/rust/internal/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/TypeInference.qll @@ -104,8 +104,12 @@ private module Input1 implements InputSig1 { node = tp0.(ImplTraitTypeTypeParameter).getImplTraitTypeRepr() ) or - kind = 2 and - id = tp0.(TupleTypeParameter).getIndex() + exists(TupleTypeParameter ttp, int maxArity | + maxArity = max(int i | i = any(TupleType tt).getArity()) and + tp0 = ttp and + kind = 2 and + id = ttp.getArity() * maxArity + ttp.getIndex() + ) | tp0 order by kind, id ) @@ -324,11 +328,14 @@ private predicate typeEquality(AstNode n1, TypePath prefix1, AstNode n2, TypePat prefix1.isEmpty() and prefix2 = TypePath::singleton(TRefTypeParameter()) or - exists(int i | + exists(int i, int arity | prefix1.isEmpty() and - prefix2 = TypePath::singleton(TTupleTypeParameter(i)) + prefix2 = TypePath::singleton(TTupleTypeParameter(arity, i)) | - n1 = n2.(TupleExpr).getField(i) or + arity = n2.(TupleExpr).getNumberOfFields() and + n1 = n2.(TupleExpr).getField(i) + or + arity = n2.(TuplePat).getNumberOfFields() and n1 = n2.(TuplePat).getField(i) ) or @@ -1077,7 +1084,7 @@ private Type inferTupleIndexExprType(FieldExpr fe, TypePath path) { exists(int i, TypePath path0 | fe.getIdentifier().getText() = i.toString() and result = inferType(fe.getContainer(), path0) and - path0.isCons(TTupleTypeParameter(i), path) and + path0.isCons(TTupleTypeParameter(_, i), path) and fe.getIdentifier().getText() = i.toString() ) } @@ -1088,12 +1095,12 @@ private Type inferTupleContainerExprType(Expr e, TypePath path) { // a tuple struct or a tuple. It is only correct to let type information flow // from `t.n` to tuple type parameters of `t` in the latter case. Hence we // include the condition that the root type of `t` must be a tuple type. - exists(int i, TypePath path0, FieldExpr fe | + exists(int i, TypePath path0, FieldExpr fe, int arity | e = fe.getContainer() and fe.getIdentifier().getText() = i.toString() and - inferType(fe.getContainer()) instanceof TupleType and + arity = inferType(fe.getContainer()).(TupleType).getArity() and result = inferType(fe, path0) and - path = TypePath::cons(TTupleTypeParameter(i), path0) + path = TypePath::cons(TTupleTypeParameter(arity, i), path0) // FIXME: ) } diff --git a/rust/ql/lib/codeql/rust/internal/TypeMention.qll b/rust/ql/lib/codeql/rust/internal/TypeMention.qll index a40c068b4894..a70d25e9a908 100644 --- a/rust/ql/lib/codeql/rust/internal/TypeMention.qll +++ b/rust/ql/lib/codeql/rust/internal/TypeMention.qll @@ -21,7 +21,7 @@ class TupleTypeReprMention extends TypeMention instanceof TupleTypeRepr { or exists(TypePath suffix, int i | result = super.getField(i).(TypeMention).resolveTypeAt(suffix) and - path = TypePath::cons(TTupleTypeParameter(i), suffix) + path = TypePath::cons(TTupleTypeParameter(super.getNumberOfFields(), i), suffix) ) } } diff --git a/rust/ql/test/library-tests/type-inference/main.rs b/rust/ql/test/library-tests/type-inference/main.rs index 583f4349df6f..03efbfc9b4ff 100644 --- a/rust/ql/test/library-tests/type-inference/main.rs +++ b/rust/ql/test/library-tests/type-inference/main.rs @@ -2354,7 +2354,7 @@ mod tuples { // `a` and `b` to be inferred. let a = Default::default(); // $ target=default type=a:i64 let b = Default::default(); // $ target=default type=b:bool - let pair = (a, b); // $ type=pair:0.i64 type=pair:1.bool + let pair = (a, b); // $ type=pair:0(2).i64 type=pair:1(2).bool let i: i64 = pair.0; let j: bool = pair.1; } diff --git a/rust/ql/test/library-tests/type-inference/pattern_matching.rs b/rust/ql/test/library-tests/type-inference/pattern_matching.rs index 91774706c46f..396428eedc0f 100755 --- a/rust/ql/test/library-tests/type-inference/pattern_matching.rs +++ b/rust/ql/test/library-tests/type-inference/pattern_matching.rs @@ -460,7 +460,7 @@ pub fn tuple_patterns() { // With rest pattern match tuple { (first, ..) => { - let tuple_first = first; // $ type=tuple_first:i32 + let tuple_first = first; // $ MISSING: type=tuple_first:i32 println!("First element: {}", tuple_first); } } @@ -630,7 +630,7 @@ pub fn rest_patterns() { // RestPat - Rest patterns (..) match tuple { (first, ..) => { - let rest_first = first; // $ type=rest_first:i32 + let rest_first = first; // $ MISSING: type=rest_first:i32 println!("First with rest: {}", rest_first); } } @@ -644,7 +644,7 @@ pub fn rest_patterns() { match tuple { (first, .., last) => { - let rest_start = first; // $ type=rest_start:i32 + let rest_start = first; // $ MISSING: type=rest_start:i32 let rest_end = last; // $ MISSING: type=rest_end:u8 println!("First and last: {}, {}", rest_start, rest_end); } @@ -772,7 +772,7 @@ pub fn patterns_in_function_parameters() { let red = extract_color(color); // $ target=extract_color type=red:u8 let tuple = (42i32, 3.14f64, true); - let tuple_extracted = extract_tuple(tuple); // $ target=extract_tuple type=tuple_extracted:0.i32 type=tuple_extracted:1.bool + let tuple_extracted = extract_tuple(tuple); // $ target=extract_tuple type=tuple_extracted:0(2).i32 type=tuple_extracted:1(2).bool } #[rustfmt::skip] 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 6a9776d9d705..b6f5e24244d6 100644 --- a/rust/ql/test/library-tests/type-inference/type-inference.expected +++ b/rust/ql/test/library-tests/type-inference/type-inference.expected @@ -3927,13 +3927,13 @@ inferType | main.rs:2253:22:2253:34 | map1.values() | V.T.&T | {EXTERNAL LOCATION} | str | | main.rs:2254:13:2254:24 | TuplePat | | {EXTERNAL LOCATION} | Item | | main.rs:2254:13:2254:24 | TuplePat | | file://:0:0:0:0 | (T_2) | -| main.rs:2254:13:2254:24 | TuplePat | 0 | file://:0:0:0:0 | & | -| main.rs:2254:13:2254:24 | TuplePat | 0.&T | {EXTERNAL LOCATION} | i32 | -| main.rs:2254:13:2254:24 | TuplePat | 1 | file://:0:0:0:0 | & | -| main.rs:2254:13:2254:24 | TuplePat | 1.&T | {EXTERNAL LOCATION} | Box | -| main.rs:2254:13:2254:24 | TuplePat | 1.&T.A | {EXTERNAL LOCATION} | Global | -| main.rs:2254:13:2254:24 | TuplePat | 1.&T.T | file://:0:0:0:0 | & | -| main.rs:2254:13:2254:24 | TuplePat | 1.&T.T.&T | {EXTERNAL LOCATION} | str | +| main.rs:2254:13:2254:24 | TuplePat | 0(2) | file://:0:0:0:0 | & | +| main.rs:2254:13:2254:24 | TuplePat | 0(2).&T | {EXTERNAL LOCATION} | i32 | +| main.rs:2254:13:2254:24 | TuplePat | 1(2) | file://:0:0:0:0 | & | +| main.rs:2254:13:2254:24 | TuplePat | 1(2).&T | {EXTERNAL LOCATION} | Box | +| main.rs:2254:13:2254:24 | TuplePat | 1(2).&T.A | {EXTERNAL LOCATION} | Global | +| main.rs:2254:13:2254:24 | TuplePat | 1(2).&T.T | file://:0:0:0:0 | & | +| main.rs:2254:13:2254:24 | TuplePat | 1(2).&T.T.&T | {EXTERNAL LOCATION} | str | | main.rs:2254:14:2254:16 | key | | file://:0:0:0:0 | & | | main.rs:2254:14:2254:16 | key | &T | {EXTERNAL LOCATION} | i32 | | main.rs:2254:19:2254:23 | value | | file://:0:0:0:0 | & | @@ -3956,13 +3956,13 @@ inferType | main.rs:2254:29:2254:39 | map1.iter() | V.T.&T | {EXTERNAL LOCATION} | str | | main.rs:2255:13:2255:24 | TuplePat | | {EXTERNAL LOCATION} | Item | | main.rs:2255:13:2255:24 | TuplePat | | file://:0:0:0:0 | (T_2) | -| main.rs:2255:13:2255:24 | TuplePat | 0 | file://:0:0:0:0 | & | -| main.rs:2255:13:2255:24 | TuplePat | 0.&T | {EXTERNAL LOCATION} | i32 | -| main.rs:2255:13:2255:24 | TuplePat | 1 | file://:0:0:0:0 | & | -| main.rs:2255:13:2255:24 | TuplePat | 1.&T | {EXTERNAL LOCATION} | Box | -| main.rs:2255:13:2255:24 | TuplePat | 1.&T.A | {EXTERNAL LOCATION} | Global | -| main.rs:2255:13:2255:24 | TuplePat | 1.&T.T | file://:0:0:0:0 | & | -| main.rs:2255:13:2255:24 | TuplePat | 1.&T.T.&T | {EXTERNAL LOCATION} | str | +| main.rs:2255:13:2255:24 | TuplePat | 0(2) | file://:0:0:0:0 | & | +| main.rs:2255:13:2255:24 | TuplePat | 0(2).&T | {EXTERNAL LOCATION} | i32 | +| main.rs:2255:13:2255:24 | TuplePat | 1(2) | file://:0:0:0:0 | & | +| main.rs:2255:13:2255:24 | TuplePat | 1(2).&T | {EXTERNAL LOCATION} | Box | +| main.rs:2255:13:2255:24 | TuplePat | 1(2).&T.A | {EXTERNAL LOCATION} | Global | +| main.rs:2255:13:2255:24 | TuplePat | 1(2).&T.T | file://:0:0:0:0 | & | +| main.rs:2255:13:2255:24 | TuplePat | 1(2).&T.T.&T | {EXTERNAL LOCATION} | str | | main.rs:2255:14:2255:16 | key | | file://:0:0:0:0 | & | | main.rs:2255:14:2255:16 | key | &T | {EXTERNAL LOCATION} | i32 | | main.rs:2255:19:2255:23 | value | | file://:0:0:0:0 | & | @@ -4092,57 +4092,57 @@ inferType | main.rs:2322:19:2322:48 | foo::<...>(...) | | {EXTERNAL LOCATION} | i32 | | main.rs:2322:30:2322:47 | ...::default(...) | | {EXTERNAL LOCATION} | i32 | | main.rs:2330:35:2332:9 | { ... } | | file://:0:0:0:0 | (T_2) | -| main.rs:2330:35:2332:9 | { ... } | 0 | main.rs:2327:5:2327:16 | S1 | -| main.rs:2330:35:2332:9 | { ... } | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2330:35:2332:9 | { ... } | 0(2) | main.rs:2327:5:2327:16 | S1 | +| main.rs:2330:35:2332:9 | { ... } | 1(2) | main.rs:2327:5:2327:16 | S1 | | main.rs:2331:13:2331:26 | TupleExpr | | file://:0:0:0:0 | (T_2) | -| main.rs:2331:13:2331:26 | TupleExpr | 0 | main.rs:2327:5:2327:16 | S1 | -| main.rs:2331:13:2331:26 | TupleExpr | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2331:13:2331:26 | TupleExpr | 0(2) | main.rs:2327:5:2327:16 | S1 | +| main.rs:2331:13:2331:26 | TupleExpr | 1(2) | main.rs:2327:5:2327:16 | S1 | | main.rs:2331:14:2331:18 | S1 {...} | | main.rs:2327:5:2327:16 | S1 | | main.rs:2331:21:2331:25 | S1 {...} | | main.rs:2327:5:2327:16 | S1 | | main.rs:2333:16:2333:19 | SelfParam | | main.rs:2327:5:2327:16 | S1 | | main.rs:2337:13:2337:13 | a | | file://:0:0:0:0 | (T_2) | -| main.rs:2337:13:2337:13 | a | 0 | main.rs:2327:5:2327:16 | S1 | -| main.rs:2337:13:2337:13 | a | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2337:13:2337:13 | a | 0(2) | main.rs:2327:5:2327:16 | S1 | +| main.rs:2337:13:2337:13 | a | 1(2) | main.rs:2327:5:2327:16 | S1 | | main.rs:2337:17:2337:30 | ...::get_pair(...) | | file://:0:0:0:0 | (T_2) | -| main.rs:2337:17:2337:30 | ...::get_pair(...) | 0 | main.rs:2327:5:2327:16 | S1 | -| main.rs:2337:17:2337:30 | ...::get_pair(...) | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2337:17:2337:30 | ...::get_pair(...) | 0(2) | main.rs:2327:5:2327:16 | S1 | +| main.rs:2337:17:2337:30 | ...::get_pair(...) | 1(2) | main.rs:2327:5:2327:16 | S1 | | main.rs:2338:17:2338:17 | b | | file://:0:0:0:0 | (T_2) | -| main.rs:2338:17:2338:17 | b | 0 | main.rs:2327:5:2327:16 | S1 | -| main.rs:2338:17:2338:17 | b | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2338:17:2338:17 | b | 0(2) | main.rs:2327:5:2327:16 | S1 | +| main.rs:2338:17:2338:17 | b | 1(2) | main.rs:2327:5:2327:16 | S1 | | main.rs:2338:21:2338:34 | ...::get_pair(...) | | file://:0:0:0:0 | (T_2) | -| main.rs:2338:21:2338:34 | ...::get_pair(...) | 0 | main.rs:2327:5:2327:16 | S1 | -| main.rs:2338:21:2338:34 | ...::get_pair(...) | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2338:21:2338:34 | ...::get_pair(...) | 0(2) | main.rs:2327:5:2327:16 | S1 | +| main.rs:2338:21:2338:34 | ...::get_pair(...) | 1(2) | main.rs:2327:5:2327:16 | S1 | | main.rs:2339:13:2339:18 | TuplePat | | file://:0:0:0:0 | (T_2) | -| main.rs:2339:13:2339:18 | TuplePat | 0 | main.rs:2327:5:2327:16 | S1 | -| main.rs:2339:13:2339:18 | TuplePat | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2339:13:2339:18 | TuplePat | 0(2) | main.rs:2327:5:2327:16 | S1 | +| main.rs:2339:13:2339:18 | TuplePat | 1(2) | main.rs:2327:5:2327:16 | S1 | | main.rs:2339:14:2339:14 | c | | main.rs:2327:5:2327:16 | S1 | | main.rs:2339:17:2339:17 | d | | main.rs:2327:5:2327:16 | S1 | | main.rs:2339:22:2339:35 | ...::get_pair(...) | | file://:0:0:0:0 | (T_2) | -| main.rs:2339:22:2339:35 | ...::get_pair(...) | 0 | main.rs:2327:5:2327:16 | S1 | -| main.rs:2339:22:2339:35 | ...::get_pair(...) | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2339:22:2339:35 | ...::get_pair(...) | 0(2) | main.rs:2327:5:2327:16 | S1 | +| main.rs:2339:22:2339:35 | ...::get_pair(...) | 1(2) | main.rs:2327:5:2327:16 | S1 | | main.rs:2340:13:2340:22 | TuplePat | | file://:0:0:0:0 | (T_2) | -| main.rs:2340:13:2340:22 | TuplePat | 0 | main.rs:2327:5:2327:16 | S1 | -| main.rs:2340:13:2340:22 | TuplePat | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2340:13:2340:22 | TuplePat | 0(2) | main.rs:2327:5:2327:16 | S1 | +| main.rs:2340:13:2340:22 | TuplePat | 1(2) | main.rs:2327:5:2327:16 | S1 | | main.rs:2340:18:2340:18 | e | | main.rs:2327:5:2327:16 | S1 | | main.rs:2340:21:2340:21 | f | | main.rs:2327:5:2327:16 | S1 | | main.rs:2340:26:2340:39 | ...::get_pair(...) | | file://:0:0:0:0 | (T_2) | -| main.rs:2340:26:2340:39 | ...::get_pair(...) | 0 | main.rs:2327:5:2327:16 | S1 | -| main.rs:2340:26:2340:39 | ...::get_pair(...) | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2340:26:2340:39 | ...::get_pair(...) | 0(2) | main.rs:2327:5:2327:16 | S1 | +| main.rs:2340:26:2340:39 | ...::get_pair(...) | 1(2) | main.rs:2327:5:2327:16 | S1 | | main.rs:2341:13:2341:26 | TuplePat | | file://:0:0:0:0 | (T_2) | -| main.rs:2341:13:2341:26 | TuplePat | 0 | main.rs:2327:5:2327:16 | S1 | -| main.rs:2341:13:2341:26 | TuplePat | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2341:13:2341:26 | TuplePat | 0(2) | main.rs:2327:5:2327:16 | S1 | +| main.rs:2341:13:2341:26 | TuplePat | 1(2) | main.rs:2327:5:2327:16 | S1 | | main.rs:2341:18:2341:18 | g | | main.rs:2327:5:2327:16 | S1 | | main.rs:2341:25:2341:25 | h | | main.rs:2327:5:2327:16 | S1 | | main.rs:2341:30:2341:43 | ...::get_pair(...) | | file://:0:0:0:0 | (T_2) | -| main.rs:2341:30:2341:43 | ...::get_pair(...) | 0 | main.rs:2327:5:2327:16 | S1 | -| main.rs:2341:30:2341:43 | ...::get_pair(...) | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2341:30:2341:43 | ...::get_pair(...) | 0(2) | main.rs:2327:5:2327:16 | S1 | +| main.rs:2341:30:2341:43 | ...::get_pair(...) | 1(2) | main.rs:2327:5:2327:16 | S1 | | main.rs:2343:9:2343:9 | a | | file://:0:0:0:0 | (T_2) | -| main.rs:2343:9:2343:9 | a | 0 | main.rs:2327:5:2327:16 | S1 | -| main.rs:2343:9:2343:9 | a | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2343:9:2343:9 | a | 0(2) | main.rs:2327:5:2327:16 | S1 | +| main.rs:2343:9:2343:9 | a | 1(2) | main.rs:2327:5:2327:16 | S1 | | main.rs:2343:9:2343:11 | a.0 | | main.rs:2327:5:2327:16 | S1 | | main.rs:2344:9:2344:9 | b | | file://:0:0:0:0 | (T_2) | -| main.rs:2344:9:2344:9 | b | 0 | main.rs:2327:5:2327:16 | S1 | -| main.rs:2344:9:2344:9 | b | 1 | main.rs:2327:5:2327:16 | S1 | +| main.rs:2344:9:2344:9 | b | 0(2) | main.rs:2327:5:2327:16 | S1 | +| main.rs:2344:9:2344:9 | b | 1(2) | main.rs:2327:5:2327:16 | S1 | | main.rs:2344:9:2344:11 | b.1 | | main.rs:2327:5:2327:16 | S1 | | main.rs:2345:9:2345:9 | c | | main.rs:2327:5:2327:16 | S1 | | main.rs:2346:9:2346:9 | d | | main.rs:2327:5:2327:16 | S1 | @@ -4155,22 +4155,22 @@ inferType | main.rs:2356:13:2356:13 | b | | {EXTERNAL LOCATION} | bool | | main.rs:2356:17:2356:34 | ...::default(...) | | {EXTERNAL LOCATION} | bool | | main.rs:2357:13:2357:16 | pair | | file://:0:0:0:0 | (T_2) | -| main.rs:2357:13:2357:16 | pair | 0 | {EXTERNAL LOCATION} | i64 | -| main.rs:2357:13:2357:16 | pair | 1 | {EXTERNAL LOCATION} | bool | +| main.rs:2357:13:2357:16 | pair | 0(2) | {EXTERNAL LOCATION} | i64 | +| main.rs:2357:13:2357:16 | pair | 1(2) | {EXTERNAL LOCATION} | bool | | main.rs:2357:20:2357:25 | TupleExpr | | file://:0:0:0:0 | (T_2) | -| main.rs:2357:20:2357:25 | TupleExpr | 0 | {EXTERNAL LOCATION} | i64 | -| main.rs:2357:20:2357:25 | TupleExpr | 1 | {EXTERNAL LOCATION} | bool | +| main.rs:2357:20:2357:25 | TupleExpr | 0(2) | {EXTERNAL LOCATION} | i64 | +| main.rs:2357:20:2357:25 | TupleExpr | 1(2) | {EXTERNAL LOCATION} | bool | | main.rs:2357:21:2357:21 | a | | {EXTERNAL LOCATION} | i64 | | main.rs:2357:24:2357:24 | b | | {EXTERNAL LOCATION} | bool | | main.rs:2358:13:2358:13 | i | | {EXTERNAL LOCATION} | i64 | | main.rs:2358:22:2358:25 | pair | | file://:0:0:0:0 | (T_2) | -| main.rs:2358:22:2358:25 | pair | 0 | {EXTERNAL LOCATION} | i64 | -| main.rs:2358:22:2358:25 | pair | 1 | {EXTERNAL LOCATION} | bool | +| main.rs:2358:22:2358:25 | pair | 0(2) | {EXTERNAL LOCATION} | i64 | +| main.rs:2358:22:2358:25 | pair | 1(2) | {EXTERNAL LOCATION} | bool | | main.rs:2358:22:2358:27 | pair.0 | | {EXTERNAL LOCATION} | i64 | | main.rs:2359:13:2359:13 | j | | {EXTERNAL LOCATION} | bool | | main.rs:2359:23:2359:26 | pair | | file://:0:0:0:0 | (T_2) | -| main.rs:2359:23:2359:26 | pair | 0 | {EXTERNAL LOCATION} | i64 | -| main.rs:2359:23:2359:26 | pair | 1 | {EXTERNAL LOCATION} | bool | +| main.rs:2359:23:2359:26 | pair | 0(2) | {EXTERNAL LOCATION} | i64 | +| main.rs:2359:23:2359:26 | pair | 1(2) | {EXTERNAL LOCATION} | bool | | main.rs:2359:23:2359:28 | pair.1 | | {EXTERNAL LOCATION} | bool | | main.rs:2366:13:2366:23 | boxed_value | | {EXTERNAL LOCATION} | Box | | main.rs:2366:13:2366:23 | boxed_value | A | {EXTERNAL LOCATION} | Global | @@ -5033,67 +5033,67 @@ inferType | pattern_matching.rs:438:22:438:49 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:438:37:438:49 | wrapped_value | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:444:9:444:13 | tuple | | file://:0:0:0:0 | (T_3) | -| pattern_matching.rs:444:9:444:13 | tuple | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:444:9:444:13 | tuple | 1 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:444:9:444:13 | tuple | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:444:9:444:13 | tuple | 2 | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:444:9:444:13 | tuple | 2 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:444:9:444:13 | tuple | 0(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:444:9:444:13 | tuple | 1(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:444:9:444:13 | tuple | 1(3) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:444:9:444:13 | tuple | 2(3) | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:444:9:444:13 | tuple | 2(3) | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:444:17:444:36 | TupleExpr | | file://:0:0:0:0 | (T_3) | -| pattern_matching.rs:444:17:444:36 | TupleExpr | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:444:17:444:36 | TupleExpr | 1 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:444:17:444:36 | TupleExpr | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:444:17:444:36 | TupleExpr | 2 | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:444:17:444:36 | TupleExpr | 2 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:444:17:444:36 | TupleExpr | 0(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:444:17:444:36 | TupleExpr | 1(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:444:17:444:36 | TupleExpr | 1(3) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:444:17:444:36 | TupleExpr | 2(3) | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:444:17:444:36 | TupleExpr | 2(3) | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:444:18:444:21 | 1i32 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:444:24:444:27 | 2i64 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:444:24:444:27 | 2i64 | | {EXTERNAL LOCATION} | i64 | | pattern_matching.rs:444:30:444:35 | 3.0f32 | | {EXTERNAL LOCATION} | f32 | | pattern_matching.rs:444:30:444:35 | 3.0f32 | | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:447:11:447:15 | tuple | | file://:0:0:0:0 | (T_3) | -| pattern_matching.rs:447:11:447:15 | tuple | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:447:11:447:15 | tuple | 1 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:447:11:447:15 | tuple | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:447:11:447:15 | tuple | 2 | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:447:11:447:15 | tuple | 2 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:447:11:447:15 | tuple | 0(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:447:11:447:15 | tuple | 1(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:447:11:447:15 | tuple | 1(3) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:447:11:447:15 | tuple | 2(3) | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:447:11:447:15 | tuple | 2(3) | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:448:9:448:19 | TuplePat | | file://:0:0:0:0 | (T_3) | -| pattern_matching.rs:448:9:448:19 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:448:9:448:19 | TuplePat | 1 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:448:9:448:19 | TuplePat | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:448:9:448:19 | TuplePat | 2 | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:448:9:448:19 | TuplePat | 2 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:448:9:448:19 | TuplePat | 0(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:448:9:448:19 | TuplePat | 1(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:448:9:448:19 | TuplePat | 1(3) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:448:9:448:19 | TuplePat | 2(3) | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:448:9:448:19 | TuplePat | 2(3) | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:448:10:448:10 | 1 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:448:13:448:13 | 2 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:448:13:448:13 | 2 | | {EXTERNAL LOCATION} | i64 | | pattern_matching.rs:448:16:448:18 | 3.0 | | {EXTERNAL LOCATION} | f32 | | pattern_matching.rs:448:16:448:18 | 3.0 | | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:449:17:449:27 | exact_tuple | | file://:0:0:0:0 | (T_3) | -| pattern_matching.rs:449:17:449:27 | exact_tuple | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:449:17:449:27 | exact_tuple | 1 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:449:17:449:27 | exact_tuple | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:449:17:449:27 | exact_tuple | 2 | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:449:17:449:27 | exact_tuple | 2 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:449:17:449:27 | exact_tuple | 0(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:449:17:449:27 | exact_tuple | 1(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:449:17:449:27 | exact_tuple | 1(3) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:449:17:449:27 | exact_tuple | 2(3) | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:449:17:449:27 | exact_tuple | 2(3) | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:449:31:449:35 | tuple | | file://:0:0:0:0 | (T_3) | -| pattern_matching.rs:449:31:449:35 | tuple | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:449:31:449:35 | tuple | 1 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:449:31:449:35 | tuple | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:449:31:449:35 | tuple | 2 | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:449:31:449:35 | tuple | 2 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:449:31:449:35 | tuple | 0(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:449:31:449:35 | tuple | 1(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:449:31:449:35 | tuple | 1(3) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:449:31:449:35 | tuple | 2(3) | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:449:31:449:35 | tuple | 2(3) | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:450:22:450:40 | "Exact tuple: {:?}\\n" | | file://:0:0:0:0 | & | | pattern_matching.rs:450:22:450:40 | "Exact tuple: {:?}\\n" | &T | {EXTERNAL LOCATION} | str | | pattern_matching.rs:450:22:450:53 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:450:22:450:53 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:450:43:450:53 | exact_tuple | | file://:0:0:0:0 | (T_3) | -| pattern_matching.rs:450:43:450:53 | exact_tuple | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:450:43:450:53 | exact_tuple | 1 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:450:43:450:53 | exact_tuple | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:450:43:450:53 | exact_tuple | 2 | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:450:43:450:53 | exact_tuple | 2 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:450:43:450:53 | exact_tuple | 0(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:450:43:450:53 | exact_tuple | 1(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:450:43:450:53 | exact_tuple | 1(3) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:450:43:450:53 | exact_tuple | 2(3) | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:450:43:450:53 | exact_tuple | 2(3) | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:452:9:452:17 | TuplePat | | file://:0:0:0:0 | (T_3) | -| pattern_matching.rs:452:9:452:17 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:452:9:452:17 | TuplePat | 1 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:452:9:452:17 | TuplePat | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:452:9:452:17 | TuplePat | 2 | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:452:9:452:17 | TuplePat | 2 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:452:9:452:17 | TuplePat | 0(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:452:9:452:17 | TuplePat | 1(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:452:9:452:17 | TuplePat | 1(3) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:452:9:452:17 | TuplePat | 2(3) | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:452:9:452:17 | TuplePat | 2(3) | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:452:10:452:10 | a | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:452:13:452:13 | b | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:452:13:452:13 | b | | {EXTERNAL LOCATION} | i64 | @@ -5119,27 +5119,21 @@ inferType | pattern_matching.rs:456:70:456:79 | third_elem | | {EXTERNAL LOCATION} | f32 | | pattern_matching.rs:456:70:456:79 | third_elem | | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:461:11:461:15 | tuple | | file://:0:0:0:0 | (T_3) | -| pattern_matching.rs:461:11:461:15 | tuple | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:461:11:461:15 | tuple | 1 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:461:11:461:15 | tuple | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:461:11:461:15 | tuple | 2 | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:461:11:461:15 | tuple | 2 | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:461:11:461:15 | tuple | 0(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:461:11:461:15 | tuple | 1(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:461:11:461:15 | tuple | 1(3) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:461:11:461:15 | tuple | 2(3) | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:461:11:461:15 | tuple | 2(3) | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:462:9:462:19 | TuplePat | | file://:0:0:0:0 | (T_3) | -| pattern_matching.rs:462:9:462:19 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:462:9:462:19 | TuplePat | 1 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:462:9:462:19 | TuplePat | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:462:9:462:19 | TuplePat | 2 | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:462:9:462:19 | TuplePat | 2 | {EXTERNAL LOCATION} | f64 | -| pattern_matching.rs:462:10:462:14 | first | | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:462:17:462:18 | .. | | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:462:17:462:18 | .. | | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:463:17:463:27 | tuple_first | | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:463:31:463:35 | first | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:462:9:462:19 | TuplePat | 0(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:462:9:462:19 | TuplePat | 1(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:462:9:462:19 | TuplePat | 1(3) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:462:9:462:19 | TuplePat | 2(3) | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:462:9:462:19 | TuplePat | 2(3) | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:464:22:464:40 | "First element: {}\\n" | | file://:0:0:0:0 | & | | pattern_matching.rs:464:22:464:40 | "First element: {}\\n" | &T | {EXTERNAL LOCATION} | str | | pattern_matching.rs:464:22:464:53 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:464:22:464:53 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | -| pattern_matching.rs:464:43:464:53 | tuple_first | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:469:9:469:12 | unit | | file://:0:0:0:0 | () | | pattern_matching.rs:469:16:469:17 | TupleExpr | | file://:0:0:0:0 | () | | pattern_matching.rs:470:11:470:14 | unit | | file://:0:0:0:0 | () | @@ -5152,14 +5146,14 @@ inferType | pattern_matching.rs:473:22:473:51 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:473:42:473:51 | unit_value | | file://:0:0:0:0 | () | | pattern_matching.rs:478:9:478:14 | single | | file://:0:0:0:0 | (T_1) | -| pattern_matching.rs:478:9:478:14 | single | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:478:9:478:14 | single | 0(1) | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:478:18:478:25 | TupleExpr | | file://:0:0:0:0 | (T_1) | -| pattern_matching.rs:478:18:478:25 | TupleExpr | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:478:18:478:25 | TupleExpr | 0(1) | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:478:19:478:23 | 42i32 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:479:11:479:16 | single | | file://:0:0:0:0 | (T_1) | -| pattern_matching.rs:479:11:479:16 | single | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:479:11:479:16 | single | 0(1) | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:480:9:480:12 | TuplePat | | file://:0:0:0:0 | (T_1) | -| pattern_matching.rs:480:9:480:12 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:480:9:480:12 | TuplePat | 0(1) | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:480:10:480:10 | x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:481:17:481:27 | single_elem | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:481:31:481:31 | x | | {EXTERNAL LOCATION} | i32 | @@ -5181,19 +5175,19 @@ inferType | pattern_matching.rs:494:22:494:61 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:494:51:494:61 | paren_bound | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:499:9:499:13 | tuple | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:499:9:499:13 | tuple | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:499:9:499:13 | tuple | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:499:9:499:13 | tuple | 0(2) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:499:9:499:13 | tuple | 1(2) | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:499:17:499:28 | TupleExpr | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:499:17:499:28 | TupleExpr | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:499:17:499:28 | TupleExpr | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:499:17:499:28 | TupleExpr | 0(2) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:499:17:499:28 | TupleExpr | 1(2) | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:499:18:499:21 | 1i32 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:499:24:499:27 | 2i32 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:500:11:500:15 | tuple | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:500:11:500:15 | tuple | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:500:11:500:15 | tuple | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:500:11:500:15 | tuple | 0(2) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:500:11:500:15 | tuple | 1(2) | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:501:9:501:16 | TuplePat | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:501:9:501:16 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:501:9:501:16 | TuplePat | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:501:9:501:16 | TuplePat | 0(2) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:501:9:501:16 | TuplePat | 1(2) | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:501:10:501:10 | x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:501:13:501:15 | (...) | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:501:14:501:14 | y | | {EXTERNAL LOCATION} | i32 | @@ -5426,80 +5420,61 @@ inferType | pattern_matching.rs:621:38:621:51 | range_or_value | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:623:9:623:9 | _ | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:628:9:628:13 | tuple | | file://:0:0:0:0 | (T_4) | -| pattern_matching.rs:628:9:628:13 | tuple | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:628:9:628:13 | tuple | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:628:9:628:13 | tuple | 2 | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:628:9:628:13 | tuple | 3 | {EXTERNAL LOCATION} | u8 | +| pattern_matching.rs:628:9:628:13 | tuple | 0(4) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:628:9:628:13 | tuple | 1(4) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:628:9:628:13 | tuple | 2(4) | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:628:9:628:13 | tuple | 3(4) | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:628:17:628:41 | TupleExpr | | file://:0:0:0:0 | (T_4) | -| pattern_matching.rs:628:17:628:41 | TupleExpr | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:628:17:628:41 | TupleExpr | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:628:17:628:41 | TupleExpr | 2 | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:628:17:628:41 | TupleExpr | 3 | {EXTERNAL LOCATION} | u8 | +| pattern_matching.rs:628:17:628:41 | TupleExpr | 0(4) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:628:17:628:41 | TupleExpr | 1(4) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:628:17:628:41 | TupleExpr | 2(4) | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:628:17:628:41 | TupleExpr | 3(4) | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:628:18:628:21 | 1i32 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:628:24:628:27 | 2i64 | | {EXTERNAL LOCATION} | i64 | | pattern_matching.rs:628:30:628:35 | 3.0f32 | | {EXTERNAL LOCATION} | f32 | | pattern_matching.rs:628:38:628:40 | 4u8 | | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:631:11:631:15 | tuple | | file://:0:0:0:0 | (T_4) | -| pattern_matching.rs:631:11:631:15 | tuple | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:631:11:631:15 | tuple | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:631:11:631:15 | tuple | 2 | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:631:11:631:15 | tuple | 3 | {EXTERNAL LOCATION} | u8 | +| pattern_matching.rs:631:11:631:15 | tuple | 0(4) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:631:11:631:15 | tuple | 1(4) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:631:11:631:15 | tuple | 2(4) | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:631:11:631:15 | tuple | 3(4) | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:632:9:632:19 | TuplePat | | file://:0:0:0:0 | (T_4) | -| pattern_matching.rs:632:9:632:19 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:632:9:632:19 | TuplePat | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:632:9:632:19 | TuplePat | 2 | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:632:9:632:19 | TuplePat | 3 | {EXTERNAL LOCATION} | u8 | -| pattern_matching.rs:632:10:632:14 | first | | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:632:17:632:18 | .. | | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:633:17:633:26 | rest_first | | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:633:30:633:34 | first | | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:632:9:632:19 | TuplePat | 0(4) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:632:9:632:19 | TuplePat | 1(4) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:632:9:632:19 | TuplePat | 2(4) | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:632:9:632:19 | TuplePat | 3(4) | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:634:22:634:42 | "First with rest: {}\\n" | | file://:0:0:0:0 | & | | pattern_matching.rs:634:22:634:42 | "First with rest: {}\\n" | &T | {EXTERNAL LOCATION} | str | | pattern_matching.rs:634:22:634:54 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:634:22:634:54 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | -| pattern_matching.rs:634:45:634:54 | rest_first | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:638:11:638:15 | tuple | | file://:0:0:0:0 | (T_4) | -| pattern_matching.rs:638:11:638:15 | tuple | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:638:11:638:15 | tuple | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:638:11:638:15 | tuple | 2 | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:638:11:638:15 | tuple | 3 | {EXTERNAL LOCATION} | u8 | +| pattern_matching.rs:638:11:638:15 | tuple | 0(4) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:638:11:638:15 | tuple | 1(4) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:638:11:638:15 | tuple | 2(4) | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:638:11:638:15 | tuple | 3(4) | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:639:9:639:18 | TuplePat | | file://:0:0:0:0 | (T_4) | -| pattern_matching.rs:639:9:639:18 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:639:9:639:18 | TuplePat | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:639:9:639:18 | TuplePat | 2 | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:639:9:639:18 | TuplePat | 3 | {EXTERNAL LOCATION} | u8 | -| pattern_matching.rs:639:10:639:11 | .. | | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:639:14:639:17 | last | | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:640:17:640:25 | rest_last | | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:640:29:640:32 | last | | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:639:9:639:18 | TuplePat | 0(4) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:639:9:639:18 | TuplePat | 1(4) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:639:9:639:18 | TuplePat | 2(4) | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:639:9:639:18 | TuplePat | 3(4) | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:641:22:641:41 | "Last with rest: {}\\n" | | file://:0:0:0:0 | & | | pattern_matching.rs:641:22:641:41 | "Last with rest: {}\\n" | &T | {EXTERNAL LOCATION} | str | | pattern_matching.rs:641:22:641:52 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:641:22:641:52 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | -| pattern_matching.rs:641:44:641:52 | rest_last | | {EXTERNAL LOCATION} | i64 | | pattern_matching.rs:645:11:645:15 | tuple | | file://:0:0:0:0 | (T_4) | -| pattern_matching.rs:645:11:645:15 | tuple | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:645:11:645:15 | tuple | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:645:11:645:15 | tuple | 2 | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:645:11:645:15 | tuple | 3 | {EXTERNAL LOCATION} | u8 | +| pattern_matching.rs:645:11:645:15 | tuple | 0(4) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:645:11:645:15 | tuple | 1(4) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:645:11:645:15 | tuple | 2(4) | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:645:11:645:15 | tuple | 3(4) | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:646:9:646:25 | TuplePat | | file://:0:0:0:0 | (T_4) | -| pattern_matching.rs:646:9:646:25 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:646:9:646:25 | TuplePat | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:646:9:646:25 | TuplePat | 2 | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:646:9:646:25 | TuplePat | 3 | {EXTERNAL LOCATION} | u8 | -| pattern_matching.rs:646:10:646:14 | first | | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:646:17:646:18 | .. | | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:646:21:646:24 | last | | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:647:17:647:26 | rest_start | | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:647:30:647:34 | first | | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:648:17:648:24 | rest_end | | {EXTERNAL LOCATION} | f32 | -| pattern_matching.rs:648:28:648:31 | last | | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:646:9:646:25 | TuplePat | 0(4) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:646:9:646:25 | TuplePat | 1(4) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:646:9:646:25 | TuplePat | 2(4) | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:646:9:646:25 | TuplePat | 3(4) | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:649:22:649:45 | "First and last: {}, {}\\n" | | file://:0:0:0:0 | & | | pattern_matching.rs:649:22:649:45 | "First and last: {}, {}\\n" | &T | {EXTERNAL LOCATION} | str | | pattern_matching.rs:649:22:649:67 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:649:22:649:67 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | -| pattern_matching.rs:649:48:649:57 | rest_start | | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:649:60:649:67 | rest_end | | {EXTERNAL LOCATION} | f32 | | pattern_matching.rs:654:9:654:13 | point | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:654:17:654:38 | Point {...} | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:654:28:654:29 | 10 | | {EXTERNAL LOCATION} | i32 | @@ -5523,13 +5498,13 @@ inferType | pattern_matching.rs:682:21:682:25 | 10i32 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:682:28:682:28 | x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:687:9:687:20 | complex_data | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:687:9:687:20 | complex_data | 0 | pattern_matching.rs:135:1:140:1 | Point | -| pattern_matching.rs:687:9:687:20 | complex_data | 1 | pattern_matching.rs:152:1:156:1 | MyOption | -| pattern_matching.rs:687:9:687:20 | complex_data | 1.T | pattern_matching.rs:142:1:143:25 | Color | +| pattern_matching.rs:687:9:687:20 | complex_data | 0(2) | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:687:9:687:20 | complex_data | 1(2) | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:687:9:687:20 | complex_data | 1(2).T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:687:24:687:79 | TupleExpr | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:687:24:687:79 | TupleExpr | 0 | pattern_matching.rs:135:1:140:1 | Point | -| pattern_matching.rs:687:24:687:79 | TupleExpr | 1 | pattern_matching.rs:152:1:156:1 | MyOption | -| pattern_matching.rs:687:24:687:79 | TupleExpr | 1.T | pattern_matching.rs:142:1:143:25 | Color | +| pattern_matching.rs:687:24:687:79 | TupleExpr | 0(2) | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:687:24:687:79 | TupleExpr | 1(2) | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:687:24:687:79 | TupleExpr | 1(2).T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:687:25:687:44 | Point {...} | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:687:36:687:36 | 1 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:687:42:687:42 | 2 | | {EXTERNAL LOCATION} | i32 | @@ -5543,13 +5518,13 @@ inferType | pattern_matching.rs:687:76:687:76 | 0 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:687:76:687:76 | 0 | | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:689:11:689:22 | complex_data | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:689:11:689:22 | complex_data | 0 | pattern_matching.rs:135:1:140:1 | Point | -| pattern_matching.rs:689:11:689:22 | complex_data | 1 | pattern_matching.rs:152:1:156:1 | MyOption | -| pattern_matching.rs:689:11:689:22 | complex_data | 1.T | pattern_matching.rs:142:1:143:25 | Color | +| pattern_matching.rs:689:11:689:22 | complex_data | 0(2) | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:689:11:689:22 | complex_data | 1(2) | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:689:11:689:22 | complex_data | 1(2).T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:691:9:691:61 | TuplePat | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:691:9:691:61 | TuplePat | 0 | pattern_matching.rs:135:1:140:1 | Point | -| pattern_matching.rs:691:9:691:61 | TuplePat | 1 | pattern_matching.rs:152:1:156:1 | MyOption | -| pattern_matching.rs:691:9:691:61 | TuplePat | 1.T | pattern_matching.rs:142:1:143:25 | Color | +| pattern_matching.rs:691:9:691:61 | TuplePat | 0(2) | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:691:9:691:61 | TuplePat | 1(2) | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:691:9:691:61 | TuplePat | 1(2).T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:691:10:691:26 | Point {...} | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:691:21:691:21 | 1 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:691:24:691:24 | y | | {EXTERNAL LOCATION} | i32 | @@ -5574,21 +5549,21 @@ inferType | pattern_matching.rs:697:27:697:34 | nested_g | | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:697:37:697:44 | nested_b | | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:701:9:701:41 | TuplePat | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:701:9:701:41 | TuplePat | 0 | pattern_matching.rs:135:1:140:1 | Point | -| pattern_matching.rs:701:9:701:41 | TuplePat | 1 | pattern_matching.rs:152:1:156:1 | MyOption | -| pattern_matching.rs:701:9:701:41 | TuplePat | 1.T | pattern_matching.rs:142:1:143:25 | Color | +| pattern_matching.rs:701:9:701:41 | TuplePat | 0(2) | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:701:9:701:41 | TuplePat | 1(2) | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:701:9:701:41 | TuplePat | 1(2).T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:701:9:701:71 | ... \| ... | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:701:9:701:71 | ... \| ... | 0 | pattern_matching.rs:135:1:140:1 | Point | -| pattern_matching.rs:701:9:701:71 | ... \| ... | 1 | pattern_matching.rs:152:1:156:1 | MyOption | -| pattern_matching.rs:701:9:701:71 | ... \| ... | 1.T | pattern_matching.rs:142:1:143:25 | Color | +| pattern_matching.rs:701:9:701:71 | ... \| ... | 0(2) | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:701:9:701:71 | ... \| ... | 1(2) | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:701:9:701:71 | ... \| ... | 1(2).T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:701:10:701:24 | Point {...} | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:701:18:701:18 | x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:701:27:701:40 | ...::None | | pattern_matching.rs:152:1:156:1 | MyOption | | pattern_matching.rs:701:27:701:40 | ...::None | T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:701:45:701:71 | TuplePat | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:701:45:701:71 | TuplePat | 0 | pattern_matching.rs:135:1:140:1 | Point | -| pattern_matching.rs:701:45:701:71 | TuplePat | 1 | pattern_matching.rs:152:1:156:1 | MyOption | -| pattern_matching.rs:701:45:701:71 | TuplePat | 1.T | pattern_matching.rs:142:1:143:25 | Color | +| pattern_matching.rs:701:45:701:71 | TuplePat | 0(2) | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:701:45:701:71 | TuplePat | 1(2) | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:701:45:701:71 | TuplePat | 1(2).T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:701:46:701:67 | Point {...} | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:701:57:701:57 | x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:701:61:701:61 | 0 | | {EXTERNAL LOCATION} | i32 | @@ -5602,25 +5577,25 @@ inferType | pattern_matching.rs:703:22:703:65 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:703:53:703:65 | alt_complex_x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:706:9:706:13 | other | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:706:9:706:13 | other | 0 | pattern_matching.rs:135:1:140:1 | Point | -| pattern_matching.rs:706:9:706:13 | other | 1 | pattern_matching.rs:152:1:156:1 | MyOption | -| pattern_matching.rs:706:9:706:13 | other | 1.T | pattern_matching.rs:142:1:143:25 | Color | +| pattern_matching.rs:706:9:706:13 | other | 0(2) | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:706:9:706:13 | other | 1(2) | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:706:9:706:13 | other | 1(2).T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:707:17:707:29 | other_complex | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:707:17:707:29 | other_complex | 0 | pattern_matching.rs:135:1:140:1 | Point | -| pattern_matching.rs:707:17:707:29 | other_complex | 1 | pattern_matching.rs:152:1:156:1 | MyOption | -| pattern_matching.rs:707:17:707:29 | other_complex | 1.T | pattern_matching.rs:142:1:143:25 | Color | +| pattern_matching.rs:707:17:707:29 | other_complex | 0(2) | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:707:17:707:29 | other_complex | 1(2) | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:707:17:707:29 | other_complex | 1(2).T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:707:33:707:37 | other | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:707:33:707:37 | other | 0 | pattern_matching.rs:135:1:140:1 | Point | -| pattern_matching.rs:707:33:707:37 | other | 1 | pattern_matching.rs:152:1:156:1 | MyOption | -| pattern_matching.rs:707:33:707:37 | other | 1.T | pattern_matching.rs:142:1:143:25 | Color | +| pattern_matching.rs:707:33:707:37 | other | 0(2) | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:707:33:707:37 | other | 1(2) | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:707:33:707:37 | other | 1(2).T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:708:22:708:47 | "Other complex data: {:?}\\n" | | file://:0:0:0:0 | & | | pattern_matching.rs:708:22:708:47 | "Other complex data: {:?}\\n" | &T | {EXTERNAL LOCATION} | str | | pattern_matching.rs:708:22:708:62 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:708:22:708:62 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | | pattern_matching.rs:708:50:708:62 | other_complex | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:708:50:708:62 | other_complex | 0 | pattern_matching.rs:135:1:140:1 | Point | -| pattern_matching.rs:708:50:708:62 | other_complex | 1 | pattern_matching.rs:152:1:156:1 | MyOption | -| pattern_matching.rs:708:50:708:62 | other_complex | 1.T | pattern_matching.rs:142:1:143:25 | Color | +| pattern_matching.rs:708:50:708:62 | other_complex | 0(2) | pattern_matching.rs:135:1:140:1 | Point | +| pattern_matching.rs:708:50:708:62 | other_complex | 1(2) | pattern_matching.rs:152:1:156:1 | MyOption | +| pattern_matching.rs:708:50:708:62 | other_complex | 1(2).T | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:715:9:715:13 | point | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:715:17:715:38 | Point {...} | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:715:28:715:29 | 10 | | {EXTERNAL LOCATION} | i32 | @@ -5634,27 +5609,27 @@ inferType | pattern_matching.rs:718:9:718:13 | let_y | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:718:17:718:17 | y | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:720:9:720:13 | tuple | | file://:0:0:0:0 | (T_3) | -| pattern_matching.rs:720:9:720:13 | tuple | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:720:9:720:13 | tuple | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:720:9:720:13 | tuple | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:720:9:720:13 | tuple | 0(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:720:9:720:13 | tuple | 1(3) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:720:9:720:13 | tuple | 2(3) | {EXTERNAL LOCATION} | f32 | | pattern_matching.rs:720:17:720:36 | TupleExpr | | file://:0:0:0:0 | (T_3) | -| pattern_matching.rs:720:17:720:36 | TupleExpr | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:720:17:720:36 | TupleExpr | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:720:17:720:36 | TupleExpr | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:720:17:720:36 | TupleExpr | 0(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:720:17:720:36 | TupleExpr | 1(3) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:720:17:720:36 | TupleExpr | 2(3) | {EXTERNAL LOCATION} | f32 | | pattern_matching.rs:720:18:720:21 | 1i32 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:720:24:720:27 | 2i64 | | {EXTERNAL LOCATION} | i64 | | pattern_matching.rs:720:30:720:35 | 3.0f32 | | {EXTERNAL LOCATION} | f32 | | pattern_matching.rs:721:9:721:17 | TuplePat | | file://:0:0:0:0 | (T_3) | -| pattern_matching.rs:721:9:721:17 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:721:9:721:17 | TuplePat | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:721:9:721:17 | TuplePat | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:721:9:721:17 | TuplePat | 0(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:721:9:721:17 | TuplePat | 1(3) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:721:9:721:17 | TuplePat | 2(3) | {EXTERNAL LOCATION} | f32 | | pattern_matching.rs:721:10:721:10 | a | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:721:13:721:13 | b | | {EXTERNAL LOCATION} | i64 | | pattern_matching.rs:721:16:721:16 | c | | {EXTERNAL LOCATION} | f32 | | pattern_matching.rs:721:21:721:25 | tuple | | file://:0:0:0:0 | (T_3) | -| pattern_matching.rs:721:21:721:25 | tuple | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:721:21:721:25 | tuple | 1 | {EXTERNAL LOCATION} | i64 | -| pattern_matching.rs:721:21:721:25 | tuple | 2 | {EXTERNAL LOCATION} | f32 | +| pattern_matching.rs:721:21:721:25 | tuple | 0(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:721:21:721:25 | tuple | 1(3) | {EXTERNAL LOCATION} | i64 | +| pattern_matching.rs:721:21:721:25 | tuple | 2(3) | {EXTERNAL LOCATION} | f32 | | pattern_matching.rs:722:9:722:13 | let_a | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:722:17:722:17 | a | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:723:9:723:13 | let_b | | {EXTERNAL LOCATION} | i64 | @@ -5710,15 +5685,15 @@ inferType | pattern_matching.rs:750:30:750:30 | x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:750:33:750:33 | y | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:750:59:754:5 | { ... } | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:750:59:754:5 | { ... } | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:750:59:754:5 | { ... } | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:750:59:754:5 | { ... } | 0(2) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:750:59:754:5 | { ... } | 1(2) | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:751:13:751:19 | param_x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:751:23:751:23 | x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:752:13:752:19 | param_y | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:752:23:752:23 | y | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:753:9:753:26 | TupleExpr | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:753:9:753:26 | TupleExpr | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:753:9:753:26 | TupleExpr | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:753:9:753:26 | TupleExpr | 0(2) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:753:9:753:26 | TupleExpr | 1(2) | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:753:10:753:16 | param_x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:753:19:753:25 | param_y | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:756:22:756:35 | Color(...) | | pattern_matching.rs:142:1:143:25 | Color | @@ -5730,22 +5705,22 @@ inferType | pattern_matching.rs:757:23:757:23 | r | | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:758:9:758:15 | param_r | | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:761:22:761:38 | TuplePat | | file://:0:0:0:0 | (T_3) | -| pattern_matching.rs:761:22:761:38 | TuplePat | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:761:22:761:38 | TuplePat | 1 | {EXTERNAL LOCATION} | f64 | -| pattern_matching.rs:761:22:761:38 | TuplePat | 2 | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:761:22:761:38 | TuplePat | 0(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:761:22:761:38 | TuplePat | 1(3) | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:761:22:761:38 | TuplePat | 2(3) | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:761:23:761:27 | first | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:761:30:761:30 | _ | | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:761:33:761:37 | third | | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:761:74:765:5 | { ... } | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:761:74:765:5 | { ... } | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:761:74:765:5 | { ... } | 1 | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:761:74:765:5 | { ... } | 0(2) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:761:74:765:5 | { ... } | 1(2) | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:762:13:762:23 | param_first | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:762:27:762:31 | first | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:763:13:763:23 | param_third | | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:763:27:763:31 | third | | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:764:9:764:34 | TupleExpr | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:764:9:764:34 | TupleExpr | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:764:9:764:34 | TupleExpr | 1 | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:764:9:764:34 | TupleExpr | 0(2) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:764:9:764:34 | TupleExpr | 1(2) | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:764:10:764:20 | param_first | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:764:23:764:33 | param_third | | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:768:9:768:13 | point | | pattern_matching.rs:135:1:140:1 | Point | @@ -5753,11 +5728,11 @@ inferType | pattern_matching.rs:768:28:768:28 | 5 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:768:34:768:35 | 10 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:769:9:769:17 | extracted | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:769:9:769:17 | extracted | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:769:9:769:17 | extracted | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:769:9:769:17 | extracted | 0(2) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:769:9:769:17 | extracted | 1(2) | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:769:21:769:40 | extract_point(...) | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:769:21:769:40 | extract_point(...) | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:769:21:769:40 | extract_point(...) | 1 | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:769:21:769:40 | extract_point(...) | 0(2) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:769:21:769:40 | extract_point(...) | 1(2) | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:769:35:769:39 | point | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:771:9:771:13 | color | | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:771:17:771:35 | Color(...) | | pattern_matching.rs:142:1:143:25 | Color | @@ -5771,26 +5746,26 @@ inferType | pattern_matching.rs:772:15:772:34 | extract_color(...) | | {EXTERNAL LOCATION} | u8 | | pattern_matching.rs:772:29:772:33 | color | | pattern_matching.rs:142:1:143:25 | Color | | pattern_matching.rs:774:9:774:13 | tuple | | file://:0:0:0:0 | (T_3) | -| pattern_matching.rs:774:9:774:13 | tuple | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:774:9:774:13 | tuple | 1 | {EXTERNAL LOCATION} | f64 | -| pattern_matching.rs:774:9:774:13 | tuple | 2 | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:774:9:774:13 | tuple | 0(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:774:9:774:13 | tuple | 1(3) | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:774:9:774:13 | tuple | 2(3) | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:774:17:774:38 | TupleExpr | | file://:0:0:0:0 | (T_3) | -| pattern_matching.rs:774:17:774:38 | TupleExpr | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:774:17:774:38 | TupleExpr | 1 | {EXTERNAL LOCATION} | f64 | -| pattern_matching.rs:774:17:774:38 | TupleExpr | 2 | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:774:17:774:38 | TupleExpr | 0(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:774:17:774:38 | TupleExpr | 1(3) | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:774:17:774:38 | TupleExpr | 2(3) | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:774:18:774:22 | 42i32 | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:774:25:774:31 | 3.14f64 | | {EXTERNAL LOCATION} | f64 | | pattern_matching.rs:774:34:774:37 | true | | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:775:9:775:23 | tuple_extracted | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:775:9:775:23 | tuple_extracted | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:775:9:775:23 | tuple_extracted | 1 | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:775:9:775:23 | tuple_extracted | 0(2) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:775:9:775:23 | tuple_extracted | 1(2) | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:775:27:775:46 | extract_tuple(...) | | file://:0:0:0:0 | (T_2) | -| pattern_matching.rs:775:27:775:46 | extract_tuple(...) | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:775:27:775:46 | extract_tuple(...) | 1 | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:775:27:775:46 | extract_tuple(...) | 0(2) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:775:27:775:46 | extract_tuple(...) | 1(2) | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:775:41:775:45 | tuple | | file://:0:0:0:0 | (T_3) | -| pattern_matching.rs:775:41:775:45 | tuple | 0 | {EXTERNAL LOCATION} | i32 | -| pattern_matching.rs:775:41:775:45 | tuple | 1 | {EXTERNAL LOCATION} | f64 | -| pattern_matching.rs:775:41:775:45 | tuple | 2 | {EXTERNAL LOCATION} | bool | +| pattern_matching.rs:775:41:775:45 | tuple | 0(3) | {EXTERNAL LOCATION} | i32 | +| pattern_matching.rs:775:41:775:45 | tuple | 1(3) | {EXTERNAL LOCATION} | f64 | +| pattern_matching.rs:775:41:775:45 | tuple | 2(3) | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:781:23:781:42 | (...) | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:781:23:781:42 | Point {...} | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:781:34:781:34 | 1 | | {EXTERNAL LOCATION} | i32 | From 97e77944eb19336e5af3e842f2b9925ed7d5b296 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Tue, 15 Jul 2025 10:21:53 +0200 Subject: [PATCH 4/8] Rust: Accept test changes --- .../local/CONSISTENCY/PathResolutionConsistency.expected | 2 ++ rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 rust/ql/test/library-tests/dataflow/local/CONSISTENCY/PathResolutionConsistency.expected diff --git a/rust/ql/test/library-tests/dataflow/local/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/library-tests/dataflow/local/CONSISTENCY/PathResolutionConsistency.expected new file mode 100644 index 000000000000..75c14035c455 --- /dev/null +++ b/rust/ql/test/library-tests/dataflow/local/CONSISTENCY/PathResolutionConsistency.expected @@ -0,0 +1,2 @@ +multipleCallTargets +| main.rs:445:18:445:24 | n.len() | diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index a51811179f00..b6bb529b23ee 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -979,6 +979,7 @@ readStep | main.rs:442:25:442:29 | names | file://:0:0:0:0 | element | main.rs:442:9:442:20 | TuplePat | | main.rs:444:41:444:67 | [post] \|...\| ... | main.rs:441:9:441:20 | captured default_name | main.rs:444:41:444:67 | [post] default_name | | main.rs:444:44:444:55 | this | main.rs:441:9:441:20 | captured default_name | main.rs:444:44:444:55 | default_name | +| main.rs:445:18:445:18 | [post] receiver for n | file://:0:0:0:0 | &ref | main.rs:445:18:445:18 | [post] n | | main.rs:469:13:469:13 | [post] receiver for b | file://:0:0:0:0 | &ref | main.rs:469:13:469:13 | [post] b | | main.rs:470:18:470:18 | [post] receiver for b | file://:0:0:0:0 | &ref | main.rs:470:18:470:18 | [post] b | | main.rs:481:10:481:11 | vs | file://:0:0:0:0 | element | main.rs:481:10:481:14 | vs[0] | @@ -1078,6 +1079,7 @@ storeStep | main.rs:429:30:429:30 | 3 | file://:0:0:0:0 | element | main.rs:429:23:429:31 | [...] | | main.rs:432:18:432:27 | source(...) | file://:0:0:0:0 | element | main.rs:432:5:432:11 | [post] mut_arr | | main.rs:444:41:444:67 | default_name | main.rs:441:9:441:20 | captured default_name | main.rs:444:41:444:67 | \|...\| ... | +| main.rs:445:18:445:18 | n | file://:0:0:0:0 | &ref | main.rs:445:18:445:18 | receiver for n | | main.rs:469:13:469:13 | b | file://:0:0:0:0 | &ref | main.rs:469:13:469:13 | receiver for b | | main.rs:470:18:470:18 | b | file://:0:0:0:0 | &ref | main.rs:470:18:470:18 | receiver for b | | main.rs:479:15:479:24 | source(...) | file://:0:0:0:0 | element | main.rs:479:14:479:34 | [...] | From 8858f213ff35e60c838c906e6f4186e3cd941843 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Tue, 15 Jul 2025 10:23:30 +0200 Subject: [PATCH 5/8] Rust: Add a change note --- rust/ql/src/change-notes/2025-07-15-type-inference-tuples.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 rust/ql/src/change-notes/2025-07-15-type-inference-tuples.md diff --git a/rust/ql/src/change-notes/2025-07-15-type-inference-tuples.md b/rust/ql/src/change-notes/2025-07-15-type-inference-tuples.md new file mode 100644 index 000000000000..bb44c45053bc --- /dev/null +++ b/rust/ql/src/change-notes/2025-07-15-type-inference-tuples.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Type inference now supports tuple types. \ No newline at end of file From a508089df8a961cc7031257611157958d0d0bdfd Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 16 Jul 2025 09:38:29 +0200 Subject: [PATCH 6/8] Rust: Improvements to tuple type inference based on PR feedback --- rust/ql/.generated.list | 1 - rust/ql/.gitattributes | 1 - .../rust/elements/internal/TuplePatImpl.qll | 16 +- rust/ql/lib/codeql/rust/internal/Type.qll | 41 ++-- .../codeql/rust/internal/TypeInference.qll | 33 ++- .../test/library-tests/type-inference/main.rs | 7 + .../type-inference/pattern_matching.rs | 4 +- .../type-inference/type-inference.expected | 214 ++++++++++-------- 8 files changed, 189 insertions(+), 128 deletions(-) diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 1d2b69ce32ed..a87de2bc4682 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -417,7 +417,6 @@ lib/codeql/rust/elements/internal/TupleFieldConstructor.qll 89d3cf2540235044ed5a lib/codeql/rust/elements/internal/TupleFieldListConstructor.qll 4335ba2061b6e4968db9ec05c0b4d3e6a564db89a2df69e036f317672a7900b1 0b8dded875dbf696cf588e8c21acc27332a2ff66ced7bfabdfc1ad621991f888 lib/codeql/rust/elements/internal/TupleFieldListImpl.qll 74869e92a3cbdd7895adaaa418d29d5e97387daf46c17315f219ad967af15d76 5815e4b37db958663df1f6fedc9667a11b261c9c2133e3f983a3aedc452c01fc lib/codeql/rust/elements/internal/TuplePatConstructor.qll 2a5e83ad5b8713a732e610128aeddf14e9b344402d6cf30ff0b43aa39e838418 6d467f7141307523994f03ed7b8e8b1a5bcf860963c9934b90e54582ea38096a -lib/codeql/rust/elements/internal/TuplePatImpl.qll 4adb38f0f8dae4ff285b9f5843efb92af419719a7549e0ff62dc56969bd3c852 3f622130771d7731ed053175a83b289bab1d1f5931526c4854923dbcec7e43f1 lib/codeql/rust/elements/internal/TupleStructPatConstructor.qll 9d68f67a17a5cec0e78907a53eccfa7696be5b0571da4b486c8184274e56344a 3ffa29f546cd6c644be4fecc7415477a3a4dc00d69b8764be9119abe4c6d8b9e lib/codeql/rust/elements/internal/TupleTypeReprConstructor.qll 80c31c25fd27e330690fb500d757a4bbd33f226186d88ea73bfe4cf29a7db508 d572a72fa361990a3d0a3f9b81d1e966e2ba1ac0a60314ec824c1b8b2814c857 lib/codeql/rust/elements/internal/TupleTypeReprImpl.qll daf679e3cac0eaf1c20880b49b22bbe0822a27cc6ab2c241916b4bf6da995586 ebd87d7fce7d8acd7fa37c4107f8210e60412dd418104bd9fdbdbcde13c8b6a7 diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index 43819916ce08..a10f0277198c 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -419,7 +419,6 @@ /lib/codeql/rust/elements/internal/TupleFieldListConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/TupleFieldListImpl.qll linguist-generated /lib/codeql/rust/elements/internal/TuplePatConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/TuplePatImpl.qll linguist-generated /lib/codeql/rust/elements/internal/TupleStructPatConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/TupleTypeReprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/TupleTypeReprImpl.qll linguist-generated diff --git a/rust/ql/lib/codeql/rust/elements/internal/TuplePatImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/TuplePatImpl.qll index 93f5b79c8208..ac9a723b6e13 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/TuplePatImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/TuplePatImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `TuplePat`. * @@ -12,6 +11,9 @@ private import codeql.rust.elements.internal.generated.TuplePat * be referenced directly. */ module Impl { + private import rust + + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A tuple pattern. For example: * ```rust @@ -19,5 +21,15 @@ module Impl { * let (a, b, .., z) = (1, 2, 3, 4, 5); * ``` */ - class TuplePat extends Generated::TuplePat { } + class TuplePat extends Generated::TuplePat { + /** + * Gets the arity of the tuple matched by this pattern, if any. + * + * This is the number of fields in the tuple pattern if and only if the + * pattern does not contain a `..` pattern. + */ + int getTupleArity() { + result = this.getNumberOfFields() and not this.getAField() instanceof RestPat + } + } } diff --git a/rust/ql/lib/codeql/rust/internal/Type.qll b/rust/ql/lib/codeql/rust/internal/Type.qll index f9db78035348..79f2ad84b18a 100644 --- a/rust/ql/lib/codeql/rust/internal/Type.qll +++ b/rust/ql/lib/codeql/rust/internal/Type.qll @@ -10,7 +10,12 @@ private import codeql.rust.elements.internal.generated.Synth cached newtype TType = TTuple(int arity) { - arity = any(TupleTypeRepr t).getNumberOfFields() and + arity = + [ + any(TupleTypeRepr t).getNumberOfFields(), + any(TupleExpr e).getNumberOfFields(), + any(TuplePat p).getNumberOfFields() + ] and Stages::TypeInferenceStage::ref() } or TStruct(Struct s) or @@ -59,26 +64,11 @@ abstract class Type extends TType { abstract Location getLocation(); } -/** The unit type `()`. */ -class UnitType extends Type, TTuple { - UnitType() { this = TTuple(0) } - - override StructField getStructField(string name) { none() } - - override TupleField getTupleField(int i) { none() } - - override TypeParameter getTypeParameter(int i) { none() } - - override string toString() { result = "()" } - - override Location getLocation() { result instanceof EmptyLocation } -} - /** A tuple type `(T, ...)`. */ class TupleType extends Type, TTuple { private int arity; - TupleType() { this = TTuple(arity) and arity > 0 } + TupleType() { this = TTuple(arity) } override StructField getStructField(string name) { none() } @@ -86,6 +76,7 @@ class TupleType extends Type, TTuple { override TypeParameter getTypeParameter(int i) { result = TTupleTypeParameter(arity, i) } + /** Gets the arity of this tuple type. */ int getArity() { result = arity } override string toString() { result = "(T_" + arity + ")" } @@ -93,6 +84,13 @@ class TupleType extends Type, TTuple { override Location getLocation() { result instanceof EmptyLocation } } +/** The unit type `()`. */ +class UnitType extends TupleType, TTuple { + UnitType() { this = TTuple(0) } + + override string toString() { result = "()" } +} + abstract private class StructOrEnumType extends Type { abstract ItemNode asItemNode(); } @@ -355,8 +353,9 @@ class AssociatedTypeTypeParameter extends TypeParameter, TAssociatedTypeTypePara /** * A tuple type parameter. For instance the `T` in `(T, U)`. * - * Since tuples are structural their parameters can be represented simply as - * their positional index. + * Since tuples are structural their type parameters can be represented as their + * positional index. The type inference library requires that type parameters + * belong to a single type, so we also include the arity of the tuple type. */ class TupleTypeParameter extends TypeParameter, TTupleTypeParameter { private int arity; @@ -371,8 +370,8 @@ class TupleTypeParameter extends TypeParameter, TTupleTypeParameter { /** Gets the index of this tuple type parameter. */ int getIndex() { result = index } - /** Gets the arity of this tuple type parameter. */ - int getArity() { result = arity } + /** Gets the tuple type that corresponds to this tuple type parameter. */ + TupleType getTupleType() { result = TTuple(arity) } } /** An implicit array type parameter. */ diff --git a/rust/ql/lib/codeql/rust/internal/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/TypeInference.qll index 8f2a2ca2ae1c..51e0f3a715ab 100644 --- a/rust/ql/lib/codeql/rust/internal/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/TypeInference.qll @@ -108,7 +108,7 @@ private module Input1 implements InputSig1 { maxArity = max(int i | i = any(TupleType tt).getArity()) and tp0 = ttp and kind = 2 and - id = ttp.getArity() * maxArity + ttp.getIndex() + id = ttp.getTupleType().getArity() * maxArity + ttp.getIndex() ) | tp0 order by kind, id @@ -335,7 +335,7 @@ private predicate typeEquality(AstNode n1, TypePath prefix1, AstNode n2, TypePat arity = n2.(TupleExpr).getNumberOfFields() and n1 = n2.(TupleExpr).getField(i) or - arity = n2.(TuplePat).getNumberOfFields() and + arity = n2.(TuplePat).getTupleArity() and n1 = n2.(TuplePat).getField(i) ) or @@ -553,9 +553,9 @@ private Type inferStructExprType(AstNode n, TypePath path) { } pragma[nomagic] -private Type inferTupleExprRootType(TupleExpr te) { - // `typeEquality` handles the non-root case - result = TTuple(te.getNumberOfFields()) +private Type inferTupleRootType(AstNode n) { + // `typeEquality` handles the non-root cases + result = TTuple([n.(TupleExpr).getNumberOfFields(), n.(TuplePat).getTupleArity()]) } pragma[nomagic] @@ -1091,16 +1091,27 @@ private Type inferTupleIndexExprType(FieldExpr fe, TypePath path) { /** Infers the type of `t` in `t.n` when `t` is a tuple. */ private Type inferTupleContainerExprType(Expr e, TypePath path) { - // NOTE: For a field expression `t.n` where `n` is a number `t` might both be - // a tuple struct or a tuple. It is only correct to let type information flow - // from `t.n` to tuple type parameters of `t` in the latter case. Hence we - // include the condition that the root type of `t` must be a tuple type. + // NOTE: For a field expression `t.n` where `n` is a number `t` might be a + // tuple as in: + // ```rust + // let t = (Default::default(), 2); + // let s: String = t.0; + // ``` + // But it could also be a tuple struct as in: + // ```rust + // struct T(String, u32); + // let t = T(Default::default(), 2); + // let s: String = t.0; + // ``` + // We need type information to flow from `t.n` to tuple type parameters of `t` + // in the former case but not the latter case. Hence we include the condition + // that the root type of `t` must be a tuple type. exists(int i, TypePath path0, FieldExpr fe, int arity | e = fe.getContainer() and fe.getIdentifier().getText() = i.toString() and arity = inferType(fe.getContainer()).(TupleType).getArity() and result = inferType(fe, path0) and - path = TypePath::cons(TTupleTypeParameter(arity, i), path0) // FIXME: + path = TypePath::cons(TTupleTypeParameter(arity, i), path0) ) } @@ -1992,7 +2003,7 @@ private module Cached { or result = inferStructExprType(n, path) or - result = inferTupleExprRootType(n) and + result = inferTupleRootType(n) and path.isEmpty() or result = inferPathExprType(n, path) diff --git a/rust/ql/test/library-tests/type-inference/main.rs b/rust/ql/test/library-tests/type-inference/main.rs index 03efbfc9b4ff..a8bb332a08f0 100644 --- a/rust/ql/test/library-tests/type-inference/main.rs +++ b/rust/ql/test/library-tests/type-inference/main.rs @@ -2357,6 +2357,13 @@ mod tuples { let pair = (a, b); // $ type=pair:0(2).i64 type=pair:1(2).bool let i: i64 = pair.0; let j: bool = pair.1; + + let pair = [1, 1].into(); // $ type=pair:0(2).i32 MISSING: target=into + match pair { + (0,0) => print!("unexpected"), + _ => print!("expected"), + } + let x = pair.0; // $ type=x:i32 } } diff --git a/rust/ql/test/library-tests/type-inference/pattern_matching.rs b/rust/ql/test/library-tests/type-inference/pattern_matching.rs index 396428eedc0f..28da3e1ab580 100755 --- a/rust/ql/test/library-tests/type-inference/pattern_matching.rs +++ b/rust/ql/test/library-tests/type-inference/pattern_matching.rs @@ -704,7 +704,7 @@ pub fn complex_nested_patterns() { } // Catch-all with identifier pattern other => { - let other_complex = other; // $ MISSING: type=other_complex:? + let other_complex = other; // $ type=other_complex:0(2).Point type=other_complex:1(2).MyOption println!("Other complex data: {:?}", other_complex); } } @@ -766,7 +766,7 @@ pub fn patterns_in_function_parameters() { // Call the functions to use them let point = Point { x: 5, y: 10 }; - let extracted = extract_point(point); // $ target=extract_point MISSING: type=extracted:? + let extracted = extract_point(point); // $ target=extract_point type=extracted:0(2).i32 type=extracted:1(2).i32 let color = Color(200, 100, 50); let red = extract_color(color); // $ target=extract_color type=red:u8 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 b6f5e24244d6..e7c8467f0ae6 100644 --- a/rust/ql/test/library-tests/type-inference/type-inference.expected +++ b/rust/ql/test/library-tests/type-inference/type-inference.expected @@ -4172,96 +4172,130 @@ inferType | main.rs:2359:23:2359:26 | pair | 0(2) | {EXTERNAL LOCATION} | i64 | | main.rs:2359:23:2359:26 | pair | 1(2) | {EXTERNAL LOCATION} | bool | | main.rs:2359:23:2359:28 | pair.1 | | {EXTERNAL LOCATION} | bool | -| main.rs:2366:13:2366:23 | boxed_value | | {EXTERNAL LOCATION} | Box | -| main.rs:2366:13:2366:23 | boxed_value | A | {EXTERNAL LOCATION} | Global | -| main.rs:2366:13:2366:23 | boxed_value | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2366:27:2366:42 | ...::new(...) | | {EXTERNAL LOCATION} | Box | -| main.rs:2366:27:2366:42 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | -| main.rs:2366:27:2366:42 | ...::new(...) | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2366:36:2366:41 | 100i32 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2369:15:2369:25 | boxed_value | | {EXTERNAL LOCATION} | Box | -| main.rs:2369:15:2369:25 | boxed_value | A | {EXTERNAL LOCATION} | Global | -| main.rs:2369:15:2369:25 | boxed_value | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2370:13:2370:19 | box 100 | | {EXTERNAL LOCATION} | Box | -| main.rs:2370:13:2370:19 | box 100 | A | {EXTERNAL LOCATION} | Global | -| main.rs:2370:13:2370:19 | box 100 | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2370:17:2370:19 | 100 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2371:26:2371:36 | "Boxed 100\\n" | | file://:0:0:0:0 | & | -| main.rs:2371:26:2371:36 | "Boxed 100\\n" | &T | {EXTERNAL LOCATION} | str | -| main.rs:2371:26:2371:36 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | -| main.rs:2371:26:2371:36 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | -| main.rs:2373:13:2373:17 | box ... | | {EXTERNAL LOCATION} | Box | -| main.rs:2373:13:2373:17 | box ... | A | {EXTERNAL LOCATION} | Global | -| main.rs:2373:13:2373:17 | box ... | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2375:26:2375:42 | "Boxed value: {}\\n" | | file://:0:0:0:0 | & | -| main.rs:2375:26:2375:42 | "Boxed value: {}\\n" | &T | {EXTERNAL LOCATION} | str | -| main.rs:2375:26:2375:51 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | -| main.rs:2375:26:2375:51 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | -| main.rs:2380:13:2380:22 | nested_box | | {EXTERNAL LOCATION} | Box | -| main.rs:2380:13:2380:22 | nested_box | A | {EXTERNAL LOCATION} | Global | -| main.rs:2380:13:2380:22 | nested_box | T | {EXTERNAL LOCATION} | Box | -| main.rs:2380:13:2380:22 | nested_box | T.A | {EXTERNAL LOCATION} | Global | -| main.rs:2380:13:2380:22 | nested_box | T.T | {EXTERNAL LOCATION} | i32 | -| main.rs:2380:26:2380:50 | ...::new(...) | | {EXTERNAL LOCATION} | Box | -| main.rs:2380:26:2380:50 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | -| main.rs:2380:26:2380:50 | ...::new(...) | T | {EXTERNAL LOCATION} | Box | -| main.rs:2380:26:2380:50 | ...::new(...) | T.A | {EXTERNAL LOCATION} | Global | -| main.rs:2380:26:2380:50 | ...::new(...) | T.T | {EXTERNAL LOCATION} | i32 | -| main.rs:2380:35:2380:49 | ...::new(...) | | {EXTERNAL LOCATION} | Box | -| main.rs:2380:35:2380:49 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | -| main.rs:2380:35:2380:49 | ...::new(...) | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2380:44:2380:48 | 42i32 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2381:15:2381:24 | nested_box | | {EXTERNAL LOCATION} | Box | -| main.rs:2381:15:2381:24 | nested_box | A | {EXTERNAL LOCATION} | Global | -| main.rs:2381:15:2381:24 | nested_box | T | {EXTERNAL LOCATION} | Box | -| main.rs:2381:15:2381:24 | nested_box | T.A | {EXTERNAL LOCATION} | Global | -| main.rs:2381:15:2381:24 | nested_box | T.T | {EXTERNAL LOCATION} | i32 | -| main.rs:2382:13:2382:21 | box ... | | {EXTERNAL LOCATION} | Box | -| main.rs:2382:13:2382:21 | box ... | A | {EXTERNAL LOCATION} | Global | -| main.rs:2382:13:2382:21 | box ... | T | {EXTERNAL LOCATION} | Box | -| main.rs:2382:13:2382:21 | box ... | T.A | {EXTERNAL LOCATION} | Global | -| main.rs:2382:13:2382:21 | box ... | T.T | {EXTERNAL LOCATION} | i32 | -| main.rs:2384:26:2384:43 | "Nested boxed: {}\\n" | | file://:0:0:0:0 | & | -| main.rs:2384:26:2384:43 | "Nested boxed: {}\\n" | &T | {EXTERNAL LOCATION} | str | -| main.rs:2384:26:2384:59 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | -| main.rs:2384:26:2384:59 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | -| main.rs:2396:16:2396:20 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:2396:16:2396:20 | SelfParam | &T | main.rs:2391:5:2393:5 | Row | -| main.rs:2396:30:2398:9 | { ... } | | {EXTERNAL LOCATION} | i64 | -| main.rs:2397:13:2397:16 | self | | file://:0:0:0:0 | & | -| main.rs:2397:13:2397:16 | self | &T | main.rs:2391:5:2393:5 | Row | -| main.rs:2397:13:2397:21 | self.data | | {EXTERNAL LOCATION} | i64 | -| main.rs:2406:26:2408:9 | { ... } | | main.rs:2401:5:2403:5 | Table | -| main.rs:2407:13:2407:38 | Table {...} | | main.rs:2401:5:2403:5 | Table | -| main.rs:2407:27:2407:36 | ...::new(...) | | {EXTERNAL LOCATION} | Vec | -| main.rs:2407:27:2407:36 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | -| main.rs:2407:27:2407:36 | ...::new(...) | T | main.rs:2391:5:2393:5 | Row | -| main.rs:2410:23:2410:27 | SelfParam | | file://:0:0:0:0 | & | -| main.rs:2410:23:2410:27 | SelfParam | &T | main.rs:2401:5:2403:5 | Table | -| main.rs:2410:30:2410:37 | property | | main.rs:2410:40:2410:59 | ImplTraitTypeRepr | -| main.rs:2410:69:2412:9 | { ... } | | {EXTERNAL LOCATION} | i32 | -| main.rs:2410:69:2412:9 | { ... } | | {EXTERNAL LOCATION} | i64 | -| main.rs:2411:13:2411:13 | 0 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2411:13:2411:13 | 0 | | {EXTERNAL LOCATION} | i64 | -| main.rs:2416:9:2416:15 | Some(...) | | {EXTERNAL LOCATION} | Option | -| main.rs:2416:9:2416:15 | Some(...) | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2416:9:2419:10 | ... .map(...) | | {EXTERNAL LOCATION} | Option | -| main.rs:2416:14:2416:14 | 1 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2418:22:2418:26 | "{x}\\n" | | file://:0:0:0:0 | & | -| main.rs:2418:22:2418:26 | "{x}\\n" | &T | {EXTERNAL LOCATION} | str | -| main.rs:2418:22:2418:26 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | -| main.rs:2418:22:2418:26 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | -| main.rs:2421:13:2421:17 | table | | main.rs:2401:5:2403:5 | Table | -| main.rs:2421:21:2421:32 | ...::new(...) | | main.rs:2401:5:2403:5 | Table | -| main.rs:2422:13:2422:18 | result | | {EXTERNAL LOCATION} | i64 | -| main.rs:2422:22:2422:26 | table | | main.rs:2401:5:2403:5 | Table | -| main.rs:2422:22:2426:14 | table.count_with(...) | | {EXTERNAL LOCATION} | i64 | -| main.rs:2425:21:2425:21 | 0 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2432:5:2432:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo | -| main.rs:2433:5:2433:60 | ...::g(...) | | main.rs:72:5:72:21 | Foo | -| main.rs:2433:20:2433:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | -| main.rs:2433:41:2433:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | -| main.rs:2449:5:2449:15 | ...::f(...) | | {EXTERNAL LOCATION} | trait Future | +| main.rs:2361:13:2361:16 | pair | | file://:0:0:0:0 | (T_2) | +| main.rs:2361:13:2361:16 | pair | 0(2) | {EXTERNAL LOCATION} | i32 | +| main.rs:2361:13:2361:16 | pair | 1(2) | {EXTERNAL LOCATION} | i32 | +| main.rs:2361:20:2361:25 | [...] | | file://:0:0:0:0 | [] | +| main.rs:2361:20:2361:25 | [...] | [T;...] | {EXTERNAL LOCATION} | i32 | +| main.rs:2361:20:2361:32 | ... .into() | | file://:0:0:0:0 | (T_2) | +| main.rs:2361:20:2361:32 | ... .into() | 0(2) | {EXTERNAL LOCATION} | i32 | +| main.rs:2361:20:2361:32 | ... .into() | 1(2) | {EXTERNAL LOCATION} | i32 | +| main.rs:2361:21:2361:21 | 1 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2361:24:2361:24 | 1 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2362:15:2362:18 | pair | | file://:0:0:0:0 | (T_2) | +| main.rs:2362:15:2362:18 | pair | 0(2) | {EXTERNAL LOCATION} | i32 | +| main.rs:2362:15:2362:18 | pair | 1(2) | {EXTERNAL LOCATION} | i32 | +| main.rs:2363:13:2363:17 | TuplePat | | file://:0:0:0:0 | (T_2) | +| main.rs:2363:13:2363:17 | TuplePat | 0(2) | {EXTERNAL LOCATION} | i32 | +| main.rs:2363:13:2363:17 | TuplePat | 1(2) | {EXTERNAL LOCATION} | i32 | +| main.rs:2363:14:2363:14 | 0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2363:16:2363:16 | 0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2363:29:2363:40 | "unexpected" | | file://:0:0:0:0 | & | +| main.rs:2363:29:2363:40 | "unexpected" | &T | {EXTERNAL LOCATION} | str | +| main.rs:2363:29:2363:40 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2363:29:2363:40 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2364:13:2364:13 | _ | | file://:0:0:0:0 | (T_2) | +| main.rs:2364:13:2364:13 | _ | 0(2) | {EXTERNAL LOCATION} | i32 | +| main.rs:2364:13:2364:13 | _ | 1(2) | {EXTERNAL LOCATION} | i32 | +| main.rs:2364:25:2364:34 | "expected" | | file://:0:0:0:0 | & | +| main.rs:2364:25:2364:34 | "expected" | &T | {EXTERNAL LOCATION} | str | +| main.rs:2364:25:2364:34 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2364:25:2364:34 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2366:13:2366:13 | x | | {EXTERNAL LOCATION} | i32 | +| main.rs:2366:17:2366:20 | pair | | file://:0:0:0:0 | (T_2) | +| main.rs:2366:17:2366:20 | pair | 0(2) | {EXTERNAL LOCATION} | i32 | +| main.rs:2366:17:2366:20 | pair | 1(2) | {EXTERNAL LOCATION} | i32 | +| main.rs:2366:17:2366:22 | pair.0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2373:13:2373:23 | boxed_value | | {EXTERNAL LOCATION} | Box | +| main.rs:2373:13:2373:23 | boxed_value | A | {EXTERNAL LOCATION} | Global | +| main.rs:2373:13:2373:23 | boxed_value | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2373:27:2373:42 | ...::new(...) | | {EXTERNAL LOCATION} | Box | +| main.rs:2373:27:2373:42 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | +| main.rs:2373:27:2373:42 | ...::new(...) | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2373:36:2373:41 | 100i32 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2376:15:2376:25 | boxed_value | | {EXTERNAL LOCATION} | Box | +| main.rs:2376:15:2376:25 | boxed_value | A | {EXTERNAL LOCATION} | Global | +| main.rs:2376:15:2376:25 | boxed_value | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2377:13:2377:19 | box 100 | | {EXTERNAL LOCATION} | Box | +| main.rs:2377:13:2377:19 | box 100 | A | {EXTERNAL LOCATION} | Global | +| main.rs:2377:13:2377:19 | box 100 | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2377:17:2377:19 | 100 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2378:26:2378:36 | "Boxed 100\\n" | | file://:0:0:0:0 | & | +| main.rs:2378:26:2378:36 | "Boxed 100\\n" | &T | {EXTERNAL LOCATION} | str | +| main.rs:2378:26:2378:36 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2378:26:2378:36 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2380:13:2380:17 | box ... | | {EXTERNAL LOCATION} | Box | +| main.rs:2380:13:2380:17 | box ... | A | {EXTERNAL LOCATION} | Global | +| main.rs:2380:13:2380:17 | box ... | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2382:26:2382:42 | "Boxed value: {}\\n" | | file://:0:0:0:0 | & | +| main.rs:2382:26:2382:42 | "Boxed value: {}\\n" | &T | {EXTERNAL LOCATION} | str | +| main.rs:2382:26:2382:51 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2382:26:2382:51 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2387:13:2387:22 | nested_box | | {EXTERNAL LOCATION} | Box | +| main.rs:2387:13:2387:22 | nested_box | A | {EXTERNAL LOCATION} | Global | +| main.rs:2387:13:2387:22 | nested_box | T | {EXTERNAL LOCATION} | Box | +| main.rs:2387:13:2387:22 | nested_box | T.A | {EXTERNAL LOCATION} | Global | +| main.rs:2387:13:2387:22 | nested_box | T.T | {EXTERNAL LOCATION} | i32 | +| main.rs:2387:26:2387:50 | ...::new(...) | | {EXTERNAL LOCATION} | Box | +| main.rs:2387:26:2387:50 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | +| main.rs:2387:26:2387:50 | ...::new(...) | T | {EXTERNAL LOCATION} | Box | +| main.rs:2387:26:2387:50 | ...::new(...) | T.A | {EXTERNAL LOCATION} | Global | +| main.rs:2387:26:2387:50 | ...::new(...) | T.T | {EXTERNAL LOCATION} | i32 | +| main.rs:2387:35:2387:49 | ...::new(...) | | {EXTERNAL LOCATION} | Box | +| main.rs:2387:35:2387:49 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | +| main.rs:2387:35:2387:49 | ...::new(...) | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2387:44:2387:48 | 42i32 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2388:15:2388:24 | nested_box | | {EXTERNAL LOCATION} | Box | +| main.rs:2388:15:2388:24 | nested_box | A | {EXTERNAL LOCATION} | Global | +| main.rs:2388:15:2388:24 | nested_box | T | {EXTERNAL LOCATION} | Box | +| main.rs:2388:15:2388:24 | nested_box | T.A | {EXTERNAL LOCATION} | Global | +| main.rs:2388:15:2388:24 | nested_box | T.T | {EXTERNAL LOCATION} | i32 | +| main.rs:2389:13:2389:21 | box ... | | {EXTERNAL LOCATION} | Box | +| main.rs:2389:13:2389:21 | box ... | A | {EXTERNAL LOCATION} | Global | +| main.rs:2389:13:2389:21 | box ... | T | {EXTERNAL LOCATION} | Box | +| main.rs:2389:13:2389:21 | box ... | T.A | {EXTERNAL LOCATION} | Global | +| main.rs:2389:13:2389:21 | box ... | T.T | {EXTERNAL LOCATION} | i32 | +| main.rs:2391:26:2391:43 | "Nested boxed: {}\\n" | | file://:0:0:0:0 | & | +| main.rs:2391:26:2391:43 | "Nested boxed: {}\\n" | &T | {EXTERNAL LOCATION} | str | +| main.rs:2391:26:2391:59 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2391:26:2391:59 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2403:16:2403:20 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:2403:16:2403:20 | SelfParam | &T | main.rs:2398:5:2400:5 | Row | +| main.rs:2403:30:2405:9 | { ... } | | {EXTERNAL LOCATION} | i64 | +| main.rs:2404:13:2404:16 | self | | file://:0:0:0:0 | & | +| main.rs:2404:13:2404:16 | self | &T | main.rs:2398:5:2400:5 | Row | +| main.rs:2404:13:2404:21 | self.data | | {EXTERNAL LOCATION} | i64 | +| main.rs:2413:26:2415:9 | { ... } | | main.rs:2408:5:2410:5 | Table | +| main.rs:2414:13:2414:38 | Table {...} | | main.rs:2408:5:2410:5 | Table | +| main.rs:2414:27:2414:36 | ...::new(...) | | {EXTERNAL LOCATION} | Vec | +| main.rs:2414:27:2414:36 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | +| main.rs:2414:27:2414:36 | ...::new(...) | T | main.rs:2398:5:2400:5 | Row | +| main.rs:2417:23:2417:27 | SelfParam | | file://:0:0:0:0 | & | +| main.rs:2417:23:2417:27 | SelfParam | &T | main.rs:2408:5:2410:5 | Table | +| main.rs:2417:30:2417:37 | property | | main.rs:2417:40:2417:59 | ImplTraitTypeRepr | +| main.rs:2417:69:2419:9 | { ... } | | {EXTERNAL LOCATION} | i32 | +| main.rs:2417:69:2419:9 | { ... } | | {EXTERNAL LOCATION} | i64 | +| main.rs:2418:13:2418:13 | 0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2418:13:2418:13 | 0 | | {EXTERNAL LOCATION} | i64 | +| main.rs:2423:9:2423:15 | Some(...) | | {EXTERNAL LOCATION} | Option | +| main.rs:2423:9:2423:15 | Some(...) | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2423:9:2426:10 | ... .map(...) | | {EXTERNAL LOCATION} | Option | +| main.rs:2423:14:2423:14 | 1 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2425:22:2425:26 | "{x}\\n" | | file://:0:0:0:0 | & | +| main.rs:2425:22:2425:26 | "{x}\\n" | &T | {EXTERNAL LOCATION} | str | +| main.rs:2425:22:2425:26 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2425:22:2425:26 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | +| main.rs:2428:13:2428:17 | table | | main.rs:2408:5:2410:5 | Table | +| main.rs:2428:21:2428:32 | ...::new(...) | | main.rs:2408:5:2410:5 | Table | +| main.rs:2429:13:2429:18 | result | | {EXTERNAL LOCATION} | i64 | +| main.rs:2429:22:2429:26 | table | | main.rs:2408:5:2410:5 | Table | +| main.rs:2429:22:2433:14 | table.count_with(...) | | {EXTERNAL LOCATION} | i64 | +| main.rs:2432:21:2432:21 | 0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2439:5:2439:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo | +| main.rs:2440:5:2440:60 | ...::g(...) | | main.rs:72:5:72:21 | Foo | +| main.rs:2440:20:2440:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | +| main.rs:2440:41:2440:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | +| main.rs:2456:5:2456:15 | ...::f(...) | | {EXTERNAL LOCATION} | trait Future | | pattern_matching.rs:13:26:133:1 | { ... } | | {EXTERNAL LOCATION} | Option | | pattern_matching.rs:13:26:133:1 | { ... } | T | file://:0:0:0:0 | () | | pattern_matching.rs:14:9:14:13 | value | | {EXTERNAL LOCATION} | Option | From bbd7ed57ced01d2f60f000a634eb9c367c493c77 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 16 Jul 2025 12:32:35 +0200 Subject: [PATCH 7/8] Rust: Add inline expectation --- rust/ql/test/library-tests/type-inference/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/test/library-tests/type-inference/main.rs b/rust/ql/test/library-tests/type-inference/main.rs index a8bb332a08f0..ae29e0515bdb 100644 --- a/rust/ql/test/library-tests/type-inference/main.rs +++ b/rust/ql/test/library-tests/type-inference/main.rs @@ -2358,7 +2358,7 @@ mod tuples { let i: i64 = pair.0; let j: bool = pair.1; - let pair = [1, 1].into(); // $ type=pair:0(2).i32 MISSING: target=into + let pair = [1, 1].into(); // $ type=pair:0(2).i32 type=pair:1(2).i32 MISSING: target=into match pair { (0,0) => print!("unexpected"), _ => print!("expected"), From 7f8829ad8ea2ab5e700f45f0abec86cd77ac6c67 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 16 Jul 2025 14:00:27 +0200 Subject: [PATCH 8/8] Rust: Add additional inline expectation Co-authored-by: Arthur Baars --- rust/ql/test/library-tests/type-inference/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/test/library-tests/type-inference/main.rs b/rust/ql/test/library-tests/type-inference/main.rs index ae29e0515bdb..f1a961522440 100644 --- a/rust/ql/test/library-tests/type-inference/main.rs +++ b/rust/ql/test/library-tests/type-inference/main.rs @@ -2358,7 +2358,7 @@ mod tuples { let i: i64 = pair.0; let j: bool = pair.1; - let pair = [1, 1].into(); // $ type=pair:0(2).i32 type=pair:1(2).i32 MISSING: target=into + let pair = [1, 1].into(); // $ type=pair:(T_2) type=pair:0(2).i32 type=pair:1(2).i32 MISSING: target=into match pair { (0,0) => print!("unexpected"), _ => print!("expected"), pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy