1 use expect_test::expect;
3 use super::{check_infer, check_infer_with_mismatches, check_no_mismatches, check_types};
6 fn infer_block_expr_type_mismatch() {
10 let a: i32 = { 1i64 };
14 10..40 '{ ...4 }; }': ()
16 29..37 '{ 1i64 }': i64
26 //- minicore: coerce_unsized
29 fn f<T>(_: &[T]) -> T { loop {} }
30 fn g<T>(_: S<&[T]>) -> T { loop {} }
32 fn gen<T>() -> *mut [T; 2] { loop {} }
33 fn test1<U>() -> *mut [U] {
38 let arr: &[u8; 1] = &[1];
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);
51 44..55 '{ loop {} }': T
55 81..92 '{ loop {} }': T
58 121..132 '{ loop {} }': *mut [T; 2]
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]
70 236..239 'arr': &[u8; 1]
72 253..254 'f': fn f<u8>(&[u8]) -> u8
74 255..258 'arr': &[u8; 1]
76 279..286 '{ arr }': &[u8]
77 281..284 'arr': &[u8; 1]
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]
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]
99 fn infer_let_stmt_coerce() {
103 let x: &[isize] = &[1];
104 let x: *const [isize] = &[1];
108 10..75 '{ ...[1]; }': ()
110 34..38 '&[1]': &[isize; 1]
111 35..38 '[1]': [isize; 1]
113 48..49 'x': *const [isize]
114 68..72 '&[1]': &[isize; 1]
115 69..72 '[1]': [isize; 1]
122 fn infer_custom_coerce_unsized() {
125 struct A<T: ?Sized>(*const T);
126 struct B<T: ?Sized>(*const T);
127 struct C<T: ?Sized> { inner: *const T }
129 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {}
130 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {}
132 fn foo1<T>(x: A<[T]>) -> A<[T]> { x }
133 fn foo2<T>(x: B<[T]>) -> B<[T]> { x }
134 fn foo3<T>(x: C<[T]>) -> C<[T]> { x }
136 fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) {
146 pub trait Unsize<T: ?Sized> {}
147 #[lang = "coerce_unsized"]
148 pub trait CoerceUnsized<T> {}
150 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
151 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
155 278..283 '{ x }': A<[T]>
158 316..321 '{ x }': B<[T]>
161 354..359 '{ x }': C<[T]>
163 369..370 'a': A<[u8; 2]>
164 384..385 'b': B<[u8; 2]>
165 399..400 'c': C<[u8; 2]>
166 414..480 '{ ...(c); }': ()
167 424..425 'd': A<[{unknown}]>
168 428..432 'foo1': fn foo1<{unknown}>(A<[{unknown}]>) -> A<[{unknown}]>
169 428..435 'foo1(a)': A<[{unknown}]>
170 433..434 'a': A<[u8; 2]>
171 445..446 'e': B<[u8]>
172 449..453 'foo2': fn foo2<u8>(B<[u8]>) -> B<[u8]>
173 449..456 'foo2(b)': B<[u8]>
174 454..455 'b': B<[u8; 2]>
175 466..467 'f': C<[u8]>
176 470..474 'foo3': fn foo3<u8>(C<[u8]>) -> C<[u8]>
177 470..477 'foo3(c)': C<[u8]>
178 475..476 'c': C<[u8; 2]>
184 fn infer_if_coerce() {
187 fn foo<T>(x: &[T]) -> &[T] { loop {} }
200 pub trait Unsize<T: ?Sized> {}
204 27..38 '{ loop {} }': &[T]
207 49..125 '{ ... }; }': ()
209 63..122 'if tru... }': &[i32]
211 71..96 '{ ... }': &[i32]
212 81..84 'foo': fn foo<i32>(&[i32]) -> &[i32]
213 81..90 'foo(&[1])': &[i32]
214 85..89 '&[1]': &[i32; 1]
215 86..89 '[1]': [i32; 1]
217 102..122 '{ ... }': &[i32; 1]
218 112..116 '&[1]': &[i32; 1]
219 113..116 '[1]': [i32; 1]
226 fn infer_if_else_coerce() {
229 fn foo<T>(x: &[T]) -> &[T] { loop {} }
241 pub trait Unsize<T: ?Sized> {}
242 #[lang = "coerce_unsized"]
243 pub trait CoerceUnsized<T> {}
245 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
246 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
250 27..38 '{ loop {} }': &[T]
253 49..125 '{ ... }; }': ()
255 63..122 'if tru... }': &[i32]
257 71..91 '{ ... }': &[i32; 1]
258 81..85 '&[1]': &[i32; 1]
259 82..85 '[1]': [i32; 1]
261 97..122 '{ ... }': &[i32]
262 107..110 'foo': fn foo<i32>(&[i32]) -> &[i32]
263 107..116 'foo(&[1])': &[i32]
264 111..115 '&[1]': &[i32; 1]
265 112..115 '[1]': [i32; 1]
272 fn infer_match_first_coerce() {
275 fn foo<T>(x: &[T]) -> &[T] { loop {} }
287 pub trait Unsize<T: ?Sized> {}
291 27..38 '{ loop {} }': &[T]
295 55..149 '{ ... }; }': ()
297 69..146 'match ... }': &[i32]
301 92..95 'foo': fn foo<i32>(&[i32]) -> &[i32]
302 92..101 'foo(&[2])': &[i32]
303 96..100 '&[2]': &[i32; 1]
304 97..100 '[2]': [i32; 1]
308 116..120 '&[1]': &[i32; 1]
309 117..120 '[1]': [i32; 1]
312 135..139 '&[3]': &[i32; 1]
313 136..139 '[3]': [i32; 1]
320 fn infer_match_second_coerce() {
323 fn foo<T>(x: &[T]) -> &[T] { loop {} }
335 pub trait Unsize<T: ?Sized> {}
336 #[lang = "coerce_unsized"]
337 pub trait CoerceUnsized<T> {}
339 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
340 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
344 27..38 '{ loop {} }': &[T]
348 55..149 '{ ... }; }': ()
350 69..146 'match ... }': &[i32]
354 92..96 '&[1]': &[i32; 1]
355 93..96 '[1]': [i32; 1]
359 111..114 'foo': fn foo<i32>(&[i32]) -> &[i32]
360 111..120 'foo(&[2])': &[i32]
361 115..119 '&[2]': &[i32; 1]
362 116..119 '[2]': [i32; 1]
365 135..139 '&[3]': &[i32; 1]
366 136..139 '[3]': [i32; 1]
373 fn coerce_merge_one_by_one1() {
374 cov_mark::check!(coerce_merge_fail_fallback);
383 _ => t as *const i32,
388 10..144 '{ ... }; }': ()
390 24..30 '&mut 1': &mut i32
392 40..41 'x': *const i32
393 44..141 'match ... }': *const i32
398 67..80 't as *mut i32': *mut i32
402 95..104 't as &i32': &i32
404 119..120 't': &mut i32
405 119..134 't as *const i32': *const i32
411 fn return_coerce_unknown() {
412 check_infer_with_mismatches(
419 16..39 '{ ...own; }': u32
420 22..36 'return unknown': !
421 29..36 'unknown': u32
427 fn coerce_autoderef() {
428 check_infer_with_mismatches(
431 fn takes_ref_foo(x: &Foo) {}
434 takes_ref_foo(&&Foo);
435 takes_ref_foo(&&&Foo);
441 51..132 '{ ...oo); }': ()
442 57..70 'takes_ref_foo': fn takes_ref_foo(&Foo)
443 57..76 'takes_...(&Foo)': ()
446 82..95 'takes_ref_foo': fn takes_ref_foo(&Foo)
447 82..102 'takes_...&&Foo)': ()
448 96..101 '&&Foo': &&Foo
451 108..121 'takes_ref_foo': fn takes_ref_foo(&Foo)
452 108..129 'takes_...&&Foo)': ()
453 122..128 '&&&Foo': &&&Foo
454 123..128 '&&Foo': &&Foo
455 124..128 '&Foo': &Foo
462 fn coerce_autoderef_generic() {
463 check_infer_with_mismatches(
466 fn takes_ref<T>(x: &T) -> T { *x }
478 57..126 '{ ...oo); }': ()
479 63..72 'takes_ref': fn takes_ref<Foo>(&Foo) -> Foo
480 63..78 'takes_ref(&Foo)': Foo
483 84..93 'takes_ref': fn takes_ref<&Foo>(&&Foo) -> &Foo
484 84..100 'takes_...&&Foo)': &Foo
485 94..99 '&&Foo': &&Foo
488 106..115 'takes_ref': fn takes_ref<&&Foo>(&&&Foo) -> &&Foo
489 106..123 'takes_...&&Foo)': &&Foo
490 116..122 '&&&Foo': &&&Foo
491 117..122 '&&Foo': &&Foo
492 118..122 '&Foo': &Foo
499 fn coerce_autoderef_block() {
500 check_infer_with_mismatches(
504 trait Deref { type Target; }
505 impl Deref for String { type Target = str; }
506 fn takes_ref_str(x: &str) {}
507 fn returns_string() -> String { loop {} }
509 takes_ref_str(&{ returns_string() });
515 168..179 '{ loop {} }': String
516 170..177 'loop {}': !
518 190..235 '{ ... }); }': ()
519 196..209 'takes_ref_str': fn takes_ref_str(&str)
520 196..232 'takes_...g() })': ()
521 210..231 '&{ ret...ng() }': &String
522 211..231 '{ retu...ng() }': String
523 213..227 'returns_string': fn returns_string() -> String
524 213..229 'return...ring()': String
530 fn closure_return_coerce() {
531 check_infer_with_mismatches(
543 9..105 '{ ... }; }': ()
544 19..20 'x': || -> &u32
545 23..102 '|| { ... }': || -> &u32
546 26..102 '{ ... }': &u32
547 36..81 'if tru... }': ()
550 58..70 'return &1u32': !
553 90..96 '&&1u32': &&u32
561 fn coerce_fn_item_to_fn_ptr() {
562 check_infer_with_mismatches(
564 fn foo(x: u32) -> isize { 1 }
566 let f: fn(u32) -> isize = foo;
571 24..29 '{ 1 }': isize
573 40..78 '{ ...foo; }': ()
574 50..51 'f': fn(u32) -> isize
575 72..75 'foo': fn foo(u32) -> isize
581 fn coerce_fn_items_in_match_arms() {
582 cov_mark::check!(coerce_fn_reification);
584 check_infer_with_mismatches(
586 fn foo1(x: u32) -> isize { 1 }
587 fn foo2(x: u32) -> isize { 2 }
588 fn foo3(x: u32) -> isize { 3 }
599 25..30 '{ 1 }': isize
602 56..61 '{ 2 }': isize
605 87..92 '{ 3 }': isize
607 103..192 '{ ... }; }': ()
608 113..114 'x': fn(u32) -> isize
609 117..189 'match ... }': fn(u32) -> isize
613 140..144 'foo1': fn foo1(u32) -> isize
616 159..163 'foo2': fn foo2(u32) -> isize
618 178..182 'foo3': fn foo3(u32) -> isize
624 fn coerce_closure_to_fn_ptr() {
625 check_infer_with_mismatches(
628 let f: fn(u32) -> isize = |x| { 1 };
632 10..54 '{ ...1 }; }': ()
633 20..21 'f': fn(u32) -> isize
634 42..51 '|x| { 1 }': |u32| -> isize
636 46..51 '{ 1 }': isize
643 fn coerce_placeholder_ref() {
644 // placeholders should unify, even behind references
645 check_infer_with_mismatches(
649 fn get(&self) -> &TT {
655 50..54 'self': &S<TT>
656 63..86 '{ ... }': &TT
657 73..80 '&self.t': &TT
658 74..78 'self': &S<TT>
665 fn coerce_unsize_array() {
666 check_infer_with_mismatches(
669 pub trait Unsize<T> {}
670 #[lang = "coerce_unsized"]
671 pub trait CoerceUnsized<T> {}
673 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
676 let f: &[usize] = &[1, 2, 3];
680 161..198 '{ ... 3]; }': ()
681 171..172 'f': &[usize]
682 185..195 '&[1, 2, 3]': &[usize; 3]
683 186..195 '[1, 2, 3]': [usize; 3]
692 fn coerce_unsize_trait_object_simple() {
693 check_infer_with_mismatches(
698 pub trait Unsize<T> {}
699 #[lang = "coerce_unsized"]
700 pub trait CoerceUnsized<T> {}
702 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
705 trait Bar<U, T, X>: Foo<T, U> {}
706 trait Baz<T, X>: Bar<usize, T, X> {}
709 impl<T, X> Foo<T, usize> for S<T, X> {}
710 impl<T, X> Bar<usize, T, X> for S<T, X> {}
711 impl<T, X> Baz<T, X> for S<T, X> {}
714 let obj: &dyn Baz<i8, i16> = &S;
715 let obj: &dyn Bar<_, i8, i16> = &S;
716 let obj: &dyn Foo<i8, _> = &S;
720 424..539 '{ ... &S; }': ()
721 434..437 'obj': &dyn Baz<i8, i16>
722 459..461 '&S': &S<i8, i16>
723 460..461 'S': S<i8, i16>
724 471..474 'obj': &dyn Bar<usize, i8, i16>
725 499..501 '&S': &S<i8, i16>
726 500..501 'S': S<i8, i16>
727 511..514 'obj': &dyn Foo<i8, usize>
728 534..536 '&S': &S<i8, {unknown}>
729 535..536 'S': S<i8, {unknown}>
735 fn coerce_unsize_trait_object_to_trait_object() {
736 // FIXME: The rust reference says this should be possible, but rustc doesn't
737 // implement it. We used to support it, but Chalk doesn't. Here's the
740 // 424..609 '{ ...bj2; }': ()
741 // 434..437 'obj': &dyn Baz<i8, i16>
742 // 459..461 '&S': &S<i8, i16>
743 // 460..461 'S': S<i8, i16>
744 // 471..474 'obj': &dyn Bar<usize, i8, i16>
745 // 496..499 'obj': &dyn Baz<i8, i16>
746 // 509..512 'obj': &dyn Foo<i8, usize>
747 // 531..534 'obj': &dyn Bar<usize, i8, i16>
748 // 544..548 'obj2': &dyn Baz<i8, i16>
749 // 570..572 '&S': &S<i8, i16>
750 // 571..572 'S': S<i8, i16>
751 // 582..583 '_': &dyn Foo<i8, usize>
752 // 602..606 'obj2': &dyn Baz<i8, i16>
753 check_infer_with_mismatches(
758 pub trait Unsize<T> {}
759 #[lang = "coerce_unsized"]
760 pub trait CoerceUnsized<T> {}
762 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
765 trait Bar<U, T, X>: Foo<T, U> {}
766 trait Baz<T, X>: Bar<usize, T, X> {}
769 impl<T, X> Foo<T, usize> for S<T, X> {}
770 impl<T, X> Bar<usize, T, X> for S<T, X> {}
771 impl<T, X> Baz<T, X> for S<T, X> {}
774 let obj: &dyn Baz<i8, i16> = &S;
775 let obj: &dyn Bar<_, _, _> = obj;
776 let obj: &dyn Foo<_, _> = obj;
777 let obj2: &dyn Baz<i8, i16> = &S;
778 let _: &dyn Foo<_, _> = obj2;
782 424..609 '{ ...bj2; }': ()
783 434..437 'obj': &dyn Baz<i8, i16>
784 459..461 '&S': &S<i8, i16>
785 460..461 'S': S<i8, i16>
786 471..474 'obj': &dyn Bar<{unknown}, {unknown}, {unknown}>
787 496..499 'obj': &dyn Baz<i8, i16>
788 509..512 'obj': &dyn Foo<{unknown}, {unknown}>
789 531..534 'obj': &dyn Bar<{unknown}, {unknown}, {unknown}>
790 544..548 'obj2': &dyn Baz<i8, i16>
791 570..572 '&S': &S<i8, i16>
792 571..572 'S': S<i8, i16>
793 582..583 '_': &dyn Foo<{unknown}, {unknown}>
794 602..606 'obj2': &dyn Baz<i8, i16>
795 496..499: expected &dyn Bar<{unknown}, {unknown}, {unknown}>, got &dyn Baz<i8, i16>
796 531..534: expected &dyn Foo<{unknown}, {unknown}>, got &dyn Bar<{unknown}, {unknown}, {unknown}>
797 602..606: expected &dyn Foo<{unknown}, {unknown}>, got &dyn Baz<i8, i16>
803 fn coerce_unsize_super_trait_cycle() {
804 check_infer_with_mismatches(
809 pub trait Unsize<T> {}
810 #[lang = "coerce_unsized"]
811 pub trait CoerceUnsized<T> {}
813 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
827 let obj: &dyn D = &S;
828 let obj: &dyn A = &S;
832 328..383 '{ ... &S; }': ()
833 338..341 'obj': &dyn D
836 364..367 'obj': &dyn A
844 fn coerce_unsize_generic() {
845 // FIXME: fix the type mismatches here
846 check_infer_with_mismatches(
849 pub trait Unsize<T> {}
850 #[lang = "coerce_unsized"]
851 pub trait CoerceUnsized<T> {}
853 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
855 struct Foo<T> { t: T };
856 struct Bar<T>(Foo<T>);
859 let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] };
860 let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] });
864 209..317 '{ ... }); }': ()
865 219..220 '_': &Foo<[usize]>
866 238..259 '&Foo {..., 3] }': &Foo<[usize]>
867 239..259 'Foo { ..., 3] }': Foo<[usize]>
868 248..257 '[1, 2, 3]': [usize; 3]
872 269..270 '_': &Bar<[usize]>
873 288..314 '&Bar(F... 3] })': &Bar<[i32; 3]>
874 289..292 'Bar': Bar<[i32; 3]>(Foo<[i32; 3]>) -> Bar<[i32; 3]>
875 289..314 'Bar(Fo... 3] })': Bar<[i32; 3]>
876 293..313 'Foo { ..., 3] }': Foo<[i32; 3]>
877 302..311 '[1, 2, 3]': [i32; 3]
881 248..257: expected [usize], got [usize; 3]
882 288..314: expected &Bar<[usize]>, got &Bar<[i32; 3]>
888 fn coerce_unsize_apit() {
890 check_infer_with_mismatches(
895 pub trait Unsize<T> {}
896 #[lang = "coerce_unsized"]
897 pub trait CoerceUnsized<T> {}
899 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
903 fn test(f: impl Foo) {
904 let _: &dyn Foo = &f;
908 210..211 'f': impl Foo
909 223..252 '{ ... &f; }': ()
910 233..234 '_': &dyn Foo
911 247..249 '&f': &impl Foo
912 248..249 'f': impl Foo
913 247..249: expected &dyn Foo, got &impl Foo
919 fn infer_two_closures_lub() {
923 let add = |a: i32, b: i32| a + b;
924 let sub = |a, b| a - b;
925 //^ |i32, i32| -> i32
926 if c > 42 { add } else { sub };
927 //^ fn(i32, i32) -> i32
934 fn infer_match_diverging_branch_1() {
937 enum Result<T> { Ok(T), Err }
938 fn parse<T>() -> T { loop {} }
941 let a = match parse() {
953 fn infer_match_diverging_branch_2() {
954 // same as 1 except for order of branches
957 enum Result<T> { Ok(T), Err }
958 fn parse<T>() -> T { loop {} }
961 let a = match parse() {
978 pub macro panic_2015 {
980 $crate::panicking::panic()
986 pub fn panic() -> ! { loop {} }
989 #[rustc_builtin_macro = "core_panic"]
991 // Expands to either `$crate::panic::panic_2015` or `$crate::panic::panic_2021`
992 // depending on the edition of the caller.
994 /* compiler built-in */
1006 fn coerce_unsize_expected_type() {
1007 check_no_mismatches(
1012 pub trait Unsize<T> {}
1013 #[lang = "coerce_unsized"]
1014 pub trait CoerceUnsized<T> {}
1016 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
1019 let foo: &[u32] = &[1, 2];
1020 let foo: &[u32] = match true {
1022 false => &[1, 2, 3],
1024 let foo: &[u32] = if true {