]> git.lizzy.rs Git - rust.git/blob - crates/hir_ty/src/tests/coercion.rs
eca6ae1fe85c0f2f58f0bfd89559d55021b58db1
[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_no_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 //- minicore: coerce_unsized
27 struct S<T> { a: T }
28
29 fn f<T>(_: &[T]) -> T { loop {} }
30 fn g<T>(_: S<&[T]>) -> T { loop {} }
31
32 fn gen<T>() -> *mut [T; 2] { loop {} }
33 fn test1<U>() -> *mut [U] {
34     gen()
35 }
36
37 fn test2() {
38     let arr: &[u8; 1] = &[1];
39
40     let a: &[_] = arr;
41     let b = f(arr);
42     let c: &[_] = { arr };
43     let d = g(S { a: arr });
44     let e: [&[_]; 1] = [arr];
45     let f: [&[_]; 2] = [arr; 2];
46     let g: (&[_], &[_]) = (arr, arr);
47 }
48 "#,
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     );
96 }
97
98 #[test]
99 fn infer_let_stmt_coerce() {
100     check_infer(
101         r"
102         fn test() {
103             let x: &[isize] = &[1];
104             let x: *const [isize] = &[1];
105         }
106         ",
107         expect![[r#"
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     );
119 }
120
121 #[test]
122 fn infer_custom_coerce_unsized() {
123     check_infer(
124         r#"
125 //- minicore: coerce_unsized
126 use core::{marker::Unsize, ops::CoerceUnsized};
127
128 struct A<T: ?Sized>(*const T);
129 struct B<T: ?Sized>(*const T);
130 struct C<T: ?Sized> { inner: *const T }
131
132 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {}
133 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {}
134
135 fn foo1<T>(x: A<[T]>) -> A<[T]> { x }
136 fn foo2<T>(x: B<[T]>) -> B<[T]> { x }
137 fn foo3<T>(x: C<[T]>) -> C<[T]> { x }
138
139 fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) {
140     let d = foo1(a);
141     let e = foo2(b);
142     let f = foo3(c);
143 }
144 "#,
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     );
173 }
174
175 #[test]
176 fn infer_if_coerce() {
177     check_infer(
178         r#"
179 //- minicore: unsize
180 fn foo<T>(x: &[T]) -> &[T] { loop {} }
181 fn test() {
182     let x = if true {
183         foo(&[1])
184     } else {
185         &[1]
186     };
187 }
188 "#,
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     );
210 }
211
212 #[test]
213 fn infer_if_else_coerce() {
214     check_infer(
215         r#"
216 //- minicore: coerce_unsized
217 fn foo<T>(x: &[T]) -> &[T] { loop {} }
218 fn test() {
219     let x = if true {
220         &[1]
221     } else {
222         foo(&[1])
223     };
224 }
225 "#,
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     )
247 }
248
249 #[test]
250 fn infer_match_first_coerce() {
251     check_infer(
252         r#"
253 //- minicore: unsize
254 fn foo<T>(x: &[T]) -> &[T] { loop {} }
255 fn test(i: i32) {
256     let x = match i {
257         2 => foo(&[2]),
258         1 => &[1],
259         _ => &[3],
260     };
261 }
262 "#,
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     );
291 }
292
293 #[test]
294 fn infer_match_second_coerce() {
295     check_infer(
296         r#"
297 //- minicore: coerce_unsized
298 fn foo<T>(x: &[T]) -> &[T] { loop {} }
299 fn test(i: i32) {
300     let x = match i {
301         1 => &[1],
302         2 => foo(&[2]),
303         _ => &[3],
304     };
305 }
306 "#,
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     );
335 }
336
337 #[test]
338 fn coerce_merge_one_by_one1() {
339     cov_mark::check!(coerce_merge_fail_fallback);
340
341     check_infer(
342         r"
343         fn test() {
344             let t = &mut 1;
345             let x = match 1 {
346                 1 => t as *mut i32,
347                 2 => t as &i32,
348                 _ => t as *const i32,
349             };
350         }
351         ",
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     );
373 }
374
375 #[test]
376 fn return_coerce_unknown() {
377     check_infer_with_mismatches(
378         r"
379         fn foo() -> u32 {
380             return unknown;
381         }
382         ",
383         expect![[r"
384             16..39 '{     ...own; }': u32
385             22..36 'return unknown': !
386             29..36 'unknown': u32
387         "]],
388     );
389 }
390
391 #[test]
392 fn coerce_autoderef() {
393     check_infer_with_mismatches(
394         r"
395         struct Foo;
396         fn takes_ref_foo(x: &Foo) {}
397         fn test() {
398             takes_ref_foo(&Foo);
399             takes_ref_foo(&&Foo);
400             takes_ref_foo(&&&Foo);
401         }
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     );
424 }
425
426 #[test]
427 fn coerce_autoderef_generic() {
428     check_infer_with_mismatches(
429         r"
430         struct Foo;
431         fn takes_ref<T>(x: &T) -> T { *x }
432         fn test() {
433             takes_ref(&Foo);
434             takes_ref(&&Foo);
435             takes_ref(&&&Foo);
436         }
437         ",
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     );
461 }
462
463 #[test]
464 fn coerce_autoderef_block() {
465     check_infer_with_mismatches(
466         r#"
467         struct String {}
468         #[lang = "deref"]
469         trait Deref { type Target; }
470         impl Deref for String { type Target = str; }
471         fn takes_ref_str(x: &str) {}
472         fn returns_string() -> String { loop {} }
473         fn test() {
474             takes_ref_str(&{ returns_string() });
475         }
476         "#,
477         expect![[r"
478             126..127 'x': &str
479             135..137 '{}': ()
480             168..179 '{ loop {} }': String
481             170..177 'loop {}': !
482             175..177 '{}': ()
483             190..235 '{     ... }); }': ()
484             196..209 'takes_ref_str': fn takes_ref_str(&str)
485             196..232 'takes_...g() })': ()
486             210..231 '&{ ret...ng() }': &String
487             211..231 '{ retu...ng() }': String
488             213..227 'returns_string': fn returns_string() -> String
489             213..229 'return...ring()': String
490         "]],
491     );
492 }
493
494 #[test]
495 fn closure_return_coerce() {
496     check_infer_with_mismatches(
497         r"
498         fn foo() {
499             let x = || {
500                 if true {
501                     return &1u32;
502                 }
503                 &&1u32
504             };
505         }
506         ",
507         expect![[r"
508             9..105 '{     ...  }; }': ()
509             19..20 'x': || -> &u32
510             23..102 '|| {  ...     }': || -> &u32
511             26..102 '{     ...     }': &u32
512             36..81 'if tru...     }': ()
513             39..43 'true': bool
514             44..81 '{     ...     }': ()
515             58..70 'return &1u32': !
516             65..70 '&1u32': &u32
517             66..70 '1u32': u32
518             90..96 '&&1u32': &&u32
519             91..96 '&1u32': &u32
520             92..96 '1u32': u32
521         "]],
522     );
523 }
524
525 #[test]
526 fn coerce_fn_item_to_fn_ptr() {
527     check_infer_with_mismatches(
528         r"
529         fn foo(x: u32) -> isize { 1 }
530         fn test() {
531             let f: fn(u32) -> isize = foo;
532         }
533         ",
534         expect![[r"
535             7..8 'x': u32
536             24..29 '{ 1 }': isize
537             26..27 '1': isize
538             40..78 '{     ...foo; }': ()
539             50..51 'f': fn(u32) -> isize
540             72..75 'foo': fn foo(u32) -> isize
541         "]],
542     );
543 }
544
545 #[test]
546 fn coerce_fn_items_in_match_arms() {
547     cov_mark::check!(coerce_fn_reification);
548
549     check_infer_with_mismatches(
550         r"
551         fn foo1(x: u32) -> isize { 1 }
552         fn foo2(x: u32) -> isize { 2 }
553         fn foo3(x: u32) -> isize { 3 }
554         fn test() {
555             let x = match 1 {
556                 1 => foo1,
557                 2 => foo2,
558                 _ => foo3,
559             };
560         }
561         ",
562         expect![[r"
563             8..9 'x': u32
564             25..30 '{ 1 }': isize
565             27..28 '1': isize
566             39..40 'x': u32
567             56..61 '{ 2 }': isize
568             58..59 '2': isize
569             70..71 'x': u32
570             87..92 '{ 3 }': isize
571             89..90 '3': isize
572             103..192 '{     ...  }; }': ()
573             113..114 'x': fn(u32) -> isize
574             117..189 'match ...     }': fn(u32) -> isize
575             123..124 '1': i32
576             135..136 '1': i32
577             135..136 '1': i32
578             140..144 'foo1': fn foo1(u32) -> isize
579             154..155 '2': i32
580             154..155 '2': i32
581             159..163 'foo2': fn foo2(u32) -> isize
582             173..174 '_': i32
583             178..182 'foo3': fn foo3(u32) -> isize
584         "]],
585     );
586 }
587
588 #[test]
589 fn coerce_closure_to_fn_ptr() {
590     check_infer_with_mismatches(
591         r"
592         fn test() {
593             let f: fn(u32) -> isize = |x| { 1 };
594         }
595         ",
596         expect![[r"
597             10..54 '{     ...1 }; }': ()
598             20..21 'f': fn(u32) -> isize
599             42..51 '|x| { 1 }': |u32| -> isize
600             43..44 'x': u32
601             46..51 '{ 1 }': isize
602             48..49 '1': isize
603         "]],
604     );
605 }
606
607 #[test]
608 fn coerce_placeholder_ref() {
609     // placeholders should unify, even behind references
610     check_infer_with_mismatches(
611         r"
612         struct S<T> { t: T }
613         impl<TT> S<TT> {
614             fn get(&self) -> &TT {
615                 &self.t
616             }
617         }
618         ",
619         expect![[r"
620             50..54 'self': &S<TT>
621             63..86 '{     ...     }': &TT
622             73..80 '&self.t': &TT
623             74..78 'self': &S<TT>
624             74..80 'self.t': TT
625         "]],
626     );
627 }
628
629 #[test]
630 fn coerce_unsize_array() {
631     check_infer_with_mismatches(
632         r#"
633 //- minicore: coerce_unsized
634 fn test() {
635     let f: &[usize] = &[1, 2, 3];
636 }
637         "#,
638         expect![[r#"
639             10..47 '{     ... 3]; }': ()
640             20..21 'f': &[usize]
641             34..44 '&[1, 2, 3]': &[usize; 3]
642             35..44 '[1, 2, 3]': [usize; 3]
643             36..37 '1': usize
644             39..40 '2': usize
645             42..43 '3': usize
646         "#]],
647     );
648 }
649
650 #[test]
651 fn coerce_unsize_trait_object_simple() {
652     check_infer_with_mismatches(
653         r#"
654 //- minicore: coerce_unsized
655 trait Foo<T, U> {}
656 trait Bar<U, T, X>: Foo<T, U> {}
657 trait Baz<T, X>: Bar<usize, T, X> {}
658
659 struct S<T, X>;
660 impl<T, X> Foo<T, usize> for S<T, X> {}
661 impl<T, X> Bar<usize, T, X> for S<T, X> {}
662 impl<T, X> Baz<T, X> for S<T, X> {}
663
664 fn test() {
665     let obj: &dyn Baz<i8, i16> = &S;
666     let obj: &dyn Bar<_, i8, i16> = &S;
667     let obj: &dyn Foo<i8, _> = &S;
668 }
669 "#,
670         expect![[r#"
671             236..351 '{     ... &S; }': ()
672             246..249 'obj': &dyn Baz<i8, i16>
673             271..273 '&S': &S<i8, i16>
674             272..273 'S': S<i8, i16>
675             283..286 'obj': &dyn Bar<usize, i8, i16>
676             311..313 '&S': &S<i8, i16>
677             312..313 'S': S<i8, i16>
678             323..326 'obj': &dyn Foo<i8, usize>
679             346..348 '&S': &S<i8, {unknown}>
680             347..348 'S': S<i8, {unknown}>
681         "#]],
682     );
683 }
684
685 #[test]
686 fn coerce_unsize_trait_object_to_trait_object() {
687     // FIXME: The rust reference says this should be possible, but rustc doesn't
688     // implement it. We used to support it, but Chalk doesn't. Here's the
689     // correct expect:
690     //
691     //     424..609 '{     ...bj2; }': ()
692     //     434..437 'obj': &dyn Baz<i8, i16>
693     //     459..461 '&S': &S<i8, i16>
694     //     460..461 'S': S<i8, i16>
695     //     471..474 'obj': &dyn Bar<usize, i8, i16>
696     //     496..499 'obj': &dyn Baz<i8, i16>
697     //     509..512 'obj': &dyn Foo<i8, usize>
698     //     531..534 'obj': &dyn Bar<usize, i8, i16>
699     //     544..548 'obj2': &dyn Baz<i8, i16>
700     //     570..572 '&S': &S<i8, i16>
701     //     571..572 'S': S<i8, i16>
702     //     582..583 '_': &dyn Foo<i8, usize>
703     //     602..606 'obj2': &dyn Baz<i8, i16>
704     check_infer_with_mismatches(
705         r#"
706 //- minicore: coerce_unsized
707 trait Foo<T, U> {}
708 trait Bar<U, T, X>: Foo<T, U> {}
709 trait Baz<T, X>: Bar<usize, T, X> {}
710
711 struct S<T, X>;
712 impl<T, X> Foo<T, usize> for S<T, X> {}
713 impl<T, X> Bar<usize, T, X> for S<T, X> {}
714 impl<T, X> Baz<T, X> for S<T, X> {}
715
716 fn test() {
717     let obj: &dyn Baz<i8, i16> = &S;
718     let obj: &dyn Bar<_, _, _> = obj;
719     let obj: &dyn Foo<_, _> = obj;
720     let obj2: &dyn Baz<i8, i16> = &S;
721     let _: &dyn Foo<_, _> = obj2;
722 }
723 "#,
724         expect![[r#"
725             236..421 '{     ...bj2; }': ()
726             246..249 'obj': &dyn Baz<i8, i16>
727             271..273 '&S': &S<i8, i16>
728             272..273 'S': S<i8, i16>
729             283..286 'obj': &dyn Bar<{unknown}, {unknown}, {unknown}>
730             308..311 'obj': &dyn Baz<i8, i16>
731             321..324 'obj': &dyn Foo<{unknown}, {unknown}>
732             343..346 'obj': &dyn Bar<{unknown}, {unknown}, {unknown}>
733             356..360 'obj2': &dyn Baz<i8, i16>
734             382..384 '&S': &S<i8, i16>
735             383..384 'S': S<i8, i16>
736             394..395 '_': &dyn Foo<{unknown}, {unknown}>
737             414..418 'obj2': &dyn Baz<i8, i16>
738             308..311: expected &dyn Bar<{unknown}, {unknown}, {unknown}>, got &dyn Baz<i8, i16>
739             343..346: expected &dyn Foo<{unknown}, {unknown}>, got &dyn Bar<{unknown}, {unknown}, {unknown}>
740             414..418: expected &dyn Foo<{unknown}, {unknown}>, got &dyn Baz<i8, i16>
741         "#]],
742     );
743 }
744
745 #[test]
746 fn coerce_unsize_super_trait_cycle() {
747     check_infer_with_mismatches(
748         r#"
749 //- minicore: coerce_unsized
750 trait A {}
751 trait B: C + A {}
752 trait C: B {}
753 trait D: C
754
755 struct S;
756 impl A for S {}
757 impl B for S {}
758 impl C for S {}
759 impl D for S {}
760
761 fn test() {
762     let obj: &dyn D = &S;
763     let obj: &dyn A = &S;
764 }
765 "#,
766         expect![[r#"
767             140..195 '{     ... &S; }': ()
768             150..153 'obj': &dyn D
769             164..166 '&S': &S
770             165..166 'S': S
771             176..179 'obj': &dyn A
772             190..192 '&S': &S
773             191..192 'S': S
774         "#]],
775     );
776 }
777
778 #[test]
779 fn coerce_unsize_generic() {
780     // FIXME: fix the type mismatches here
781     check_infer_with_mismatches(
782         r#"
783 //- minicore: coerce_unsized
784 struct Foo<T> { t: T };
785 struct Bar<T>(Foo<T>);
786
787 fn test() {
788     let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] };
789     let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] });
790 }
791 "#,
792         expect![[r#"
793             58..166 '{     ... }); }': ()
794             68..69 '_': &Foo<[usize]>
795             87..108 '&Foo {..., 3] }': &Foo<[usize]>
796             88..108 'Foo { ..., 3] }': Foo<[usize]>
797             97..106 '[1, 2, 3]': [usize; 3]
798             98..99 '1': usize
799             101..102 '2': usize
800             104..105 '3': usize
801             118..119 '_': &Bar<[usize]>
802             137..163 '&Bar(F... 3] })': &Bar<[i32; 3]>
803             138..141 'Bar': Bar<[i32; 3]>(Foo<[i32; 3]>) -> Bar<[i32; 3]>
804             138..163 'Bar(Fo... 3] })': Bar<[i32; 3]>
805             142..162 'Foo { ..., 3] }': Foo<[i32; 3]>
806             151..160 '[1, 2, 3]': [i32; 3]
807             152..153 '1': i32
808             155..156 '2': i32
809             158..159 '3': i32
810             97..106: expected [usize], got [usize; 3]
811             137..163: expected &Bar<[usize]>, got &Bar<[i32; 3]>
812         "#]],
813     );
814 }
815
816 #[test]
817 fn coerce_unsize_apit() {
818     // FIXME: #8984
819     check_infer_with_mismatches(
820         r#"
821 //- minicore: coerce_unsized
822 trait Foo {}
823
824 fn test(f: impl Foo) {
825     let _: &dyn Foo = &f;
826 }
827         "#,
828         expect![[r#"
829             22..23 'f': impl Foo
830             35..64 '{     ... &f; }': ()
831             45..46 '_': &dyn Foo
832             59..61 '&f': &impl Foo
833             60..61 'f': impl Foo
834             59..61: expected &dyn Foo, got &impl Foo
835         "#]],
836     );
837 }
838
839 #[test]
840 fn infer_two_closures_lub() {
841     check_types(
842         r#"
843 fn foo(c: i32) {
844     let add = |a: i32, b: i32| a + b;
845     let sub = |a, b| a - b;
846             //^ |i32, i32| -> i32
847     if c > 42 { add } else { sub };
848   //^ fn(i32, i32) -> i32
849 }
850         "#,
851     )
852 }
853
854 #[test]
855 fn infer_match_diverging_branch_1() {
856     check_types(
857         r#"
858 enum Result<T> { Ok(T), Err }
859 fn parse<T>() -> T { loop {} }
860
861 fn test() -> i32 {
862     let a = match parse() {
863         Ok(val) => val,
864         Err => return 0,
865     };
866     a
867   //^ i32
868 }
869         "#,
870     )
871 }
872
873 #[test]
874 fn infer_match_diverging_branch_2() {
875     // same as 1 except for order of branches
876     check_types(
877         r#"
878 enum Result<T> { Ok(T), Err }
879 fn parse<T>() -> T { loop {} }
880
881 fn test() -> i32 {
882     let a = match parse() {
883         Err => return 0,
884         Ok(val) => val,
885     };
886     a
887   //^ i32
888 }
889         "#,
890     )
891 }
892
893 #[test]
894 fn panic_macro() {
895     check_no_mismatches(
896         r#"
897 mod panic {
898     #[macro_export]
899     pub macro panic_2015 {
900         () => (
901             $crate::panicking::panic()
902         ),
903     }
904 }
905
906 mod panicking {
907     pub fn panic() -> ! { loop {} }
908 }
909
910 #[rustc_builtin_macro = "core_panic"]
911 macro_rules! panic {
912     // Expands to either `$crate::panic::panic_2015` or `$crate::panic::panic_2021`
913     // depending on the edition of the caller.
914     ($($arg:tt)*) => {
915         /* compiler built-in */
916     };
917 }
918
919 fn main() {
920     panic!()
921 }
922         "#,
923     );
924 }
925
926 #[test]
927 fn coerce_unsize_expected_type() {
928     check_no_mismatches(
929         r#"
930 //- minicore: coerce_unsized
931 fn main() {
932     let foo: &[u32] = &[1, 2];
933     let foo: &[u32] = match true {
934         true => &[1, 2],
935         false => &[1, 2, 3],
936     };
937     let foo: &[u32] = if true {
938         &[1, 2]
939     } else {
940         &[1, 2, 3]
941     };
942 }
943         "#,
944     );
945 }