1 use super::infer_with_mismatches;
2 use insta::assert_snapshot;
3 use test_utils::covers;
5 // Infer with some common definitions and impls.
6 fn infer(source: &str) -> String {
11 pub trait Unsize<T: ?Sized> {}
12 #[lang = "coerce_unsized"]
13 pub trait CoerceUnsized<T> {}
15 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
16 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
19 // Append to the end to keep positions unchanged.
20 super::infer(&format!("{}{}", source, defs))
24 fn infer_block_expr_type_mismatch() {
28 let a: i32 = { 1i64 };
32 [11; 41) '{ ...4 }; }': ()
34 [30; 38) '{ 1i64 }': i64
45 fn f<T>(_: &[T]) -> T { loop {} }
46 fn g<T>(_: S<&[T]>) -> T { loop {} }
48 fn gen<T>() -> *mut [T; 2] { loop {} }
49 fn test1<U>() -> *mut [U] {
54 let arr: &[u8; 1] = &[1];
58 let c: &[_] = { arr };
59 let d = g(S { a: arr });
60 let e: [&[_]; 1] = [arr];
61 let f: [&[_]; 2] = [arr; 2];
62 let g: (&[_], &[_]) = (arr, arr);
67 [45; 56) '{ loop {} }': T
71 [82; 93) '{ loop {} }': T
74 [122; 133) '{ loop {} }': *mut [T;_]
75 [124; 131) 'loop {}': !
77 [160; 173) '{ gen() }': *mut [U]
78 [166; 169) 'gen': fn gen<U>() -> *mut [T;_]
79 [166; 171) 'gen()': *mut [U;_]
80 [186; 420) '{ ...rr); }': ()
81 [196; 199) 'arr': &[u8;_]
82 [212; 216) '&[1]': &[u8;_]
83 [213; 216) '[1]': [u8;_]
86 [237; 240) 'arr': &[u8;_]
88 [254; 255) 'f': fn f<u8>(&[T]) -> T
89 [254; 260) 'f(arr)': u8
90 [256; 259) 'arr': &[u8;_]
92 [280; 287) '{ arr }': &[u8]
93 [282; 285) 'arr': &[u8;_]
95 [301; 302) 'g': fn g<u8>(S<&[T]>) -> T
96 [301; 316) 'g(S { a: arr })': u8
97 [303; 315) 'S { a: arr }': S<&[u8]>
98 [310; 313) 'arr': &[u8;_]
99 [326; 327) 'e': [&[u8];_]
100 [341; 346) '[arr]': [&[u8];_]
101 [342; 345) 'arr': &[u8;_]
102 [356; 357) 'f': [&[u8];_]
103 [371; 379) '[arr; 2]': [&[u8];_]
104 [372; 375) 'arr': &[u8;_]
105 [377; 378) '2': usize
106 [389; 390) 'g': (&[u8], &[u8])
107 [407; 417) '(arr, arr)': (&[u8], &[u8])
108 [408; 411) 'arr': &[u8;_]
109 [413; 416) 'arr': &[u8;_]
115 fn infer_let_stmt_coerce() {
119 let x: &[i32] = &[1];
123 [11; 40) '{ ...[1]; }': ()
125 [33; 37) '&[1]': &[i32;_]
126 [34; 37) '[1]': [i32;_]
132 fn infer_custom_coerce_unsized() {
135 struct A<T: ?Sized>(*const T);
136 struct B<T: ?Sized>(*const T);
137 struct C<T: ?Sized> { inner: *const T }
139 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {}
140 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {}
142 fn foo1<T>(x: A<[T]>) -> A<[T]> { x }
143 fn foo2<T>(x: B<[T]>) -> B<[T]> { x }
144 fn foo3<T>(x: C<[T]>) -> C<[T]> { x }
146 fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) {
153 [258; 259) 'x': A<[T]>
154 [279; 284) '{ x }': A<[T]>
155 [281; 282) 'x': A<[T]>
156 [296; 297) 'x': B<[T]>
157 [317; 322) '{ x }': B<[T]>
158 [319; 320) 'x': B<[T]>
159 [334; 335) 'x': C<[T]>
160 [355; 360) '{ x }': C<[T]>
161 [357; 358) 'x': C<[T]>
162 [370; 371) 'a': A<[u8;_]>
163 [385; 386) 'b': B<[u8;_]>
164 [400; 401) 'c': C<[u8;_]>
165 [415; 481) '{ ...(c); }': ()
166 [425; 426) 'd': A<[{unknown}]>
167 [429; 433) 'foo1': fn foo1<{unknown}>(A<[T]>) -> A<[T]>
168 [429; 436) 'foo1(a)': A<[{unknown}]>
169 [434; 435) 'a': A<[u8;_]>
170 [446; 447) 'e': B<[u8]>
171 [450; 454) 'foo2': fn foo2<u8>(B<[T]>) -> B<[T]>
172 [450; 457) 'foo2(b)': B<[u8]>
173 [455; 456) 'b': B<[u8;_]>
174 [467; 468) 'f': C<[u8]>
175 [471; 475) 'foo3': fn foo3<u8>(C<[T]>) -> C<[T]>
176 [471; 478) 'foo3(c)': C<[u8]>
177 [476; 477) 'c': C<[u8;_]>
183 fn infer_if_coerce() {
186 fn foo<T>(x: &[T]) -> &[T] { loop {} }
197 [28; 39) '{ loop {} }': &[T]
198 [30; 37) 'loop {}': !
200 [50; 126) '{ ... }; }': ()
202 [64; 123) 'if tru... }': &[i32]
203 [67; 71) 'true': bool
204 [72; 97) '{ ... }': &[i32]
205 [82; 85) 'foo': fn foo<i32>(&[T]) -> &[T]
206 [82; 91) 'foo(&[1])': &[i32]
207 [86; 90) '&[1]': &[i32;_]
208 [87; 90) '[1]': [i32;_]
210 [103; 123) '{ ... }': &[i32;_]
211 [113; 117) '&[1]': &[i32;_]
212 [114; 117) '[1]': [i32;_]
219 fn infer_if_else_coerce() {
222 fn foo<T>(x: &[T]) -> &[T] { loop {} }
233 [28; 39) '{ loop {} }': &[T]
234 [30; 37) 'loop {}': !
236 [50; 126) '{ ... }; }': ()
238 [64; 123) 'if tru... }': &[i32]
239 [67; 71) 'true': bool
240 [72; 92) '{ ... }': &[i32;_]
241 [82; 86) '&[1]': &[i32;_]
242 [83; 86) '[1]': [i32;_]
244 [98; 123) '{ ... }': &[i32]
245 [108; 111) 'foo': fn foo<i32>(&[T]) -> &[T]
246 [108; 117) 'foo(&[1])': &[i32]
247 [112; 116) '&[1]': &[i32;_]
248 [113; 116) '[1]': [i32;_]
255 fn infer_match_first_coerce() {
258 fn foo<T>(x: &[T]) -> &[T] { loop {} }
269 [28; 39) '{ loop {} }': &[T]
270 [30; 37) 'loop {}': !
273 [56; 150) '{ ... }; }': ()
275 [70; 147) 'match ... }': &[i32]
278 [93; 96) 'foo': fn foo<i32>(&[T]) -> &[T]
279 [93; 102) 'foo(&[2])': &[i32]
280 [97; 101) '&[2]': &[i32;_]
281 [98; 101) '[2]': [i32;_]
284 [117; 121) '&[1]': &[i32;_]
285 [118; 121) '[1]': [i32;_]
288 [136; 140) '&[3]': &[i32;_]
289 [137; 140) '[3]': [i32;_]
296 fn infer_match_second_coerce() {
299 fn foo<T>(x: &[T]) -> &[T] { loop {} }
310 [28; 39) '{ loop {} }': &[T]
311 [30; 37) 'loop {}': !
314 [56; 150) '{ ... }; }': ()
316 [70; 147) 'match ... }': &[i32]
319 [93; 97) '&[1]': &[i32;_]
320 [94; 97) '[1]': [i32;_]
323 [112; 115) 'foo': fn foo<i32>(&[T]) -> &[T]
324 [112; 121) 'foo(&[2])': &[i32]
325 [116; 120) '&[2]': &[i32;_]
326 [117; 120) '[2]': [i32;_]
329 [136; 140) '&[3]': &[i32;_]
330 [137; 140) '[3]': [i32;_]
337 fn coerce_merge_one_by_one1() {
338 covers!(coerce_merge_fail_fallback);
347 _ => t as *const i32,
352 [11; 145) '{ ... }; }': ()
353 [21; 22) 't': &mut i32
354 [25; 31) '&mut 1': &mut i32
356 [41; 42) 'x': *const i32
357 [45; 142) 'match ... }': *const i32
360 [68; 69) 't': &mut i32
361 [68; 81) 't as *mut i32': *mut i32
363 [96; 97) 't': &mut i32
364 [96; 105) 't as &i32': &i32
366 [120; 121) 't': &mut i32
367 [120; 135) 't as *const i32': *const i32
373 fn return_coerce_unknown() {
375 infer_with_mismatches(r#"
381 [17; 40) '{ ...own; }': !
382 [23; 37) 'return unknown': !
383 [30; 37) 'unknown': u32
389 fn coerce_autoderef() {
391 infer_with_mismatches(r#"
393 fn takes_ref_foo(x: &Foo) {}
396 takes_ref_foo(&&Foo);
397 takes_ref_foo(&&&Foo);
403 [52; 133) '{ ...oo); }': ()
404 [58; 71) 'takes_ref_foo': fn takes_ref_foo(&Foo) -> ()
405 [58; 77) 'takes_...(&Foo)': ()
406 [72; 76) '&Foo': &Foo
408 [83; 96) 'takes_ref_foo': fn takes_ref_foo(&Foo) -> ()
409 [83; 103) 'takes_...&&Foo)': ()
410 [97; 102) '&&Foo': &&Foo
411 [98; 102) '&Foo': &Foo
413 [109; 122) 'takes_ref_foo': fn takes_ref_foo(&Foo) -> ()
414 [109; 130) 'takes_...&&Foo)': ()
415 [123; 129) '&&&Foo': &&&Foo
416 [124; 129) '&&Foo': &&Foo
417 [125; 129) '&Foo': &Foo
418 [126; 129) 'Foo': Foo
424 fn coerce_autoderef_generic() {
426 infer_with_mismatches(r#"
428 fn takes_ref<T>(x: &T) -> T { *x }
440 [58; 127) '{ ...oo); }': ()
441 [64; 73) 'takes_ref': fn takes_ref<Foo>(&T) -> T
442 [64; 79) 'takes_ref(&Foo)': Foo
443 [74; 78) '&Foo': &Foo
445 [85; 94) 'takes_ref': fn takes_ref<&Foo>(&T) -> T
446 [85; 101) 'takes_...&&Foo)': &Foo
447 [95; 100) '&&Foo': &&Foo
448 [96; 100) '&Foo': &Foo
450 [107; 116) 'takes_ref': fn takes_ref<&&Foo>(&T) -> T
451 [107; 124) 'takes_...&&Foo)': &&Foo
452 [117; 123) '&&&Foo': &&&Foo
453 [118; 123) '&&Foo': &&Foo
454 [119; 123) '&Foo': &Foo
455 [120; 123) 'Foo': Foo
461 fn closure_return_coerce() {
463 infer_with_mismatches(r#"
474 [10; 106) '{ ... }; }': ()
475 [20; 21) 'x': || -> &u32
476 [24; 103) '|| { ... }': || -> &u32
477 [27; 103) '{ ... }': &u32
478 [37; 82) 'if tru... }': ()
479 [40; 44) 'true': bool
480 [45; 82) '{ ... }': !
481 [59; 71) 'return &1u32': !
482 [66; 71) '&1u32': &u32
484 [91; 97) '&&1u32': &&u32
485 [92; 97) '&1u32': &u32