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