Skip to content

Commit fe1b663

Browse files
committed
Rust: Model [T;n] -> [T] unsized coercion in type inference
1 parent f8a0343 commit fe1b663

3 files changed

Lines changed: 55 additions & 19 deletions

File tree

rust/ql/test/library-tests/type-inference/main.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,7 +1412,7 @@ mod builtins {
14121412

14131413
impl<T: Default, const N: usize> MyTrait<T> for [T; N] {
14141414
fn my_method(&self) -> &T {
1415-
self.get(0).unwrap() // $ MISSING: target=get target=unwrap
1415+
self.get(0).unwrap() // $ target=get target=unwrap
14161416
}
14171417

14181418
fn my_func() -> T {
@@ -2340,16 +2340,16 @@ mod loops {
23402340
let vals3 = vec![1, 2, 3]; // $ type=vals3:Vec $ MISSING: type=vals3@Vec<T>:i32
23412341
for i in vals3 {} // $ MISSING: type=i:i32
23422342

2343-
let vals4a: Vec<u16> = [1u16, 2, 3].to_vec(); // $ certainType=vals4a@Vec<T>:u16
2343+
let vals4a = [1u16, 2, 3].to_vec(); // $ type=vals4a@Vec<T>:u16 target=to_vec
23442344
for u in vals4a {} // $ type=u:u16
23452345

2346-
let vals4b = [1u16, 2, 3].to_vec(); // $ MISSING: type=vals4b:Vec type=vals4b@Vec<T>:u16
2347-
for u in vals4b {} // $ MISSING: type=u:u16
2346+
let vals4b = [1u16, 2, 3].to_vec(); // $ type=vals4b@Vec<T>:u16 target=to_vec
2347+
for u in vals4b {} // $ type=u:u16
23482348

23492349
let vals5 = Vec::from([1u32, 2, 3]); // $ target=from type=vals5@Vec<T>:u32
23502350
for u in vals5 {} // $ type=u:u32
23512351

2352-
let vals6: Vec<&u64> = [1u64, 2, 3].iter().collect(); // $ certainType=vals6@Vec<T>.&<TRef>:u64
2352+
let vals6: Vec<&u64> = [1u64, 2, 3].iter().collect(); // $ certainType=vals6@Vec<T>.&<TRef>:u64 target=iter target=collect
23532353
for u in vals6 {} // $ type=u@&<TRef>:u64
23542354

23552355
let mut vals7 = Vec::new(); // $ target=new type=vals7@Vec<T>:u8

rust/ql/test/library-tests/type-inference/type-inference.expected

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3455,15 +3455,9 @@ inferCertainType
34553455
| main.rs:2336:25:2336:26 | { ... } | | {EXTERNAL LOCATION} | () |
34563456
| main.rs:2341:9:2341:25 | for ... in ... { ... } | | {EXTERNAL LOCATION} | () |
34573457
| main.rs:2341:24:2341:25 | { ... } | | {EXTERNAL LOCATION} | () |
3458-
| main.rs:2343:13:2343:18 | vals4a | | {EXTERNAL LOCATION} | Vec |
3459-
| main.rs:2343:13:2343:18 | vals4a | A | {EXTERNAL LOCATION} | Global |
3460-
| main.rs:2343:13:2343:18 | vals4a | T | {EXTERNAL LOCATION} | u16 |
3461-
| main.rs:2343:32:2343:43 | [...] | | {EXTERNAL LOCATION} | [;] |
3462-
| main.rs:2343:33:2343:36 | 1u16 | | {EXTERNAL LOCATION} | u16 |
3458+
| main.rs:2343:22:2343:33 | [...] | | {EXTERNAL LOCATION} | [;] |
3459+
| main.rs:2343:23:2343:26 | 1u16 | | {EXTERNAL LOCATION} | u16 |
34633460
| main.rs:2344:9:2344:26 | for ... in ... { ... } | | {EXTERNAL LOCATION} | () |
3464-
| main.rs:2344:18:2344:23 | vals4a | | {EXTERNAL LOCATION} | Vec |
3465-
| main.rs:2344:18:2344:23 | vals4a | A | {EXTERNAL LOCATION} | Global |
3466-
| main.rs:2344:18:2344:23 | vals4a | T | {EXTERNAL LOCATION} | u16 |
34673461
| main.rs:2344:25:2344:26 | { ... } | | {EXTERNAL LOCATION} | () |
34683462
| main.rs:2346:22:2346:33 | [...] | | {EXTERNAL LOCATION} | [;] |
34693463
| main.rs:2346:23:2346:26 | 1u16 | | {EXTERNAL LOCATION} | u16 |
@@ -9887,9 +9881,13 @@ inferType
98879881
| main.rs:1414:26:1414:30 | SelfParam | | {EXTERNAL LOCATION} | & |
98889882
| main.rs:1414:26:1414:30 | SelfParam | TRef | {EXTERNAL LOCATION} | [;] |
98899883
| main.rs:1414:26:1414:30 | SelfParam | TRef.TArray | main.rs:1413:14:1413:23 | T |
9884+
| main.rs:1414:39:1416:13 | { ... } | | {EXTERNAL LOCATION} | & |
98909885
| main.rs:1415:17:1415:20 | self | | {EXTERNAL LOCATION} | & |
98919886
| main.rs:1415:17:1415:20 | self | TRef | {EXTERNAL LOCATION} | [;] |
98929887
| main.rs:1415:17:1415:20 | self | TRef.TArray | main.rs:1413:14:1413:23 | T |
9888+
| main.rs:1415:17:1415:27 | self.get(...) | | {EXTERNAL LOCATION} | Option |
9889+
| main.rs:1415:17:1415:27 | self.get(...) | T | {EXTERNAL LOCATION} | & |
9890+
| main.rs:1415:17:1415:36 | ... .unwrap() | | {EXTERNAL LOCATION} | & |
98939891
| main.rs:1415:26:1415:26 | 0 | | {EXTERNAL LOCATION} | i32 |
98949892
| main.rs:1418:31:1420:13 | { ... } | | main.rs:1413:14:1413:23 | T |
98959893
| main.rs:1419:17:1419:28 | ...::default(...) | | main.rs:1413:14:1413:23 | T |
@@ -11563,26 +11561,47 @@ inferType
1156311561
| main.rs:2341:24:2341:25 | { ... } | | {EXTERNAL LOCATION} | () |
1156411562
| main.rs:2343:13:2343:18 | vals4a | | {EXTERNAL LOCATION} | Vec |
1156511563
| main.rs:2343:13:2343:18 | vals4a | A | {EXTERNAL LOCATION} | Global |
11564+
| main.rs:2343:13:2343:18 | vals4a | T | {EXTERNAL LOCATION} | i32 |
1156611565
| main.rs:2343:13:2343:18 | vals4a | T | {EXTERNAL LOCATION} | u16 |
11567-
| main.rs:2343:32:2343:43 | [...] | | {EXTERNAL LOCATION} | [;] |
11568-
| main.rs:2343:32:2343:43 | [...] | TArray | {EXTERNAL LOCATION} | i32 |
11569-
| main.rs:2343:32:2343:43 | [...] | TArray | {EXTERNAL LOCATION} | u16 |
11570-
| main.rs:2343:33:2343:36 | 1u16 | | {EXTERNAL LOCATION} | u16 |
11571-
| main.rs:2343:39:2343:39 | 2 | | {EXTERNAL LOCATION} | i32 |
11572-
| main.rs:2343:42:2343:42 | 3 | | {EXTERNAL LOCATION} | i32 |
11566+
| main.rs:2343:22:2343:33 | [...] | | {EXTERNAL LOCATION} | [;] |
11567+
| main.rs:2343:22:2343:33 | [...] | TArray | {EXTERNAL LOCATION} | i32 |
11568+
| main.rs:2343:22:2343:33 | [...] | TArray | {EXTERNAL LOCATION} | u16 |
11569+
| main.rs:2343:22:2343:42 | ... .to_vec() | | {EXTERNAL LOCATION} | Vec |
11570+
| main.rs:2343:22:2343:42 | ... .to_vec() | A | {EXTERNAL LOCATION} | Global |
11571+
| main.rs:2343:22:2343:42 | ... .to_vec() | T | {EXTERNAL LOCATION} | i32 |
11572+
| main.rs:2343:22:2343:42 | ... .to_vec() | T | {EXTERNAL LOCATION} | u16 |
11573+
| main.rs:2343:23:2343:26 | 1u16 | | {EXTERNAL LOCATION} | u16 |
11574+
| main.rs:2343:29:2343:29 | 2 | | {EXTERNAL LOCATION} | i32 |
11575+
| main.rs:2343:32:2343:32 | 3 | | {EXTERNAL LOCATION} | i32 |
1157311576
| main.rs:2344:9:2344:26 | for ... in ... { ... } | | {EXTERNAL LOCATION} | () |
11577+
| main.rs:2344:13:2344:13 | u | | {EXTERNAL LOCATION} | i32 |
1157411578
| main.rs:2344:13:2344:13 | u | | {EXTERNAL LOCATION} | u16 |
1157511579
| main.rs:2344:18:2344:23 | vals4a | | {EXTERNAL LOCATION} | Vec |
1157611580
| main.rs:2344:18:2344:23 | vals4a | A | {EXTERNAL LOCATION} | Global |
11581+
| main.rs:2344:18:2344:23 | vals4a | T | {EXTERNAL LOCATION} | i32 |
1157711582
| main.rs:2344:18:2344:23 | vals4a | T | {EXTERNAL LOCATION} | u16 |
1157811583
| main.rs:2344:25:2344:26 | { ... } | | {EXTERNAL LOCATION} | () |
11584+
| main.rs:2346:13:2346:18 | vals4b | | {EXTERNAL LOCATION} | Vec |
11585+
| main.rs:2346:13:2346:18 | vals4b | A | {EXTERNAL LOCATION} | Global |
11586+
| main.rs:2346:13:2346:18 | vals4b | T | {EXTERNAL LOCATION} | i32 |
11587+
| main.rs:2346:13:2346:18 | vals4b | T | {EXTERNAL LOCATION} | u16 |
1157911588
| main.rs:2346:22:2346:33 | [...] | | {EXTERNAL LOCATION} | [;] |
1158011589
| main.rs:2346:22:2346:33 | [...] | TArray | {EXTERNAL LOCATION} | i32 |
1158111590
| main.rs:2346:22:2346:33 | [...] | TArray | {EXTERNAL LOCATION} | u16 |
11591+
| main.rs:2346:22:2346:42 | ... .to_vec() | | {EXTERNAL LOCATION} | Vec |
11592+
| main.rs:2346:22:2346:42 | ... .to_vec() | A | {EXTERNAL LOCATION} | Global |
11593+
| main.rs:2346:22:2346:42 | ... .to_vec() | T | {EXTERNAL LOCATION} | i32 |
11594+
| main.rs:2346:22:2346:42 | ... .to_vec() | T | {EXTERNAL LOCATION} | u16 |
1158211595
| main.rs:2346:23:2346:26 | 1u16 | | {EXTERNAL LOCATION} | u16 |
1158311596
| main.rs:2346:29:2346:29 | 2 | | {EXTERNAL LOCATION} | i32 |
1158411597
| main.rs:2346:32:2346:32 | 3 | | {EXTERNAL LOCATION} | i32 |
1158511598
| main.rs:2347:9:2347:26 | for ... in ... { ... } | | {EXTERNAL LOCATION} | () |
11599+
| main.rs:2347:13:2347:13 | u | | {EXTERNAL LOCATION} | i32 |
11600+
| main.rs:2347:13:2347:13 | u | | {EXTERNAL LOCATION} | u16 |
11601+
| main.rs:2347:18:2347:23 | vals4b | | {EXTERNAL LOCATION} | Vec |
11602+
| main.rs:2347:18:2347:23 | vals4b | A | {EXTERNAL LOCATION} | Global |
11603+
| main.rs:2347:18:2347:23 | vals4b | T | {EXTERNAL LOCATION} | i32 |
11604+
| main.rs:2347:18:2347:23 | vals4b | T | {EXTERNAL LOCATION} | u16 |
1158611605
| main.rs:2347:25:2347:26 | { ... } | | {EXTERNAL LOCATION} | () |
1158711606
| main.rs:2349:13:2349:17 | vals5 | | {EXTERNAL LOCATION} | Vec |
1158811607
| main.rs:2349:13:2349:17 | vals5 | A | {EXTERNAL LOCATION} | Global |
@@ -11613,6 +11632,14 @@ inferType
1161311632
| main.rs:2352:32:2352:43 | [...] | | {EXTERNAL LOCATION} | [;] |
1161411633
| main.rs:2352:32:2352:43 | [...] | TArray | {EXTERNAL LOCATION} | i32 |
1161511634
| main.rs:2352:32:2352:43 | [...] | TArray | {EXTERNAL LOCATION} | u64 |
11635+
| main.rs:2352:32:2352:50 | ... .iter() | | {EXTERNAL LOCATION} | Iter |
11636+
| main.rs:2352:32:2352:50 | ... .iter() | T | {EXTERNAL LOCATION} | i32 |
11637+
| main.rs:2352:32:2352:50 | ... .iter() | T | {EXTERNAL LOCATION} | u64 |
11638+
| main.rs:2352:32:2352:60 | ... .collect() | | {EXTERNAL LOCATION} | Vec |
11639+
| main.rs:2352:32:2352:60 | ... .collect() | A | {EXTERNAL LOCATION} | Global |
11640+
| main.rs:2352:32:2352:60 | ... .collect() | T | {EXTERNAL LOCATION} | & |
11641+
| main.rs:2352:32:2352:60 | ... .collect() | T.TRef | {EXTERNAL LOCATION} | i32 |
11642+
| main.rs:2352:32:2352:60 | ... .collect() | T.TRef | {EXTERNAL LOCATION} | u64 |
1161611643
| main.rs:2352:33:2352:36 | 1u64 | | {EXTERNAL LOCATION} | u64 |
1161711644
| main.rs:2352:39:2352:39 | 2 | | {EXTERNAL LOCATION} | i32 |
1161811645
| main.rs:2352:42:2352:42 | 3 | | {EXTERNAL LOCATION} | i32 |

rust/tools/builtins/types.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,12 @@ struct Tuple12<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(
7070
T10,
7171
T11,
7272
);
73+
74+
// model unsized coercion (https://doc.rust-lang.org/reference/type-coercions.html#r-coerce.unsize.slice)
75+
// as a `Deref` implementation in order to reuse type inference logic
76+
impl<T,const N: usize> std::ops::Deref for Array<T,N> {
77+
type Target = Slice<T>;
78+
fn deref(&self) -> &Slice<T> {
79+
// not a real implementation
80+
}
81+
}

0 commit comments

Comments
 (0)