aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/tests/coercion.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/tests/coercion.rs')
-rw-r--r--crates/hir_ty/src/tests/coercion.rs673
1 files changed, 119 insertions, 554 deletions
diff --git a/crates/hir_ty/src/tests/coercion.rs b/crates/hir_ty/src/tests/coercion.rs
index 713b74165..87089f09d 100644
--- a/crates/hir_ty/src/tests/coercion.rs
+++ b/crates/hir_ty/src/tests/coercion.rs
@@ -1,27 +1,22 @@
1use expect_test::expect; 1use super::{check, check_no_mismatches, check_types};
2
3use super::{check_infer, check_infer_with_mismatches, check_no_mismatches, check_types};
4 2
5#[test] 3#[test]
6fn infer_block_expr_type_mismatch() { 4fn block_expr_type_mismatch() {
7 check_infer( 5 // FIXME fix double type mismatch
6 check(
8 r" 7 r"
9 fn test() { 8fn test() {
10 let a: i32 = { 1i64 }; 9 let a: i32 = { 1i64 };
11 } 10 // ^^^^^^^^ expected i32, got i64
11 // ^^^^ expected i32, got i64
12}
12 ", 13 ",
13 expect![[r"
14 10..40 '{ ...4 }; }': ()
15 20..21 'a': i32
16 29..37 '{ 1i64 }': i64
17 31..35 '1i64': i64
18 "]],
19 ); 14 );
20} 15}
21 16
22#[test] 17#[test]
23fn coerce_places() { 18fn coerce_places() {
24 check_infer( 19 check_no_mismatches(
25 r#" 20 r#"
26//- minicore: coerce_unsized 21//- minicore: coerce_unsized
27struct S<T> { a: T } 22struct S<T> { a: T }
@@ -46,81 +41,25 @@ fn test2() {
46 let g: (&[_], &[_]) = (arr, arr); 41 let g: (&[_], &[_]) = (arr, arr);
47} 42}
48"#, 43"#,
49 expect![[r#"
50 30..31 '_': &[T]
51 44..55 '{ loop {} }': T
52 46..53 'loop {}': !
53 51..53 '{}': ()
54 64..65 '_': S<&[T]>
55 81..92 '{ loop {} }': T
56 83..90 'loop {}': !
57 88..90 '{}': ()
58 121..132 '{ loop {} }': *mut [T; 2]
59 123..130 'loop {}': !
60 128..130 '{}': ()
61 159..172 '{ gen() }': *mut [U]
62 165..168 'gen': fn gen<U>() -> *mut [U; 2]
63 165..170 'gen()': *mut [U; 2]
64 185..419 '{ ...rr); }': ()
65 195..198 'arr': &[u8; 1]
66 211..215 '&[1]': &[u8; 1]
67 212..215 '[1]': [u8; 1]
68 213..214 '1': u8
69 226..227 'a': &[u8]
70 236..239 'arr': &[u8; 1]
71 249..250 'b': u8
72 253..254 'f': fn f<u8>(&[u8]) -> u8
73 253..259 'f(arr)': u8
74 255..258 'arr': &[u8; 1]
75 269..270 'c': &[u8]
76 279..286 '{ arr }': &[u8]
77 281..284 'arr': &[u8; 1]
78 296..297 'd': u8
79 300..301 'g': fn g<u8>(S<&[u8]>) -> u8
80 300..315 'g(S { a: arr })': u8
81 302..314 'S { a: arr }': S<&[u8]>
82 309..312 'arr': &[u8; 1]
83 325..326 'e': [&[u8]; 1]
84 340..345 '[arr]': [&[u8]; 1]
85 341..344 'arr': &[u8; 1]
86 355..356 'f': [&[u8]; 2]
87 370..378 '[arr; 2]': [&[u8]; 2]
88 371..374 'arr': &[u8; 1]
89 376..377 '2': usize
90 388..389 'g': (&[u8], &[u8])
91 406..416 '(arr, arr)': (&[u8], &[u8])
92 407..410 'arr': &[u8; 1]
93 412..415 'arr': &[u8; 1]
94 "#]],
95 ); 44 );
96} 45}
97 46
98#[test] 47#[test]
99fn infer_let_stmt_coerce() { 48fn let_stmt_coerce() {
100 check_infer( 49 check_no_mismatches(
101 r" 50 r"
102 fn test() { 51//- minicore: coerce_unsized
103 let x: &[isize] = &[1]; 52fn test() {
104 let x: *const [isize] = &[1]; 53 let x: &[isize] = &[1];
105 } 54 let x: *const [isize] = &[1];
106 ", 55}
107 expect![[r#" 56",
108 10..75 '{ ...[1]; }': ()
109 20..21 'x': &[isize]
110 34..38 '&[1]': &[isize; 1]
111 35..38 '[1]': [isize; 1]
112 36..37 '1': isize
113 48..49 'x': *const [isize]
114 68..72 '&[1]': &[isize; 1]
115 69..72 '[1]': [isize; 1]
116 70..71 '1': isize
117 "#]],
118 ); 57 );
119} 58}
120 59
121#[test] 60#[test]
122fn infer_custom_coerce_unsized() { 61fn custom_coerce_unsized() {
123 check_infer( 62 check(
124 r#" 63 r#"
125//- minicore: coerce_unsized 64//- minicore: coerce_unsized
126use core::{marker::Unsize, ops::CoerceUnsized}; 65use core::{marker::Unsize, ops::CoerceUnsized};
@@ -138,46 +77,22 @@ fn foo3<T>(x: C<[T]>) -> C<[T]> { x }
138 77
139fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) { 78fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) {
140 let d = foo1(a); 79 let d = foo1(a);
80 // ^ expected A<[{unknown}]>, got A<[u8; 2]>
141 let e = foo2(b); 81 let e = foo2(b);
82 // ^ type: B<[u8]>
142 let f = foo3(c); 83 let f = foo3(c);
84 // ^ type: C<[u8]>
143} 85}
144"#, 86"#,
145 expect![[r#"
146 306..307 'x': A<[T]>
147 327..332 '{ x }': A<[T]>
148 329..330 'x': A<[T]>
149 344..345 'x': B<[T]>
150 365..370 '{ x }': B<[T]>
151 367..368 'x': B<[T]>
152 382..383 'x': C<[T]>
153 403..408 '{ x }': C<[T]>
154 405..406 'x': C<[T]>
155 418..419 'a': A<[u8; 2]>
156 433..434 'b': B<[u8; 2]>
157 448..449 'c': C<[u8; 2]>
158 463..529 '{ ...(c); }': ()
159 473..474 'd': A<[{unknown}]>
160 477..481 'foo1': fn foo1<{unknown}>(A<[{unknown}]>) -> A<[{unknown}]>
161 477..484 'foo1(a)': A<[{unknown}]>
162 482..483 'a': A<[u8; 2]>
163 494..495 'e': B<[u8]>
164 498..502 'foo2': fn foo2<u8>(B<[u8]>) -> B<[u8]>
165 498..505 'foo2(b)': B<[u8]>
166 503..504 'b': B<[u8; 2]>
167 515..516 'f': C<[u8]>
168 519..523 'foo3': fn foo3<u8>(C<[u8]>) -> C<[u8]>
169 519..526 'foo3(c)': C<[u8]>
170 524..525 'c': C<[u8; 2]>
171 "#]],
172 ); 87 );
173} 88}
174 89
175#[test] 90#[test]
176fn infer_if_coerce() { 91fn if_coerce() {
177 check_infer( 92 check_no_mismatches(
178 r#" 93 r#"
179//- minicore: unsize 94//- minicore: coerce_unsized
180fn foo<T>(x: &[T]) -> &[T] { loop {} } 95fn foo<T>(x: &[T]) -> &[T] { x }
181fn test() { 96fn test() {
182 let x = if true { 97 let x = if true {
183 foo(&[1]) 98 foo(&[1])
@@ -186,35 +101,15 @@ fn test() {
186 }; 101 };
187} 102}
188"#, 103"#,
189 expect![[r#"
190 10..11 'x': &[T]
191 27..38 '{ loop {} }': &[T]
192 29..36 'loop {}': !
193 34..36 '{}': ()
194 49..125 '{ ... }; }': ()
195 59..60 'x': &[i32]
196 63..122 'if tru... }': &[i32]
197 66..70 'true': bool
198 71..96 '{ ... }': &[i32]
199 81..84 'foo': fn foo<i32>(&[i32]) -> &[i32]
200 81..90 'foo(&[1])': &[i32]
201 85..89 '&[1]': &[i32; 1]
202 86..89 '[1]': [i32; 1]
203 87..88 '1': i32
204 102..122 '{ ... }': &[i32; 1]
205 112..116 '&[1]': &[i32; 1]
206 113..116 '[1]': [i32; 1]
207 114..115 '1': i32
208 "#]],
209 ); 104 );
210} 105}
211 106
212#[test] 107#[test]
213fn infer_if_else_coerce() { 108fn if_else_coerce() {
214 check_infer( 109 check_no_mismatches(
215 r#" 110 r#"
216//- minicore: coerce_unsized 111//- minicore: coerce_unsized
217fn foo<T>(x: &[T]) -> &[T] { loop {} } 112fn foo<T>(x: &[T]) -> &[T] { x }
218fn test() { 113fn test() {
219 let x = if true { 114 let x = if true {
220 &[1] 115 &[1]
@@ -223,35 +118,15 @@ fn test() {
223 }; 118 };
224} 119}
225"#, 120"#,
226 expect![[r#"
227 10..11 'x': &[T]
228 27..38 '{ loop {} }': &[T]
229 29..36 'loop {}': !
230 34..36 '{}': ()
231 49..125 '{ ... }; }': ()
232 59..60 'x': &[i32]
233 63..122 'if tru... }': &[i32]
234 66..70 'true': bool
235 71..91 '{ ... }': &[i32; 1]
236 81..85 '&[1]': &[i32; 1]
237 82..85 '[1]': [i32; 1]
238 83..84 '1': i32
239 97..122 '{ ... }': &[i32]
240 107..110 'foo': fn foo<i32>(&[i32]) -> &[i32]
241 107..116 'foo(&[1])': &[i32]
242 111..115 '&[1]': &[i32; 1]
243 112..115 '[1]': [i32; 1]
244 113..114 '1': i32
245 "#]],
246 ) 121 )
247} 122}
248 123
249#[test] 124#[test]
250fn infer_match_first_coerce() { 125fn match_first_coerce() {
251 check_infer( 126 check_no_mismatches(
252 r#" 127 r#"
253//- minicore: unsize 128//- minicore: coerce_unsized
254fn foo<T>(x: &[T]) -> &[T] { loop {} } 129fn foo<T>(x: &[T]) -> &[T] { x }
255fn test(i: i32) { 130fn test(i: i32) {
256 let x = match i { 131 let x = match i {
257 2 => foo(&[2]), 132 2 => foo(&[2]),
@@ -260,39 +135,12 @@ fn test(i: i32) {
260 }; 135 };
261} 136}
262"#, 137"#,
263 expect![[r#"
264 10..11 'x': &[T]
265 27..38 '{ loop {} }': &[T]
266 29..36 'loop {}': !
267 34..36 '{}': ()
268 47..48 'i': i32
269 55..149 '{ ... }; }': ()
270 65..66 'x': &[i32]
271 69..146 'match ... }': &[i32]
272 75..76 'i': i32
273 87..88 '2': i32
274 87..88 '2': i32
275 92..95 'foo': fn foo<i32>(&[i32]) -> &[i32]
276 92..101 'foo(&[2])': &[i32]
277 96..100 '&[2]': &[i32; 1]
278 97..100 '[2]': [i32; 1]
279 98..99 '2': i32
280 111..112 '1': i32
281 111..112 '1': i32
282 116..120 '&[1]': &[i32; 1]
283 117..120 '[1]': [i32; 1]
284 118..119 '1': i32
285 130..131 '_': i32
286 135..139 '&[3]': &[i32; 1]
287 136..139 '[3]': [i32; 1]
288 137..138 '3': i32
289 "#]],
290 ); 138 );
291} 139}
292 140
293#[test] 141#[test]
294fn infer_match_second_coerce() { 142fn match_second_coerce() {
295 check_infer( 143 check_no_mismatches(
296 r#" 144 r#"
297//- minicore: coerce_unsized 145//- minicore: coerce_unsized
298fn foo<T>(x: &[T]) -> &[T] { loop {} } 146fn foo<T>(x: &[T]) -> &[T] { loop {} }
@@ -304,33 +152,6 @@ fn test(i: i32) {
304 }; 152 };
305} 153}
306"#, 154"#,
307 expect![[r#"
308 10..11 'x': &[T]
309 27..38 '{ loop {} }': &[T]
310 29..36 'loop {}': !
311 34..36 '{}': ()
312 47..48 'i': i32
313 55..149 '{ ... }; }': ()
314 65..66 'x': &[i32]
315 69..146 'match ... }': &[i32]
316 75..76 'i': i32
317 87..88 '1': i32
318 87..88 '1': i32
319 92..96 '&[1]': &[i32; 1]
320 93..96 '[1]': [i32; 1]
321 94..95 '1': i32
322 106..107 '2': i32
323 106..107 '2': i32
324 111..114 'foo': fn foo<i32>(&[i32]) -> &[i32]
325 111..120 'foo(&[2])': &[i32]
326 115..119 '&[2]': &[i32; 1]
327 116..119 '[2]': [i32; 1]
328 117..118 '2': i32
329 130..131 '_': i32
330 135..139 '&[3]': &[i32; 1]
331 136..139 '[3]': [i32; 1]
332 137..138 '3': i32
333 "#]],
334 ); 155 );
335} 156}
336 157
@@ -338,94 +159,52 @@ fn test(i: i32) {
338fn coerce_merge_one_by_one1() { 159fn coerce_merge_one_by_one1() {
339 cov_mark::check!(coerce_merge_fail_fallback); 160 cov_mark::check!(coerce_merge_fail_fallback);
340 161
341 check_infer( 162 check(
342 r" 163 r"
343 fn test() { 164fn test() {
344 let t = &mut 1; 165 let t = &mut 1;
345 let x = match 1 { 166 let x = match 1 {
346 1 => t as *mut i32, 167 1 => t as *mut i32,
347 2 => t as &i32, 168 2 => t as &i32,
348 _ => t as *const i32, 169 //^^^^^^^^^ expected *mut i32, got &i32
349 }; 170 _ => t as *const i32,
350 } 171 };
172 x;
173 //^ type: *const i32
174}
351 ", 175 ",
352 expect![[r"
353 10..144 '{ ... }; }': ()
354 20..21 't': &mut i32
355 24..30 '&mut 1': &mut i32
356 29..30 '1': i32
357 40..41 'x': *const i32
358 44..141 'match ... }': *const i32
359 50..51 '1': i32
360 62..63 '1': i32
361 62..63 '1': i32
362 67..68 't': &mut i32
363 67..80 't as *mut i32': *mut i32
364 90..91 '2': i32
365 90..91 '2': i32
366 95..96 't': &mut i32
367 95..104 't as &i32': &i32
368 114..115 '_': i32
369 119..120 't': &mut i32
370 119..134 't as *const i32': *const i32
371 "]],
372 ); 176 );
373} 177}
374 178
375#[test] 179#[test]
376fn return_coerce_unknown() { 180fn return_coerce_unknown() {
377 check_infer_with_mismatches( 181 check_types(
378 r" 182 r"
379 fn foo() -> u32 { 183fn foo() -> u32 {
380 return unknown; 184 return unknown;
381 } 185 //^^^^^^^ u32
186}
382 ", 187 ",
383 expect![[r"
384 16..39 '{ ...own; }': u32
385 22..36 'return unknown': !
386 29..36 'unknown': u32
387 "]],
388 ); 188 );
389} 189}
390 190
391#[test] 191#[test]
392fn coerce_autoderef() { 192fn coerce_autoderef() {
393 check_infer_with_mismatches( 193 check_no_mismatches(
394 r" 194 r"
395 struct Foo; 195struct Foo;
396 fn takes_ref_foo(x: &Foo) {} 196fn takes_ref_foo(x: &Foo) {}
397 fn test() { 197fn test() {
398 takes_ref_foo(&Foo); 198 takes_ref_foo(&Foo);
399 takes_ref_foo(&&Foo); 199 takes_ref_foo(&&Foo);
400 takes_ref_foo(&&&Foo); 200 takes_ref_foo(&&&Foo);
401 } 201}",
402 ",
403 expect![[r"
404 29..30 'x': &Foo
405 38..40 '{}': ()
406 51..132 '{ ...oo); }': ()
407 57..70 'takes_ref_foo': fn takes_ref_foo(&Foo)
408 57..76 'takes_...(&Foo)': ()
409 71..75 '&Foo': &Foo
410 72..75 'Foo': Foo
411 82..95 'takes_ref_foo': fn takes_ref_foo(&Foo)
412 82..102 'takes_...&&Foo)': ()
413 96..101 '&&Foo': &&Foo
414 97..101 '&Foo': &Foo
415 98..101 'Foo': Foo
416 108..121 'takes_ref_foo': fn takes_ref_foo(&Foo)
417 108..129 'takes_...&&Foo)': ()
418 122..128 '&&&Foo': &&&Foo
419 123..128 '&&Foo': &&Foo
420 124..128 '&Foo': &Foo
421 125..128 'Foo': Foo
422 "]],
423 ); 202 );
424} 203}
425 204
426#[test] 205#[test]
427fn coerce_autoderef_generic() { 206fn coerce_autoderef_generic() {
428 check_infer_with_mismatches( 207 check_no_mismatches(
429 r#" 208 r#"
430struct Foo; 209struct Foo;
431fn takes_ref<T>(x: &T) -> T { *x } 210fn takes_ref<T>(x: &T) -> T { *x }
@@ -435,34 +214,12 @@ fn test() {
435 takes_ref(&&&Foo); 214 takes_ref(&&&Foo);
436} 215}
437"#, 216"#,
438 expect![[r"
439 28..29 'x': &T
440 40..46 '{ *x }': T
441 42..44 '*x': T
442 43..44 'x': &T
443 57..126 '{ ...oo); }': ()
444 63..72 'takes_ref': fn takes_ref<Foo>(&Foo) -> Foo
445 63..78 'takes_ref(&Foo)': Foo
446 73..77 '&Foo': &Foo
447 74..77 'Foo': Foo
448 84..93 'takes_ref': fn takes_ref<&Foo>(&&Foo) -> &Foo
449 84..100 'takes_...&&Foo)': &Foo
450 94..99 '&&Foo': &&Foo
451 95..99 '&Foo': &Foo
452 96..99 'Foo': Foo
453 106..115 'takes_ref': fn takes_ref<&&Foo>(&&&Foo) -> &&Foo
454 106..123 'takes_...&&Foo)': &&Foo
455 116..122 '&&&Foo': &&&Foo
456 117..122 '&&Foo': &&Foo
457 118..122 '&Foo': &Foo
458 119..122 'Foo': Foo
459 "]],
460 ); 217 );
461} 218}
462 219
463#[test] 220#[test]
464fn coerce_autoderef_block() { 221fn coerce_autoderef_block() {
465 check_infer_with_mismatches( 222 check_no_mismatches(
466 r#" 223 r#"
467//- minicore: deref 224//- minicore: deref
468struct String {} 225struct String {}
@@ -473,71 +230,32 @@ fn test() {
473 takes_ref_str(&{ returns_string() }); 230 takes_ref_str(&{ returns_string() });
474} 231}
475"#, 232"#,
476 expect![[r#"
477 90..91 'x': &str
478 99..101 '{}': ()
479 132..143 '{ loop {} }': String
480 134..141 'loop {}': !
481 139..141 '{}': ()
482 154..199 '{ ... }); }': ()
483 160..173 'takes_ref_str': fn takes_ref_str(&str)
484 160..196 'takes_...g() })': ()
485 174..195 '&{ ret...ng() }': &String
486 175..195 '{ retu...ng() }': String
487 177..191 'returns_string': fn returns_string() -> String
488 177..193 'return...ring()': String
489 "#]],
490 ); 233 );
491} 234}
492 235
493#[test] 236#[test]
494fn closure_return_coerce() { 237fn closure_return_coerce() {
495 check_infer_with_mismatches( 238 check_no_mismatches(
496 r" 239 r"
497 fn foo() { 240fn foo() {
498 let x = || { 241 let x = || {
499 if true { 242 if true {
500 return &1u32; 243 return &1u32;
501 }
502 &&1u32
503 };
504 } 244 }
505 ", 245 &&1u32
506 expect![[r" 246 };
507 9..105 '{ ... }; }': () 247}",
508 19..20 'x': || -> &u32
509 23..102 '|| { ... }': || -> &u32
510 26..102 '{ ... }': &u32
511 36..81 'if tru... }': ()
512 39..43 'true': bool
513 44..81 '{ ... }': ()
514 58..70 'return &1u32': !
515 65..70 '&1u32': &u32
516 66..70 '1u32': u32
517 90..96 '&&1u32': &&u32
518 91..96 '&1u32': &u32
519 92..96 '1u32': u32
520 "]],
521 ); 248 );
522} 249}
523 250
524#[test] 251#[test]
525fn coerce_fn_item_to_fn_ptr() { 252fn coerce_fn_item_to_fn_ptr() {
526 check_infer_with_mismatches( 253 check_no_mismatches(
527 r" 254 r"
528 fn foo(x: u32) -> isize { 1 } 255fn foo(x: u32) -> isize { 1 }
529 fn test() { 256fn test() {
530 let f: fn(u32) -> isize = foo; 257 let f: fn(u32) -> isize = foo;
531 } 258}",
532 ",
533 expect![[r"
534 7..8 'x': u32
535 24..29 '{ 1 }': isize
536 26..27 '1': isize
537 40..78 '{ ...foo; }': ()
538 50..51 'f': fn(u32) -> isize
539 72..75 'foo': fn foo(u32) -> isize
540 "]],
541 ); 259 );
542} 260}
543 261
@@ -545,110 +263,62 @@ fn coerce_fn_item_to_fn_ptr() {
545fn coerce_fn_items_in_match_arms() { 263fn coerce_fn_items_in_match_arms() {
546 cov_mark::check!(coerce_fn_reification); 264 cov_mark::check!(coerce_fn_reification);
547 265
548 check_infer_with_mismatches( 266 check_types(
549 r" 267 r"
550 fn foo1(x: u32) -> isize { 1 } 268fn foo1(x: u32) -> isize { 1 }
551 fn foo2(x: u32) -> isize { 2 } 269fn foo2(x: u32) -> isize { 2 }
552 fn foo3(x: u32) -> isize { 3 } 270fn foo3(x: u32) -> isize { 3 }
553 fn test() { 271fn test() {
554 let x = match 1 { 272 let x = match 1 {
555 1 => foo1, 273 1 => foo1,
556 2 => foo2, 274 2 => foo2,
557 _ => foo3, 275 _ => foo3,
558 }; 276 };
559 } 277 x;
560 ", 278 //^ fn(u32) -> isize
561 expect![[r" 279}",
562 8..9 'x': u32
563 25..30 '{ 1 }': isize
564 27..28 '1': isize
565 39..40 'x': u32
566 56..61 '{ 2 }': isize
567 58..59 '2': isize
568 70..71 'x': u32
569 87..92 '{ 3 }': isize
570 89..90 '3': isize
571 103..192 '{ ... }; }': ()
572 113..114 'x': fn(u32) -> isize
573 117..189 'match ... }': fn(u32) -> isize
574 123..124 '1': i32
575 135..136 '1': i32
576 135..136 '1': i32
577 140..144 'foo1': fn foo1(u32) -> isize
578 154..155 '2': i32
579 154..155 '2': i32
580 159..163 'foo2': fn foo2(u32) -> isize
581 173..174 '_': i32
582 178..182 'foo3': fn foo3(u32) -> isize
583 "]],
584 ); 280 );
585} 281}
586 282
587#[test] 283#[test]
588fn coerce_closure_to_fn_ptr() { 284fn coerce_closure_to_fn_ptr() {
589 check_infer_with_mismatches( 285 check_no_mismatches(
590 r" 286 r"
591 fn test() { 287fn test() {
592 let f: fn(u32) -> isize = |x| { 1 }; 288 let f: fn(u32) -> isize = |x| { 1 };
593 } 289}",
594 ",
595 expect![[r"
596 10..54 '{ ...1 }; }': ()
597 20..21 'f': fn(u32) -> isize
598 42..51 '|x| { 1 }': |u32| -> isize
599 43..44 'x': u32
600 46..51 '{ 1 }': isize
601 48..49 '1': isize
602 "]],
603 ); 290 );
604} 291}
605 292
606#[test] 293#[test]
607fn coerce_placeholder_ref() { 294fn coerce_placeholder_ref() {
608 // placeholders should unify, even behind references 295 // placeholders should unify, even behind references
609 check_infer_with_mismatches( 296 check_no_mismatches(
610 r" 297 r"
611 struct S<T> { t: T } 298struct S<T> { t: T }
612 impl<TT> S<TT> { 299impl<TT> S<TT> {
613 fn get(&self) -> &TT { 300 fn get(&self) -> &TT {
614 &self.t 301 &self.t
615 } 302 }
616 } 303}",
617 ",
618 expect![[r"
619 50..54 'self': &S<TT>
620 63..86 '{ ... }': &TT
621 73..80 '&self.t': &TT
622 74..78 'self': &S<TT>
623 74..80 'self.t': TT
624 "]],
625 ); 304 );
626} 305}
627 306
628#[test] 307#[test]
629fn coerce_unsize_array() { 308fn coerce_unsize_array() {
630 check_infer_with_mismatches( 309 check_types(
631 r#" 310 r#"
632//- minicore: coerce_unsized 311//- minicore: coerce_unsized
633fn test() { 312fn test() {
634 let f: &[usize] = &[1, 2, 3]; 313 let f: &[usize] = &[1, 2, 3];
635} 314 //^ usize
636 "#, 315}"#,
637 expect![[r#"
638 10..47 '{ ... 3]; }': ()
639 20..21 'f': &[usize]
640 34..44 '&[1, 2, 3]': &[usize; 3]
641 35..44 '[1, 2, 3]': [usize; 3]
642 36..37 '1': usize
643 39..40 '2': usize
644 42..43 '3': usize
645 "#]],
646 ); 316 );
647} 317}
648 318
649#[test] 319#[test]
650fn coerce_unsize_trait_object_simple() { 320fn coerce_unsize_trait_object_simple() {
651 check_infer_with_mismatches( 321 check_types(
652 r#" 322 r#"
653//- minicore: coerce_unsized 323//- minicore: coerce_unsized
654trait Foo<T, U> {} 324trait Foo<T, U> {}
@@ -662,88 +332,18 @@ impl<T, X> Baz<T, X> for S<T, X> {}
662 332
663fn test() { 333fn test() {
664 let obj: &dyn Baz<i8, i16> = &S; 334 let obj: &dyn Baz<i8, i16> = &S;
335 //^ S<i8, i16>
665 let obj: &dyn Bar<_, i8, i16> = &S; 336 let obj: &dyn Bar<_, i8, i16> = &S;
337 //^ S<i8, i16>
666 let obj: &dyn Foo<i8, _> = &S; 338 let obj: &dyn Foo<i8, _> = &S;
667} 339 //^ S<i8, {unknown}>
668"#, 340}"#,
669 expect![[r#"
670 236..351 '{ ... &S; }': ()
671 246..249 'obj': &dyn Baz<i8, i16>
672 271..273 '&S': &S<i8, i16>
673 272..273 'S': S<i8, i16>
674 283..286 'obj': &dyn Bar<usize, i8, i16>
675 311..313 '&S': &S<i8, i16>
676 312..313 'S': S<i8, i16>
677 323..326 'obj': &dyn Foo<i8, usize>
678 346..348 '&S': &S<i8, {unknown}>
679 347..348 'S': S<i8, {unknown}>
680 "#]],
681 );
682}
683
684#[test]
685fn coerce_unsize_trait_object_to_trait_object() {
686 // FIXME: The rust reference says this should be possible, but rustc doesn't
687 // implement it. We used to support it, but Chalk doesn't. Here's the
688 // correct expect:
689 //
690 // 424..609 '{ ...bj2; }': ()
691 // 434..437 'obj': &dyn Baz<i8, i16>
692 // 459..461 '&S': &S<i8, i16>
693 // 460..461 'S': S<i8, i16>
694 // 471..474 'obj': &dyn Bar<usize, i8, i16>
695 // 496..499 'obj': &dyn Baz<i8, i16>
696 // 509..512 'obj': &dyn Foo<i8, usize>
697 // 531..534 'obj': &dyn Bar<usize, i8, i16>
698 // 544..548 'obj2': &dyn Baz<i8, i16>
699 // 570..572 '&S': &S<i8, i16>
700 // 571..572 'S': S<i8, i16>
701 // 582..583 '_': &dyn Foo<i8, usize>
702 // 602..606 'obj2': &dyn Baz<i8, i16>
703 check_infer_with_mismatches(
704 r#"
705//- minicore: coerce_unsized
706trait Foo<T, U> {}
707trait Bar<U, T, X>: Foo<T, U> {}
708trait Baz<T, X>: Bar<usize, T, X> {}
709
710struct S<T, X>;
711impl<T, X> Foo<T, usize> for S<T, X> {}
712impl<T, X> Bar<usize, T, X> for S<T, X> {}
713impl<T, X> Baz<T, X> for S<T, X> {}
714
715fn test() {
716 let obj: &dyn Baz<i8, i16> = &S;
717 let obj: &dyn Bar<_, _, _> = obj;
718 let obj: &dyn Foo<_, _> = obj;
719 let obj2: &dyn Baz<i8, i16> = &S;
720 let _: &dyn Foo<_, _> = obj2;
721}
722"#,
723 expect![[r#"
724 236..421 '{ ...bj2; }': ()
725 246..249 'obj': &dyn Baz<i8, i16>
726 271..273 '&S': &S<i8, i16>
727 272..273 'S': S<i8, i16>
728 283..286 'obj': &dyn Bar<{unknown}, {unknown}, {unknown}>
729 308..311 'obj': &dyn Baz<i8, i16>
730 321..324 'obj': &dyn Foo<{unknown}, {unknown}>
731 343..346 'obj': &dyn Bar<{unknown}, {unknown}, {unknown}>
732 356..360 'obj2': &dyn Baz<i8, i16>
733 382..384 '&S': &S<i8, i16>
734 383..384 'S': S<i8, i16>
735 394..395 '_': &dyn Foo<{unknown}, {unknown}>
736 414..418 'obj2': &dyn Baz<i8, i16>
737 308..311: expected &dyn Bar<{unknown}, {unknown}, {unknown}>, got &dyn Baz<i8, i16>
738 343..346: expected &dyn Foo<{unknown}, {unknown}>, got &dyn Bar<{unknown}, {unknown}, {unknown}>
739 414..418: expected &dyn Foo<{unknown}, {unknown}>, got &dyn Baz<i8, i16>
740 "#]],
741 ); 341 );
742} 342}
743 343
744#[test] 344#[test]
745fn coerce_unsize_super_trait_cycle() { 345fn coerce_unsize_super_trait_cycle() {
746 check_infer_with_mismatches( 346 check_no_mismatches(
747 r#" 347 r#"
748//- minicore: coerce_unsized 348//- minicore: coerce_unsized
749trait A {} 349trait A {}
@@ -762,22 +362,13 @@ fn test() {
762 let obj: &dyn A = &S; 362 let obj: &dyn A = &S;
763} 363}
764"#, 364"#,
765 expect![[r#"
766 140..195 '{ ... &S; }': ()
767 150..153 'obj': &dyn D
768 164..166 '&S': &S
769 165..166 'S': S
770 176..179 'obj': &dyn A
771 190..192 '&S': &S
772 191..192 'S': S
773 "#]],
774 ); 365 );
775} 366}
776 367
777#[test] 368#[test]
778fn coerce_unsize_generic() { 369fn coerce_unsize_generic() {
779 // FIXME: fix the type mismatches here 370 // FIXME: fix the type mismatches here
780 check_infer_with_mismatches( 371 check(
781 r#" 372 r#"
782//- minicore: coerce_unsized 373//- minicore: coerce_unsized
783struct Foo<T> { t: T }; 374struct Foo<T> { t: T };
@@ -785,73 +376,47 @@ struct Bar<T>(Foo<T>);
785 376
786fn test() { 377fn test() {
787 let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] }; 378 let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] };
379 //^^^^^^^^^ expected [usize], got [usize; 3]
788 let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] }); 380 let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] });
381 //^^^^^^^^^^^^^^^^^^^^^^^^^^ expected &Bar<[usize]>, got &Bar<[i32; 3]>
789} 382}
790"#, 383"#,
791 expect![[r#"
792 58..166 '{ ... }); }': ()
793 68..69 '_': &Foo<[usize]>
794 87..108 '&Foo {..., 3] }': &Foo<[usize]>
795 88..108 'Foo { ..., 3] }': Foo<[usize]>
796 97..106 '[1, 2, 3]': [usize; 3]
797 98..99 '1': usize
798 101..102 '2': usize
799 104..105 '3': usize
800 118..119 '_': &Bar<[usize]>
801 137..163 '&Bar(F... 3] })': &Bar<[i32; 3]>
802 138..141 'Bar': Bar<[i32; 3]>(Foo<[i32; 3]>) -> Bar<[i32; 3]>
803 138..163 'Bar(Fo... 3] })': Bar<[i32; 3]>
804 142..162 'Foo { ..., 3] }': Foo<[i32; 3]>
805 151..160 '[1, 2, 3]': [i32; 3]
806 152..153 '1': i32
807 155..156 '2': i32
808 158..159 '3': i32
809 97..106: expected [usize], got [usize; 3]
810 137..163: expected &Bar<[usize]>, got &Bar<[i32; 3]>
811 "#]],
812 ); 384 );
813} 385}
814 386
815#[test] 387#[test]
816fn coerce_unsize_apit() { 388fn coerce_unsize_apit() {
817 // FIXME: #8984 389 // FIXME: #8984
818 check_infer_with_mismatches( 390 check(
819 r#" 391 r#"
820//- minicore: coerce_unsized 392//- minicore: coerce_unsized
821trait Foo {} 393trait Foo {}
822 394
823fn test(f: impl Foo) { 395fn test(f: impl Foo) {
824 let _: &dyn Foo = &f; 396 let _: &dyn Foo = &f;
397 //^^ expected &dyn Foo, got &impl Foo
825} 398}
826 "#, 399 "#,
827 expect![[r#"
828 22..23 'f': impl Foo
829 35..64 '{ ... &f; }': ()
830 45..46 '_': &dyn Foo
831 59..61 '&f': &impl Foo
832 60..61 'f': impl Foo
833 59..61: expected &dyn Foo, got &impl Foo
834 "#]],
835 ); 400 );
836} 401}
837 402
838#[test] 403#[test]
839fn infer_two_closures_lub() { 404fn two_closures_lub() {
840 check_types( 405 check_types(
841 r#" 406 r#"
842fn foo(c: i32) { 407fn foo(c: i32) {
843 let add = |a: i32, b: i32| a + b; 408 let add = |a: i32, b: i32| a + b;
844 let sub = |a, b| a - b; 409 let sub = |a, b| a - b;
845 //^ |i32, i32| -> i32 410 //^^^^^^^^^^^^ |i32, i32| -> i32
846 if c > 42 { add } else { sub }; 411 if c > 42 { add } else { sub };
847 //^ fn(i32, i32) -> i32 412 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ fn(i32, i32) -> i32
848} 413}
849 "#, 414 "#,
850 ) 415 )
851} 416}
852 417
853#[test] 418#[test]
854fn infer_match_diverging_branch_1() { 419fn match_diverging_branch_1() {
855 check_types( 420 check_types(
856 r#" 421 r#"
857enum Result<T> { Ok(T), Err } 422enum Result<T> { Ok(T), Err }
@@ -870,7 +435,7 @@ fn test() -> i32 {
870} 435}
871 436
872#[test] 437#[test]
873fn infer_match_diverging_branch_2() { 438fn match_diverging_branch_2() {
874 // same as 1 except for order of branches 439 // same as 1 except for order of branches
875 check_types( 440 check_types(
876 r#" 441 r#"