1 use super::{check, check_no_mismatches, check_types};
4 fn block_expr_type_mismatch() {
5 // FIXME fix double type mismatch
10 // ^^^^^^^^ expected i32, got i64
11 // ^^^^ expected i32, got i64
21 //- minicore: coerce_unsized
24 fn f<T>(_: &[T]) -> T { loop {} }
25 fn g<T>(_: S<&[T]>) -> T { loop {} }
27 fn gen<T>() -> *mut [T; 2] { loop {} }
28 fn test1<U>() -> *mut [U] {
33 let arr: &[u8; 1] = &[1];
37 let c: &[_] = { arr };
38 let d = g(S { a: arr });
39 let e: [&[_]; 1] = [arr];
40 let f: [&[_]; 2] = [arr; 2];
41 let g: (&[_], &[_]) = (arr, arr);
48 fn let_stmt_coerce() {
51 //- minicore: coerce_unsized
53 let x: &[isize] = &[1];
54 // ^^^^ adjustments: Deref(None), Borrow(Ref(Not)), Pointer(Unsize)
55 let x: *const [isize] = &[1];
56 // ^^^^ adjustments: Deref(None), Borrow(RawPtr(Not)), Pointer(Unsize)
63 fn custom_coerce_unsized() {
66 //- minicore: coerce_unsized
67 use core::{marker::Unsize, ops::CoerceUnsized};
69 struct A<T: ?Sized>(*const T);
70 struct B<T: ?Sized>(*const T);
71 struct C<T: ?Sized> { inner: *const T }
73 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {}
74 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {}
76 fn foo1<T>(x: A<[T]>) -> A<[T]> { x }
77 fn foo2<T>(x: B<[T]>) -> B<[T]> { x }
78 fn foo3<T>(x: C<[T]>) -> C<[T]> { x }
80 fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) {
82 // ^ expected A<[{unknown}]>, got A<[u8; 2]>
96 //- minicore: coerce_unsized
97 fn foo<T>(x: &[T]) -> &[T] { x }
101 // ^^^^ adjustments: Deref(None), Borrow(Ref(Not)), Pointer(Unsize)
111 fn if_else_coerce() {
114 //- minicore: coerce_unsized
115 fn foo<T>(x: &[T]) -> &[T] { x }
128 fn match_first_coerce() {
131 //- minicore: coerce_unsized
132 fn foo<T>(x: &[T]) -> &[T] { x }
136 // ^^^^ adjustments: Deref(None), Borrow(Ref(Not)), Pointer(Unsize)
146 fn match_second_coerce() {
149 //- minicore: coerce_unsized
150 fn foo<T>(x: &[T]) -> &[T] { loop {} }
151 // ^^^^^^^ adjustments: NeverToAny
164 fn coerce_merge_one_by_one1() {
165 cov_mark::check!(coerce_merge_fail_fallback);
174 //^^^^^^^^^ expected *mut i32, got &i32
175 _ => t as *const i32,
176 // ^^^^^^^^^^^^^^^ adjustments: Pointer(MutToConstPointer)
188 fn return_coerce_unknown() {
200 fn coerce_autoderef() {
204 fn takes_ref_foo(x: &Foo) {}
207 takes_ref_foo(&&Foo);
208 takes_ref_foo(&&&Foo);
214 fn coerce_autoderef_generic() {
218 fn takes_ref<T>(x: &T) -> T { *x }
229 fn coerce_autoderef_block() {
234 impl core::ops::Deref for String { type Target = str; }
235 fn takes_ref_str(x: &str) {}
236 fn returns_string() -> String { loop {} }
238 takes_ref_str(&{ returns_string() });
239 // ^^^^^^^^^^^^^^^^^^^^^ adjustments: Deref(None), Deref(Some(OverloadedDeref(Not))), Borrow(Ref(Not))
246 fn coerce_autoderef_implication_1() {
251 impl core::ops::Deref for Foo<u32> { type Target = (); }
253 fn takes_ref_foo<T>(x: &Foo<T>) {}
256 //^^^ type: Foo<{unknown}>
267 fn coerce_autoderef_implication_2() {
272 impl core::ops::Deref for Foo<u32> { type Target = (); }
274 fn takes_ref_foo<T>(x: &Foo<T>) {}
277 //^^^ type: Foo<{unknown}>
279 //^^^^ expected &u32, got &Foo<{unknown}>
285 fn closure_return_coerce() {
305 impl core::ops::Deref for String { type Target = str; }
318 fn coerce_fn_item_to_fn_ptr() {
321 fn foo(x: u32) -> isize { 1 }
323 let f: fn(u32) -> isize = foo;
324 // ^^^ adjustments: Pointer(ReifyFnPointer)
325 let f: unsafe fn(u32) -> isize = foo;
326 // ^^^ adjustments: Pointer(ReifyFnPointer)
332 fn coerce_fn_items_in_match_arms() {
333 cov_mark::check!(coerce_fn_reification);
337 fn foo1(x: u32) -> isize { 1 }
338 fn foo2(x: u32) -> isize { 2 }
339 fn foo3(x: u32) -> isize { 3 }
353 fn coerce_closure_to_fn_ptr() {
357 let f: fn(u32) -> isize = |x| { 1 };
363 fn coerce_placeholder_ref() {
364 // placeholders should unify, even behind references
369 fn get(&self) -> &TT {
377 fn coerce_unsize_array() {
380 //- minicore: coerce_unsized
382 let f: &[usize] = &[1, 2, 3];
389 fn coerce_unsize_trait_object_simple() {
392 //- minicore: coerce_unsized
394 trait Bar<U, T, X>: Foo<T, U> {}
395 trait Baz<T, X>: Bar<usize, T, X> {}
398 impl<T, X> Foo<T, usize> for S<T, X> {}
399 impl<T, X> Bar<usize, T, X> for S<T, X> {}
400 impl<T, X> Baz<T, X> for S<T, X> {}
403 let obj: &dyn Baz<i8, i16> = &S;
405 let obj: &dyn Bar<_, i8, i16> = &S;
407 let obj: &dyn Foo<i8, _> = &S;
414 fn coerce_unsize_super_trait_cycle() {
417 //- minicore: coerce_unsized
430 let obj: &dyn D = &S;
431 let obj: &dyn A = &S;
438 fn coerce_unsize_generic() {
439 // FIXME: fix the type mismatches here
442 //- minicore: coerce_unsized
443 struct Foo<T> { t: T };
444 struct Bar<T>(Foo<T>);
447 let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] };
448 //^^^^^^^^^ expected [usize], got [usize; 3]
449 let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] });
450 //^^^^^^^^^ expected [usize], got [usize; 3]
457 fn coerce_unsize_apit() {
460 //- minicore: coerce_unsized
463 fn test(f: impl Foo, g: &(impl Foo + ?Sized)) {
464 let _: &dyn Foo = &f;
466 //^ expected &dyn Foo, got &impl Foo + ?Sized
473 fn two_closures_lub() {
477 let add = |a: i32, b: i32| a + b;
478 let sub = |a, b| a - b;
479 //^^^^^^^^^^^^ |i32, i32| -> i32
480 if c > 42 { add } else { sub };
481 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ fn(i32, i32) -> i32
488 fn match_diverging_branch_1() {
491 enum Result<T> { Ok(T), Err }
492 fn parse<T>() -> T { loop {} }
495 let a = match parse() {
507 fn match_diverging_branch_2() {
508 // same as 1 except for order of branches
511 enum Result<T> { Ok(T), Err }
512 fn parse<T>() -> T { loop {} }
515 let a = match parse() {
532 pub macro panic_2015 {
534 $crate::panicking::panic()
540 pub fn panic() -> ! { loop {} }
543 #[rustc_builtin_macro = "core_panic"]
545 // Expands to either `$crate::panic::panic_2015` or `$crate::panic::panic_2021`
546 // depending on the edition of the caller.
548 /* compiler built-in */
560 fn coerce_unsize_expected_type_1() {
563 //- minicore: coerce_unsized
565 let foo: &[u32] = &[1, 2];
566 let foo: &[u32] = match true {
570 let foo: &[u32] = if true {
581 fn coerce_unsize_expected_type_2() {
584 //- minicore: coerce_unsized
587 fn with_value<U>(self, value: U) -> InFile<U> { InFile }
591 impl AstNode for RecordField {}
593 fn takes_dyn(it: InFile<&dyn AstNode>) {}
596 let x: InFile<()> = InFile;
597 let n = &RecordField;
598 takes_dyn(x.with_value(n));
605 fn coerce_unsize_expected_type_3() {
608 //- minicore: coerce_unsized
609 enum Option<T> { Some(T), None }
612 impl AstNode for RecordField {}
614 fn takes_dyn(it: Option<&dyn AstNode>) {}
617 let x: InFile<()> = InFile;
618 let n = &RecordField;
619 takes_dyn(Option::Some(n));
626 fn coerce_unsize_expected_type_4() {
629 //- minicore: coerce_unsized
630 use core::{marker::Unsize, ops::CoerceUnsized};
632 struct B<T: ?Sized>(*const T);
633 impl<T: ?Sized> B<T> {
634 fn new(t: T) -> Self { B(&t) }
637 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {}
640 let _: B<[isize]> = B::new({ [1, 2, 3] });
647 fn coerce_array_elems_lub() {
661 fn coerce_type_var() {
664 //- minicore: from, coerce_unsized
667 let _: &() = &x.into();
674 fn coerce_overloaded_binary_op_rhs() {
677 //- minicore: deref, add
680 impl core::ops::Deref for String { type Target = str; }
682 impl core::ops::Add<&str> for String {
683 type Output = String;