aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/tests/coercion.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/tests/coercion.rs')
-rw-r--r--crates/hir_ty/src/tests/coercion.rs1017
1 files changed, 251 insertions, 766 deletions
diff --git a/crates/hir_ty/src/tests/coercion.rs b/crates/hir_ty/src/tests/coercion.rs
index 71047703d..87089f09d 100644
--- a/crates/hir_ty/src/tests/coercion.rs
+++ b/crates/hir_ty/src/tests/coercion.rs
@@ -1,380 +1,157 @@
1use expect_test::expect; 1use super::{check, check_no_mismatches, check_types};
2
3use super::{check_infer, check_infer_with_mismatches, check_no_mismatches, check_types};
4 2
5#[test] 3#[test]
6fn infer_block_expr_type_mismatch() { 4fn block_expr_type_mismatch() {
7 check_infer( 5 // FIXME fix double type mismatch
6 check(
8 r" 7 r"
9 fn test() { 8fn test() {
10 let a: i32 = { 1i64 }; 9 let a: i32 = { 1i64 };
11 } 10 // ^^^^^^^^ expected i32, got i64
11 // ^^^^ expected i32, got i64
12}
12 ", 13 ",
13 expect![[r"
14 10..40 '{ ...4 }; }': ()
15 20..21 'a': i32
16 29..37 '{ 1i64 }': i64
17 31..35 '1i64': i64
18 "]],
19 ); 14 );
20} 15}
21 16
22#[test] 17#[test]
23fn coerce_places() { 18fn coerce_places() {
24 check_infer( 19 check_no_mismatches(
25 r#" 20 r#"
26 struct S<T> { a: T } 21//- minicore: coerce_unsized
22struct S<T> { a: T }
27 23
28 fn f<T>(_: &[T]) -> T { loop {} } 24fn f<T>(_: &[T]) -> T { loop {} }
29 fn g<T>(_: S<&[T]>) -> T { loop {} } 25fn g<T>(_: S<&[T]>) -> T { loop {} }
30 26
31 fn gen<T>() -> *mut [T; 2] { loop {} } 27fn gen<T>() -> *mut [T; 2] { loop {} }
32 fn test1<U>() -> *mut [U] { 28fn test1<U>() -> *mut [U] {
33 gen() 29 gen()
34 } 30}
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 31
48 #[lang = "sized"] 32fn test2() {
49 pub trait Sized {} 33 let arr: &[u8; 1] = &[1];
50 #[lang = "unsize"]
51 pub trait Unsize<T: ?Sized> {}
52 #[lang = "coerce_unsized"]
53 pub trait CoerceUnsized<T> {}
54 34
55 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} 35 let a: &[_] = arr;
56 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} 36 let b = f(arr);
57 "#, 37 let c: &[_] = { arr };
58 expect![[r#" 38 let d = g(S { a: arr });
59 30..31 '_': &[T] 39 let e: [&[_]; 1] = [arr];
60 44..55 '{ loop {} }': T 40 let f: [&[_]; 2] = [arr; 2];
61 46..53 'loop {}': ! 41 let g: (&[_], &[_]) = (arr, arr);
62 51..53 '{}': () 42}
63 64..65 '_': S<&[T]> 43"#,
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 ); 44 );
105} 45}
106 46
107#[test] 47#[test]
108fn infer_let_stmt_coerce() { 48fn let_stmt_coerce() {
109 check_infer( 49 check_no_mismatches(
110 r" 50 r"
111 fn test() { 51//- minicore: coerce_unsized
112 let x: &[isize] = &[1]; 52fn test() {
113 let x: *const [isize] = &[1]; 53 let x: &[isize] = &[1];
114 } 54 let x: *const [isize] = &[1];
115 ", 55}
116 expect![[r#" 56",
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 ); 57 );
128} 58}
129 59
130#[test] 60#[test]
131fn infer_custom_coerce_unsized() { 61fn custom_coerce_unsized() {
132 check_infer( 62 check(
133 r#" 63 r#"
134 struct A<T: ?Sized>(*const T); 64//- minicore: coerce_unsized
135 struct B<T: ?Sized>(*const T); 65use core::{marker::Unsize, ops::CoerceUnsized};
136 struct C<T: ?Sized> { inner: *const T }
137 66
138 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {} 67struct A<T: ?Sized>(*const T);
139 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {} 68struct B<T: ?Sized>(*const T);
69struct C<T: ?Sized> { inner: *const T }
140 70
141 fn foo1<T>(x: A<[T]>) -> A<[T]> { x } 71impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {}
142 fn foo2<T>(x: B<[T]>) -> B<[T]> { x } 72impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {}
143 fn foo3<T>(x: C<[T]>) -> C<[T]> { x }
144 73
145 fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) { 74fn foo1<T>(x: A<[T]>) -> A<[T]> { x }
146 let d = foo1(a); 75fn foo2<T>(x: B<[T]>) -> B<[T]> { x }
147 let e = foo2(b); 76fn foo3<T>(x: C<[T]>) -> C<[T]> { x }
148 let f = foo3(c);
149 }
150 77
151 78fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) {
152 #[lang = "sized"] 79 let d = foo1(a);
153 pub trait Sized {} 80 // ^ expected A<[{unknown}]>, got A<[u8; 2]>
154 #[lang = "unsize"] 81 let e = foo2(b);
155 pub trait Unsize<T: ?Sized> {} 82 // ^ type: B<[u8]>
156 #[lang = "coerce_unsized"] 83 let f = foo3(c);
157 pub trait CoerceUnsized<T> {} 84 // ^ type: C<[u8]>
158 85}
159 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} 86"#,
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 ); 87 );
190} 88}
191 89
192#[test] 90#[test]
193fn infer_if_coerce() { 91fn if_coerce() {
194 check_infer( 92 check_no_mismatches(
195 r#" 93 r#"
196 fn foo<T>(x: &[T]) -> &[T] { loop {} } 94//- minicore: coerce_unsized
197 fn test() { 95fn foo<T>(x: &[T]) -> &[T] { x }
198 let x = if true { 96fn test() {
199 foo(&[1]) 97 let x = if true {
200 } else { 98 foo(&[1])
201 &[1] 99 } else {
202 }; 100 &[1]
203 } 101 };
204 102}
205 103"#,
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 ); 104 );
232} 105}
233 106
234#[test] 107#[test]
235fn infer_if_else_coerce() { 108fn if_else_coerce() {
236 check_infer( 109 check_no_mismatches(
237 r#" 110 r#"
238 fn foo<T>(x: &[T]) -> &[T] { loop {} } 111//- minicore: coerce_unsized
239 fn test() { 112fn foo<T>(x: &[T]) -> &[T] { x }
240 let x = if true { 113fn test() {
241 &[1] 114 let x = if true {
242 } else { 115 &[1]
243 foo(&[1]) 116 } else {
244 }; 117 foo(&[1])
245 } 118 };
246 119}
247 #[lang = "sized"] 120"#,
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 ) 121 )
278} 122}
279 123
280#[test] 124#[test]
281fn infer_match_first_coerce() { 125fn match_first_coerce() {
282 check_infer( 126 check_no_mismatches(
283 r#" 127 r#"
284 fn foo<T>(x: &[T]) -> &[T] { loop {} } 128//- minicore: coerce_unsized
285 fn test(i: i32) { 129fn foo<T>(x: &[T]) -> &[T] { x }
286 let x = match i { 130fn test(i: i32) {
287 2 => foo(&[2]), 131 let x = match i {
288 1 => &[1], 132 2 => foo(&[2]),
289 _ => &[3], 133 1 => &[1],
290 }; 134 _ => &[3],
291 } 135 };
292 136}
293 #[lang = "sized"] 137"#,
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 ); 138 );
326} 139}
327 140
328#[test] 141#[test]
329fn infer_match_second_coerce() { 142fn match_second_coerce() {
330 check_infer( 143 check_no_mismatches(
331 r#" 144 r#"
332 fn foo<T>(x: &[T]) -> &[T] { loop {} } 145//- minicore: coerce_unsized
333 fn test(i: i32) { 146fn foo<T>(x: &[T]) -> &[T] { loop {} }
334 let x = match i { 147fn test(i: i32) {
335 1 => &[1], 148 let x = match i {
336 2 => foo(&[2]), 149 1 => &[1],
337 _ => &[3], 150 2 => foo(&[2]),
338 }; 151 _ => &[3],
339 } 152 };
340 153}
341 #[lang = "sized"] 154"#,
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 ); 155 );
379} 156}
380 157
@@ -382,207 +159,103 @@ fn infer_match_second_coerce() {
382fn coerce_merge_one_by_one1() { 159fn coerce_merge_one_by_one1() {
383 cov_mark::check!(coerce_merge_fail_fallback); 160 cov_mark::check!(coerce_merge_fail_fallback);
384 161
385 check_infer( 162 check(
386 r" 163 r"
387 fn test() { 164fn test() {
388 let t = &mut 1; 165 let t = &mut 1;
389 let x = match 1 { 166 let x = match 1 {
390 1 => t as *mut i32, 167 1 => t as *mut i32,
391 2 => t as &i32, 168 2 => t as &i32,
392 _ => t as *const i32, 169 //^^^^^^^^^ expected *mut i32, got &i32
393 }; 170 _ => t as *const i32,
394 } 171 };
172 x;
173 //^ type: *const i32
174}
395 ", 175 ",
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 ); 176 );
417} 177}
418 178
419#[test] 179#[test]
420fn return_coerce_unknown() { 180fn return_coerce_unknown() {
421 check_infer_with_mismatches( 181 check_types(
422 r" 182 r"
423 fn foo() -> u32 { 183fn foo() -> u32 {
424 return unknown; 184 return unknown;
425 } 185 //^^^^^^^ u32
186}
426 ", 187 ",
427 expect![[r"
428 16..39 '{ ...own; }': u32
429 22..36 'return unknown': !
430 29..36 'unknown': u32
431 "]],
432 ); 188 );
433} 189}
434 190
435#[test] 191#[test]
436fn coerce_autoderef() { 192fn coerce_autoderef() {
437 check_infer_with_mismatches( 193 check_no_mismatches(
438 r" 194 r"
439 struct Foo; 195struct Foo;
440 fn takes_ref_foo(x: &Foo) {} 196fn takes_ref_foo(x: &Foo) {}
441 fn test() { 197fn test() {
442 takes_ref_foo(&Foo); 198 takes_ref_foo(&Foo);
443 takes_ref_foo(&&Foo); 199 takes_ref_foo(&&Foo);
444 takes_ref_foo(&&&Foo); 200 takes_ref_foo(&&&Foo);
445 } 201}",
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 ); 202 );
468} 203}
469 204
470#[test] 205#[test]
471fn coerce_autoderef_generic() { 206fn coerce_autoderef_generic() {
472 check_infer_with_mismatches( 207 check_no_mismatches(
473 r" 208 r#"
474 struct Foo; 209struct Foo;
475 fn takes_ref<T>(x: &T) -> T { *x } 210fn takes_ref<T>(x: &T) -> T { *x }
476 fn test() { 211fn test() {
477 takes_ref(&Foo); 212 takes_ref(&Foo);
478 takes_ref(&&Foo); 213 takes_ref(&&Foo);
479 takes_ref(&&&Foo); 214 takes_ref(&&&Foo);
480 } 215}
481 ", 216"#,
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 ); 217 );
505} 218}
506 219
507#[test] 220#[test]
508fn coerce_autoderef_block() { 221fn coerce_autoderef_block() {
509 check_infer_with_mismatches( 222 check_no_mismatches(
510 r#" 223 r#"
511 struct String {} 224//- minicore: deref
512 #[lang = "deref"] 225struct String {}
513 trait Deref { type Target; } 226impl core::ops::Deref for String { type Target = str; }
514 impl Deref for String { type Target = str; } 227fn takes_ref_str(x: &str) {}
515 fn takes_ref_str(x: &str) {} 228fn returns_string() -> String { loop {} }
516 fn returns_string() -> String { loop {} } 229fn test() {
517 fn test() { 230 takes_ref_str(&{ returns_string() });
518 takes_ref_str(&{ returns_string() }); 231}
519 } 232"#,
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 ); 233 );
536} 234}
537 235
538#[test] 236#[test]
539fn closure_return_coerce() { 237fn closure_return_coerce() {
540 check_infer_with_mismatches( 238 check_no_mismatches(
541 r" 239 r"
542 fn foo() { 240fn foo() {
543 let x = || { 241 let x = || {
544 if true { 242 if true {
545 return &1u32; 243 return &1u32;
546 }
547 &&1u32
548 };
549 } 244 }
550 ", 245 &&1u32
551 expect![[r" 246 };
552 9..105 '{ ... }; }': () 247}",
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 ); 248 );
567} 249}
568 250
569#[test] 251#[test]
570fn coerce_fn_item_to_fn_ptr() { 252fn coerce_fn_item_to_fn_ptr() {
571 check_infer_with_mismatches( 253 check_no_mismatches(
572 r" 254 r"
573 fn foo(x: u32) -> isize { 1 } 255fn foo(x: u32) -> isize { 1 }
574 fn test() { 256fn test() {
575 let f: fn(u32) -> isize = foo; 257 let f: fn(u32) -> isize = foo;
576 } 258}",
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 ); 259 );
587} 260}
588 261
@@ -590,340 +263,160 @@ fn coerce_fn_item_to_fn_ptr() {
590fn coerce_fn_items_in_match_arms() { 263fn coerce_fn_items_in_match_arms() {
591 cov_mark::check!(coerce_fn_reification); 264 cov_mark::check!(coerce_fn_reification);
592 265
593 check_infer_with_mismatches( 266 check_types(
594 r" 267 r"
595 fn foo1(x: u32) -> isize { 1 } 268fn foo1(x: u32) -> isize { 1 }
596 fn foo2(x: u32) -> isize { 2 } 269fn foo2(x: u32) -> isize { 2 }
597 fn foo3(x: u32) -> isize { 3 } 270fn foo3(x: u32) -> isize { 3 }
598 fn test() { 271fn test() {
599 let x = match 1 { 272 let x = match 1 {
600 1 => foo1, 273 1 => foo1,
601 2 => foo2, 274 2 => foo2,
602 _ => foo3, 275 _ => foo3,
603 }; 276 };
604 } 277 x;
605 ", 278 //^ fn(u32) -> isize
606 expect![[r" 279}",
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 ); 280 );
630} 281}
631 282
632#[test] 283#[test]
633fn coerce_closure_to_fn_ptr() { 284fn coerce_closure_to_fn_ptr() {
634 check_infer_with_mismatches( 285 check_no_mismatches(
635 r" 286 r"
636 fn test() { 287fn test() {
637 let f: fn(u32) -> isize = |x| { 1 }; 288 let f: fn(u32) -> isize = |x| { 1 };
638 } 289}",
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 ); 290 );
649} 291}
650 292
651#[test] 293#[test]
652fn coerce_placeholder_ref() { 294fn coerce_placeholder_ref() {
653 // placeholders should unify, even behind references 295 // placeholders should unify, even behind references
654 check_infer_with_mismatches( 296 check_no_mismatches(
655 r" 297 r"
656 struct S<T> { t: T } 298struct S<T> { t: T }
657 impl<TT> S<TT> { 299impl<TT> S<TT> {
658 fn get(&self) -> &TT { 300 fn get(&self) -> &TT {
659 &self.t 301 &self.t
660 } 302 }
661 } 303}",
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 ); 304 );
671} 305}
672 306
673#[test] 307#[test]
674fn coerce_unsize_array() { 308fn coerce_unsize_array() {
675 check_infer_with_mismatches( 309 check_types(
676 r#" 310 r#"
677 #[lang = "unsize"] 311//- minicore: coerce_unsized
678 pub trait Unsize<T> {} 312fn test() {
679 #[lang = "coerce_unsized"] 313 let f: &[usize] = &[1, 2, 3];
680 pub trait CoerceUnsized<T> {} 314 //^ usize
681 315}"#,
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 ); 316 );
698} 317}
699 318
700#[test] 319#[test]
701fn coerce_unsize_trait_object_simple() { 320fn coerce_unsize_trait_object_simple() {
702 check_infer_with_mismatches( 321 check_types(
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]
747fn coerce_unsize_trait_object_to_trait_object() {
748 check_infer_with_mismatches(
749 r#" 322 r#"
750 #[lang = "sized"] 323//- minicore: coerce_unsized
751 pub trait Sized {} 324trait Foo<T, U> {}
752 #[lang = "unsize"] 325trait Bar<U, T, X>: Foo<T, U> {}
753 pub trait Unsize<T> {} 326trait Baz<T, X>: Bar<usize, T, X> {}
754 #[lang = "coerce_unsized"] 327
755 pub trait CoerceUnsized<T> {} 328struct S<T, X>;
756 329impl<T, X> Foo<T, usize> for S<T, X> {}
757 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} 330impl<T, X> Bar<usize, T, X> for S<T, X> {}
758 331impl<T, X> Baz<T, X> for S<T, X> {}
759 trait Foo<T, U> {} 332
760 trait Bar<U, T, X>: Foo<T, U> {} 333fn test() {
761 trait Baz<T, X>: Bar<usize, T, X> {} 334 let obj: &dyn Baz<i8, i16> = &S;
762 335 //^ S<i8, i16>
763 struct S<T, X>; 336 let obj: &dyn Bar<_, i8, i16> = &S;
764 impl<T, X> Foo<T, usize> for S<T, X> {} 337 //^ S<i8, i16>
765 impl<T, X> Bar<usize, T, X> for S<T, X> {} 338 let obj: &dyn Foo<i8, _> = &S;
766 impl<T, X> Baz<T, X> for S<T, X> {} 339 //^ S<i8, {unknown}>
767 340}"#,
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 ); 341 );
792} 342}
793 343
794#[test] 344#[test]
795fn coerce_unsize_super_trait_cycle() { 345fn coerce_unsize_super_trait_cycle() {
796 check_infer_with_mismatches( 346 check_no_mismatches(
797 r#" 347 r#"
798 #[lang = "sized"] 348//- minicore: coerce_unsized
799 pub trait Sized {} 349trait A {}
800 #[lang = "unsize"] 350trait B: C + A {}
801 pub trait Unsize<T> {} 351trait C: B {}
802 #[lang = "coerce_unsized"] 352trait D: C
803 pub trait CoerceUnsized<T> {} 353
804 354struct S;
805 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} 355impl A for S {}
806 356impl B for S {}
807 trait A {} 357impl C for S {}
808 trait B: C + A {} 358impl D for S {}
809 trait C: B {} 359
810 trait D: C 360fn test() {
811 361 let obj: &dyn D = &S;
812 struct S; 362 let obj: &dyn A = &S;
813 impl A for S {} 363}
814 impl B for S {} 364"#,
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 ); 365 );
833} 366}
834 367
835#[test] 368#[test]
836fn coerce_unsize_generic() { 369fn coerce_unsize_generic() {
837 // FIXME: fix the type mismatches here 370 // FIXME: fix the type mismatches here
838 check_infer_with_mismatches( 371 check(
839 r#" 372 r#"
840 #[lang = "unsize"] 373//- minicore: coerce_unsized
841 pub trait Unsize<T> {} 374struct Foo<T> { t: T };
842 #[lang = "coerce_unsized"] 375struct Bar<T>(Foo<T>);
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 376
850 fn test() { 377fn test() {
851 let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] }; 378 let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] };
852 let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] }); 379 //^^^^^^^^^ expected [usize], got [usize; 3]
853 } 380 let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] });
854 "#, 381 //^^^^^^^^^^^^^^^^^^^^^^^^^^ expected &Bar<[usize]>, got &Bar<[i32; 3]>
855 expect![[r#" 382}
856 209..317 '{ ... }); }': () 383"#,
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 ); 384 );
877} 385}
878 386
879#[test] 387#[test]
880fn coerce_unsize_apit() { 388fn coerce_unsize_apit() {
881 // FIXME: #8984 389 // FIXME: #8984
882 check_infer_with_mismatches( 390 check(
883 r#" 391 r#"
884#[lang = "sized"] 392//- minicore: coerce_unsized
885pub trait Sized {}
886#[lang = "unsize"]
887pub trait Unsize<T> {}
888#[lang = "coerce_unsized"]
889pub trait CoerceUnsized<T> {}
890
891impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
892
893trait Foo {} 393trait Foo {}
894 394
895fn test(f: impl Foo) { 395fn test(f: impl Foo) {
896 let _: &dyn Foo = &f; 396 let _: &dyn Foo = &f;
397 //^^ expected &dyn Foo, got &impl Foo
897} 398}
898 "#, 399 "#,
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 ); 400 );
908} 401}
909 402
910#[test] 403#[test]
911fn infer_two_closures_lub() { 404fn two_closures_lub() {
912 check_types( 405 check_types(
913 r#" 406 r#"
914fn foo(c: i32) { 407fn foo(c: i32) {
915 let add = |a: i32, b: i32| a + b; 408 let add = |a: i32, b: i32| a + b;
916 let sub = |a, b| a - b; 409 let sub = |a, b| a - b;
917 //^ |i32, i32| -> i32 410 //^^^^^^^^^^^^ |i32, i32| -> i32
918 if c > 42 { add } else { sub }; 411 if c > 42 { add } else { sub };
919 //^ fn(i32, i32) -> i32 412 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ fn(i32, i32) -> i32
920} 413}
921 "#, 414 "#,
922 ) 415 )
923} 416}
924 417
925#[test] 418#[test]
926fn infer_match_diverging_branch_1() { 419fn match_diverging_branch_1() {
927 check_types( 420 check_types(
928 r#" 421 r#"
929enum Result<T> { Ok(T), Err } 422enum Result<T> { Ok(T), Err }
@@ -942,7 +435,7 @@ fn test() -> i32 {
942} 435}
943 436
944#[test] 437#[test]
945fn infer_match_diverging_branch_2() { 438fn match_diverging_branch_2() {
946 // same as 1 except for order of branches 439 // same as 1 except for order of branches
947 check_types( 440 check_types(
948 r#" 441 r#"
@@ -998,15 +491,7 @@ fn main() {
998fn coerce_unsize_expected_type() { 491fn coerce_unsize_expected_type() {
999 check_no_mismatches( 492 check_no_mismatches(
1000 r#" 493 r#"
1001#[lang = "sized"] 494//- minicore: coerce_unsized
1002pub trait Sized {}
1003#[lang = "unsize"]
1004pub trait Unsize<T> {}
1005#[lang = "coerce_unsized"]
1006pub trait CoerceUnsized<T> {}
1007
1008impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
1009
1010fn main() { 495fn main() {
1011 let foo: &[u32] = &[1, 2]; 496 let foo: &[u32] = &[1, 2];
1012 let foo: &[u32] = match true { 497 let foo: &[u32] = match true {