diff options
Diffstat (limited to 'crates/hir_ty/src/tests/coercion.rs')
-rw-r--r-- | crates/hir_ty/src/tests/coercion.rs | 673 |
1 files changed, 119 insertions, 554 deletions
diff --git a/crates/hir_ty/src/tests/coercion.rs b/crates/hir_ty/src/tests/coercion.rs index 713b74165..87089f09d 100644 --- a/crates/hir_ty/src/tests/coercion.rs +++ b/crates/hir_ty/src/tests/coercion.rs | |||
@@ -1,27 +1,22 @@ | |||
1 | use expect_test::expect; | 1 | use super::{check, check_no_mismatches, check_types}; |
2 | |||
3 | use super::{check_infer, check_infer_with_mismatches, check_no_mismatches, check_types}; | ||
4 | 2 | ||
5 | #[test] | 3 | #[test] |
6 | fn infer_block_expr_type_mismatch() { | 4 | fn block_expr_type_mismatch() { |
7 | check_infer( | 5 | // FIXME fix double type mismatch |
6 | check( | ||
8 | r" | 7 | r" |
9 | fn test() { | 8 | fn 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] |
23 | fn coerce_places() { | 18 | fn coerce_places() { |
24 | check_infer( | 19 | check_no_mismatches( |
25 | r#" | 20 | r#" |
26 | //- minicore: coerce_unsized | 21 | //- minicore: coerce_unsized |
27 | struct S<T> { a: T } | 22 | struct S<T> { a: T } |
@@ -46,81 +41,25 @@ fn test2() { | |||
46 | let g: (&[_], &[_]) = (arr, arr); | 41 | let g: (&[_], &[_]) = (arr, arr); |
47 | } | 42 | } |
48 | "#, | 43 | "#, |
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 | ); | 44 | ); |
96 | } | 45 | } |
97 | 46 | ||
98 | #[test] | 47 | #[test] |
99 | fn infer_let_stmt_coerce() { | 48 | fn let_stmt_coerce() { |
100 | check_infer( | 49 | check_no_mismatches( |
101 | r" | 50 | r" |
102 | fn test() { | 51 | //- minicore: coerce_unsized |
103 | let x: &[isize] = &[1]; | 52 | fn test() { |
104 | let x: *const [isize] = &[1]; | 53 | let x: &[isize] = &[1]; |
105 | } | 54 | let x: *const [isize] = &[1]; |
106 | ", | 55 | } |
107 | expect![[r#" | 56 | ", |
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 | ); | 57 | ); |
119 | } | 58 | } |
120 | 59 | ||
121 | #[test] | 60 | #[test] |
122 | fn infer_custom_coerce_unsized() { | 61 | fn custom_coerce_unsized() { |
123 | check_infer( | 62 | check( |
124 | r#" | 63 | r#" |
125 | //- minicore: coerce_unsized | 64 | //- minicore: coerce_unsized |
126 | use core::{marker::Unsize, ops::CoerceUnsized}; | 65 | use core::{marker::Unsize, ops::CoerceUnsized}; |
@@ -138,46 +77,22 @@ fn foo3<T>(x: C<[T]>) -> C<[T]> { x } | |||
138 | 77 | ||
139 | fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) { | 78 | fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) { |
140 | let d = foo1(a); | 79 | let d = foo1(a); |
80 | // ^ expected A<[{unknown}]>, got A<[u8; 2]> | ||
141 | let e = foo2(b); | 81 | let e = foo2(b); |
82 | // ^ type: B<[u8]> | ||
142 | let f = foo3(c); | 83 | let f = foo3(c); |
84 | // ^ type: C<[u8]> | ||
143 | } | 85 | } |
144 | "#, | 86 | "#, |
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 | ); | 87 | ); |
173 | } | 88 | } |
174 | 89 | ||
175 | #[test] | 90 | #[test] |
176 | fn infer_if_coerce() { | 91 | fn if_coerce() { |
177 | check_infer( | 92 | check_no_mismatches( |
178 | r#" | 93 | r#" |
179 | //- minicore: unsize | 94 | //- minicore: coerce_unsized |
180 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | 95 | fn foo<T>(x: &[T]) -> &[T] { x } |
181 | fn test() { | 96 | fn test() { |
182 | let x = if true { | 97 | let x = if true { |
183 | foo(&[1]) | 98 | foo(&[1]) |
@@ -186,35 +101,15 @@ fn test() { | |||
186 | }; | 101 | }; |
187 | } | 102 | } |
188 | "#, | 103 | "#, |
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 | ); | 104 | ); |
210 | } | 105 | } |
211 | 106 | ||
212 | #[test] | 107 | #[test] |
213 | fn infer_if_else_coerce() { | 108 | fn if_else_coerce() { |
214 | check_infer( | 109 | check_no_mismatches( |
215 | r#" | 110 | r#" |
216 | //- minicore: coerce_unsized | 111 | //- minicore: coerce_unsized |
217 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | 112 | fn foo<T>(x: &[T]) -> &[T] { x } |
218 | fn test() { | 113 | fn test() { |
219 | let x = if true { | 114 | let x = if true { |
220 | &[1] | 115 | &[1] |
@@ -223,35 +118,15 @@ fn test() { | |||
223 | }; | 118 | }; |
224 | } | 119 | } |
225 | "#, | 120 | "#, |
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 | ) | 121 | ) |
247 | } | 122 | } |
248 | 123 | ||
249 | #[test] | 124 | #[test] |
250 | fn infer_match_first_coerce() { | 125 | fn match_first_coerce() { |
251 | check_infer( | 126 | check_no_mismatches( |
252 | r#" | 127 | r#" |
253 | //- minicore: unsize | 128 | //- minicore: coerce_unsized |
254 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | 129 | fn foo<T>(x: &[T]) -> &[T] { x } |
255 | fn test(i: i32) { | 130 | fn test(i: i32) { |
256 | let x = match i { | 131 | let x = match i { |
257 | 2 => foo(&[2]), | 132 | 2 => foo(&[2]), |
@@ -260,39 +135,12 @@ fn test(i: i32) { | |||
260 | }; | 135 | }; |
261 | } | 136 | } |
262 | "#, | 137 | "#, |
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 | ); | 138 | ); |
291 | } | 139 | } |
292 | 140 | ||
293 | #[test] | 141 | #[test] |
294 | fn infer_match_second_coerce() { | 142 | fn match_second_coerce() { |
295 | check_infer( | 143 | check_no_mismatches( |
296 | r#" | 144 | r#" |
297 | //- minicore: coerce_unsized | 145 | //- minicore: coerce_unsized |
298 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | 146 | fn foo<T>(x: &[T]) -> &[T] { loop {} } |
@@ -304,33 +152,6 @@ fn test(i: i32) { | |||
304 | }; | 152 | }; |
305 | } | 153 | } |
306 | "#, | 154 | "#, |
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 | ); | 155 | ); |
335 | } | 156 | } |
336 | 157 | ||
@@ -338,94 +159,52 @@ fn test(i: i32) { | |||
338 | fn coerce_merge_one_by_one1() { | 159 | fn coerce_merge_one_by_one1() { |
339 | cov_mark::check!(coerce_merge_fail_fallback); | 160 | cov_mark::check!(coerce_merge_fail_fallback); |
340 | 161 | ||
341 | check_infer( | 162 | check( |
342 | r" | 163 | r" |
343 | fn test() { | 164 | fn test() { |
344 | let t = &mut 1; | 165 | let t = &mut 1; |
345 | let x = match 1 { | 166 | let x = match 1 { |
346 | 1 => t as *mut i32, | 167 | 1 => t as *mut i32, |
347 | 2 => t as &i32, | 168 | 2 => t as &i32, |
348 | _ => t as *const i32, | 169 | //^^^^^^^^^ expected *mut i32, got &i32 |
349 | }; | 170 | _ => t as *const i32, |
350 | } | 171 | }; |
172 | x; | ||
173 | //^ type: *const i32 | ||
174 | } | ||
351 | ", | 175 | ", |
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 | ); | 176 | ); |
373 | } | 177 | } |
374 | 178 | ||
375 | #[test] | 179 | #[test] |
376 | fn return_coerce_unknown() { | 180 | fn return_coerce_unknown() { |
377 | check_infer_with_mismatches( | 181 | check_types( |
378 | r" | 182 | r" |
379 | fn foo() -> u32 { | 183 | fn foo() -> u32 { |
380 | return unknown; | 184 | return unknown; |
381 | } | 185 | //^^^^^^^ u32 |
186 | } | ||
382 | ", | 187 | ", |
383 | expect![[r" | ||
384 | 16..39 '{ ...own; }': u32 | ||
385 | 22..36 'return unknown': ! | ||
386 | 29..36 'unknown': u32 | ||
387 | "]], | ||
388 | ); | 188 | ); |
389 | } | 189 | } |
390 | 190 | ||
391 | #[test] | 191 | #[test] |
392 | fn coerce_autoderef() { | 192 | fn coerce_autoderef() { |
393 | check_infer_with_mismatches( | 193 | check_no_mismatches( |
394 | r" | 194 | r" |
395 | struct Foo; | 195 | struct Foo; |
396 | fn takes_ref_foo(x: &Foo) {} | 196 | fn takes_ref_foo(x: &Foo) {} |
397 | fn test() { | 197 | fn test() { |
398 | takes_ref_foo(&Foo); | 198 | takes_ref_foo(&Foo); |
399 | takes_ref_foo(&&Foo); | 199 | takes_ref_foo(&&Foo); |
400 | takes_ref_foo(&&&Foo); | 200 | takes_ref_foo(&&&Foo); |
401 | } | 201 | }", |
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 | ); | 202 | ); |
424 | } | 203 | } |
425 | 204 | ||
426 | #[test] | 205 | #[test] |
427 | fn coerce_autoderef_generic() { | 206 | fn coerce_autoderef_generic() { |
428 | check_infer_with_mismatches( | 207 | check_no_mismatches( |
429 | r#" | 208 | r#" |
430 | struct Foo; | 209 | struct Foo; |
431 | fn takes_ref<T>(x: &T) -> T { *x } | 210 | fn takes_ref<T>(x: &T) -> T { *x } |
@@ -435,34 +214,12 @@ fn test() { | |||
435 | takes_ref(&&&Foo); | 214 | takes_ref(&&&Foo); |
436 | } | 215 | } |
437 | "#, | 216 | "#, |
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 | ); | 217 | ); |
461 | } | 218 | } |
462 | 219 | ||
463 | #[test] | 220 | #[test] |
464 | fn coerce_autoderef_block() { | 221 | fn coerce_autoderef_block() { |
465 | check_infer_with_mismatches( | 222 | check_no_mismatches( |
466 | r#" | 223 | r#" |
467 | //- minicore: deref | 224 | //- minicore: deref |
468 | struct String {} | 225 | struct String {} |
@@ -473,71 +230,32 @@ fn test() { | |||
473 | takes_ref_str(&{ returns_string() }); | 230 | takes_ref_str(&{ returns_string() }); |
474 | } | 231 | } |
475 | "#, | 232 | "#, |
476 | expect![[r#" | ||
477 | 90..91 'x': &str | ||
478 | 99..101 '{}': () | ||
479 | 132..143 '{ loop {} }': String | ||
480 | 134..141 'loop {}': ! | ||
481 | 139..141 '{}': () | ||
482 | 154..199 '{ ... }); }': () | ||
483 | 160..173 'takes_ref_str': fn takes_ref_str(&str) | ||
484 | 160..196 'takes_...g() })': () | ||
485 | 174..195 '&{ ret...ng() }': &String | ||
486 | 175..195 '{ retu...ng() }': String | ||
487 | 177..191 'returns_string': fn returns_string() -> String | ||
488 | 177..193 'return...ring()': String | ||
489 | "#]], | ||
490 | ); | 233 | ); |
491 | } | 234 | } |
492 | 235 | ||
493 | #[test] | 236 | #[test] |
494 | fn closure_return_coerce() { | 237 | fn closure_return_coerce() { |
495 | check_infer_with_mismatches( | 238 | check_no_mismatches( |
496 | r" | 239 | r" |
497 | fn foo() { | 240 | fn foo() { |
498 | let x = || { | 241 | let x = || { |
499 | if true { | 242 | if true { |
500 | return &1u32; | 243 | return &1u32; |
501 | } | ||
502 | &&1u32 | ||
503 | }; | ||
504 | } | 244 | } |
505 | ", | 245 | &&1u32 |
506 | expect![[r" | 246 | }; |
507 | 9..105 '{ ... }; }': () | 247 | }", |
508 | 19..20 'x': || -> &u32 | ||
509 | 23..102 '|| { ... }': || -> &u32 | ||
510 | 26..102 '{ ... }': &u32 | ||
511 | 36..81 'if tru... }': () | ||
512 | 39..43 'true': bool | ||
513 | 44..81 '{ ... }': () | ||
514 | 58..70 'return &1u32': ! | ||
515 | 65..70 '&1u32': &u32 | ||
516 | 66..70 '1u32': u32 | ||
517 | 90..96 '&&1u32': &&u32 | ||
518 | 91..96 '&1u32': &u32 | ||
519 | 92..96 '1u32': u32 | ||
520 | "]], | ||
521 | ); | 248 | ); |
522 | } | 249 | } |
523 | 250 | ||
524 | #[test] | 251 | #[test] |
525 | fn coerce_fn_item_to_fn_ptr() { | 252 | fn coerce_fn_item_to_fn_ptr() { |
526 | check_infer_with_mismatches( | 253 | check_no_mismatches( |
527 | r" | 254 | r" |
528 | fn foo(x: u32) -> isize { 1 } | 255 | fn foo(x: u32) -> isize { 1 } |
529 | fn test() { | 256 | fn test() { |
530 | let f: fn(u32) -> isize = foo; | 257 | let f: fn(u32) -> isize = foo; |
531 | } | 258 | }", |
532 | ", | ||
533 | expect![[r" | ||
534 | 7..8 'x': u32 | ||
535 | 24..29 '{ 1 }': isize | ||
536 | 26..27 '1': isize | ||
537 | 40..78 '{ ...foo; }': () | ||
538 | 50..51 'f': fn(u32) -> isize | ||
539 | 72..75 'foo': fn foo(u32) -> isize | ||
540 | "]], | ||
541 | ); | 259 | ); |
542 | } | 260 | } |
543 | 261 | ||
@@ -545,110 +263,62 @@ fn coerce_fn_item_to_fn_ptr() { | |||
545 | fn coerce_fn_items_in_match_arms() { | 263 | fn coerce_fn_items_in_match_arms() { |
546 | cov_mark::check!(coerce_fn_reification); | 264 | cov_mark::check!(coerce_fn_reification); |
547 | 265 | ||
548 | check_infer_with_mismatches( | 266 | check_types( |
549 | r" | 267 | r" |
550 | fn foo1(x: u32) -> isize { 1 } | 268 | fn foo1(x: u32) -> isize { 1 } |
551 | fn foo2(x: u32) -> isize { 2 } | 269 | fn foo2(x: u32) -> isize { 2 } |
552 | fn foo3(x: u32) -> isize { 3 } | 270 | fn foo3(x: u32) -> isize { 3 } |
553 | fn test() { | 271 | fn test() { |
554 | let x = match 1 { | 272 | let x = match 1 { |
555 | 1 => foo1, | 273 | 1 => foo1, |
556 | 2 => foo2, | 274 | 2 => foo2, |
557 | _ => foo3, | 275 | _ => foo3, |
558 | }; | 276 | }; |
559 | } | 277 | x; |
560 | ", | 278 | //^ fn(u32) -> isize |
561 | expect![[r" | 279 | }", |
562 | 8..9 'x': u32 | ||
563 | 25..30 '{ 1 }': isize | ||
564 | 27..28 '1': isize | ||
565 | 39..40 'x': u32 | ||
566 | 56..61 '{ 2 }': isize | ||
567 | 58..59 '2': isize | ||
568 | 70..71 'x': u32 | ||
569 | 87..92 '{ 3 }': isize | ||
570 | 89..90 '3': isize | ||
571 | 103..192 '{ ... }; }': () | ||
572 | 113..114 'x': fn(u32) -> isize | ||
573 | 117..189 'match ... }': fn(u32) -> isize | ||
574 | 123..124 '1': i32 | ||
575 | 135..136 '1': i32 | ||
576 | 135..136 '1': i32 | ||
577 | 140..144 'foo1': fn foo1(u32) -> isize | ||
578 | 154..155 '2': i32 | ||
579 | 154..155 '2': i32 | ||
580 | 159..163 'foo2': fn foo2(u32) -> isize | ||
581 | 173..174 '_': i32 | ||
582 | 178..182 'foo3': fn foo3(u32) -> isize | ||
583 | "]], | ||
584 | ); | 280 | ); |
585 | } | 281 | } |
586 | 282 | ||
587 | #[test] | 283 | #[test] |
588 | fn coerce_closure_to_fn_ptr() { | 284 | fn coerce_closure_to_fn_ptr() { |
589 | check_infer_with_mismatches( | 285 | check_no_mismatches( |
590 | r" | 286 | r" |
591 | fn test() { | 287 | fn test() { |
592 | let f: fn(u32) -> isize = |x| { 1 }; | 288 | let f: fn(u32) -> isize = |x| { 1 }; |
593 | } | 289 | }", |
594 | ", | ||
595 | expect![[r" | ||
596 | 10..54 '{ ...1 }; }': () | ||
597 | 20..21 'f': fn(u32) -> isize | ||
598 | 42..51 '|x| { 1 }': |u32| -> isize | ||
599 | 43..44 'x': u32 | ||
600 | 46..51 '{ 1 }': isize | ||
601 | 48..49 '1': isize | ||
602 | "]], | ||
603 | ); | 290 | ); |
604 | } | 291 | } |
605 | 292 | ||
606 | #[test] | 293 | #[test] |
607 | fn coerce_placeholder_ref() { | 294 | fn coerce_placeholder_ref() { |
608 | // placeholders should unify, even behind references | 295 | // placeholders should unify, even behind references |
609 | check_infer_with_mismatches( | 296 | check_no_mismatches( |
610 | r" | 297 | r" |
611 | struct S<T> { t: T } | 298 | struct S<T> { t: T } |
612 | impl<TT> S<TT> { | 299 | impl<TT> S<TT> { |
613 | fn get(&self) -> &TT { | 300 | fn get(&self) -> &TT { |
614 | &self.t | 301 | &self.t |
615 | } | 302 | } |
616 | } | 303 | }", |
617 | ", | ||
618 | expect![[r" | ||
619 | 50..54 'self': &S<TT> | ||
620 | 63..86 '{ ... }': &TT | ||
621 | 73..80 '&self.t': &TT | ||
622 | 74..78 'self': &S<TT> | ||
623 | 74..80 'self.t': TT | ||
624 | "]], | ||
625 | ); | 304 | ); |
626 | } | 305 | } |
627 | 306 | ||
628 | #[test] | 307 | #[test] |
629 | fn coerce_unsize_array() { | 308 | fn coerce_unsize_array() { |
630 | check_infer_with_mismatches( | 309 | check_types( |
631 | r#" | 310 | r#" |
632 | //- minicore: coerce_unsized | 311 | //- minicore: coerce_unsized |
633 | fn test() { | 312 | fn test() { |
634 | let f: &[usize] = &[1, 2, 3]; | 313 | let f: &[usize] = &[1, 2, 3]; |
635 | } | 314 | //^ usize |
636 | "#, | 315 | }"#, |
637 | expect![[r#" | ||
638 | 10..47 '{ ... 3]; }': () | ||
639 | 20..21 'f': &[usize] | ||
640 | 34..44 '&[1, 2, 3]': &[usize; 3] | ||
641 | 35..44 '[1, 2, 3]': [usize; 3] | ||
642 | 36..37 '1': usize | ||
643 | 39..40 '2': usize | ||
644 | 42..43 '3': usize | ||
645 | "#]], | ||
646 | ); | 316 | ); |
647 | } | 317 | } |
648 | 318 | ||
649 | #[test] | 319 | #[test] |
650 | fn coerce_unsize_trait_object_simple() { | 320 | fn coerce_unsize_trait_object_simple() { |
651 | check_infer_with_mismatches( | 321 | check_types( |
652 | r#" | 322 | r#" |
653 | //- minicore: coerce_unsized | 323 | //- minicore: coerce_unsized |
654 | trait Foo<T, U> {} | 324 | trait Foo<T, U> {} |
@@ -662,88 +332,18 @@ impl<T, X> Baz<T, X> for S<T, X> {} | |||
662 | 332 | ||
663 | fn test() { | 333 | fn test() { |
664 | let obj: &dyn Baz<i8, i16> = &S; | 334 | let obj: &dyn Baz<i8, i16> = &S; |
335 | //^ S<i8, i16> | ||
665 | let obj: &dyn Bar<_, i8, i16> = &S; | 336 | let obj: &dyn Bar<_, i8, i16> = &S; |
337 | //^ S<i8, i16> | ||
666 | let obj: &dyn Foo<i8, _> = &S; | 338 | let obj: &dyn Foo<i8, _> = &S; |
667 | } | 339 | //^ S<i8, {unknown}> |
668 | "#, | 340 | }"#, |
669 | expect![[r#" | ||
670 | 236..351 '{ ... &S; }': () | ||
671 | 246..249 'obj': &dyn Baz<i8, i16> | ||
672 | 271..273 '&S': &S<i8, i16> | ||
673 | 272..273 'S': S<i8, i16> | ||
674 | 283..286 'obj': &dyn Bar<usize, i8, i16> | ||
675 | 311..313 '&S': &S<i8, i16> | ||
676 | 312..313 'S': S<i8, i16> | ||
677 | 323..326 'obj': &dyn Foo<i8, usize> | ||
678 | 346..348 '&S': &S<i8, {unknown}> | ||
679 | 347..348 'S': S<i8, {unknown}> | ||
680 | "#]], | ||
681 | ); | ||
682 | } | ||
683 | |||
684 | #[test] | ||
685 | fn coerce_unsize_trait_object_to_trait_object() { | ||
686 | // FIXME: The rust reference says this should be possible, but rustc doesn't | ||
687 | // implement it. We used to support it, but Chalk doesn't. Here's the | ||
688 | // correct expect: | ||
689 | // | ||
690 | // 424..609 '{ ...bj2; }': () | ||
691 | // 434..437 'obj': &dyn Baz<i8, i16> | ||
692 | // 459..461 '&S': &S<i8, i16> | ||
693 | // 460..461 'S': S<i8, i16> | ||
694 | // 471..474 'obj': &dyn Bar<usize, i8, i16> | ||
695 | // 496..499 'obj': &dyn Baz<i8, i16> | ||
696 | // 509..512 'obj': &dyn Foo<i8, usize> | ||
697 | // 531..534 'obj': &dyn Bar<usize, i8, i16> | ||
698 | // 544..548 'obj2': &dyn Baz<i8, i16> | ||
699 | // 570..572 '&S': &S<i8, i16> | ||
700 | // 571..572 'S': S<i8, i16> | ||
701 | // 582..583 '_': &dyn Foo<i8, usize> | ||
702 | // 602..606 'obj2': &dyn Baz<i8, i16> | ||
703 | check_infer_with_mismatches( | ||
704 | r#" | ||
705 | //- minicore: coerce_unsized | ||
706 | trait Foo<T, U> {} | ||
707 | trait Bar<U, T, X>: Foo<T, U> {} | ||
708 | trait Baz<T, X>: Bar<usize, T, X> {} | ||
709 | |||
710 | struct S<T, X>; | ||
711 | impl<T, X> Foo<T, usize> for S<T, X> {} | ||
712 | impl<T, X> Bar<usize, T, X> for S<T, X> {} | ||
713 | impl<T, X> Baz<T, X> for S<T, X> {} | ||
714 | |||
715 | fn test() { | ||
716 | let obj: &dyn Baz<i8, i16> = &S; | ||
717 | let obj: &dyn Bar<_, _, _> = obj; | ||
718 | let obj: &dyn Foo<_, _> = obj; | ||
719 | let obj2: &dyn Baz<i8, i16> = &S; | ||
720 | let _: &dyn Foo<_, _> = obj2; | ||
721 | } | ||
722 | "#, | ||
723 | expect![[r#" | ||
724 | 236..421 '{ ...bj2; }': () | ||
725 | 246..249 'obj': &dyn Baz<i8, i16> | ||
726 | 271..273 '&S': &S<i8, i16> | ||
727 | 272..273 'S': S<i8, i16> | ||
728 | 283..286 'obj': &dyn Bar<{unknown}, {unknown}, {unknown}> | ||
729 | 308..311 'obj': &dyn Baz<i8, i16> | ||
730 | 321..324 'obj': &dyn Foo<{unknown}, {unknown}> | ||
731 | 343..346 'obj': &dyn Bar<{unknown}, {unknown}, {unknown}> | ||
732 | 356..360 'obj2': &dyn Baz<i8, i16> | ||
733 | 382..384 '&S': &S<i8, i16> | ||
734 | 383..384 'S': S<i8, i16> | ||
735 | 394..395 '_': &dyn Foo<{unknown}, {unknown}> | ||
736 | 414..418 'obj2': &dyn Baz<i8, i16> | ||
737 | 308..311: expected &dyn Bar<{unknown}, {unknown}, {unknown}>, got &dyn Baz<i8, i16> | ||
738 | 343..346: expected &dyn Foo<{unknown}, {unknown}>, got &dyn Bar<{unknown}, {unknown}, {unknown}> | ||
739 | 414..418: expected &dyn Foo<{unknown}, {unknown}>, got &dyn Baz<i8, i16> | ||
740 | "#]], | ||
741 | ); | 341 | ); |
742 | } | 342 | } |
743 | 343 | ||
744 | #[test] | 344 | #[test] |
745 | fn coerce_unsize_super_trait_cycle() { | 345 | fn coerce_unsize_super_trait_cycle() { |
746 | check_infer_with_mismatches( | 346 | check_no_mismatches( |
747 | r#" | 347 | r#" |
748 | //- minicore: coerce_unsized | 348 | //- minicore: coerce_unsized |
749 | trait A {} | 349 | trait A {} |
@@ -762,22 +362,13 @@ fn test() { | |||
762 | let obj: &dyn A = &S; | 362 | let obj: &dyn A = &S; |
763 | } | 363 | } |
764 | "#, | 364 | "#, |
765 | expect![[r#" | ||
766 | 140..195 '{ ... &S; }': () | ||
767 | 150..153 'obj': &dyn D | ||
768 | 164..166 '&S': &S | ||
769 | 165..166 'S': S | ||
770 | 176..179 'obj': &dyn A | ||
771 | 190..192 '&S': &S | ||
772 | 191..192 'S': S | ||
773 | "#]], | ||
774 | ); | 365 | ); |
775 | } | 366 | } |
776 | 367 | ||
777 | #[test] | 368 | #[test] |
778 | fn coerce_unsize_generic() { | 369 | fn coerce_unsize_generic() { |
779 | // FIXME: fix the type mismatches here | 370 | // FIXME: fix the type mismatches here |
780 | check_infer_with_mismatches( | 371 | check( |
781 | r#" | 372 | r#" |
782 | //- minicore: coerce_unsized | 373 | //- minicore: coerce_unsized |
783 | struct Foo<T> { t: T }; | 374 | struct Foo<T> { t: T }; |
@@ -785,73 +376,47 @@ struct Bar<T>(Foo<T>); | |||
785 | 376 | ||
786 | fn test() { | 377 | fn test() { |
787 | let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] }; | 378 | let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] }; |
379 | //^^^^^^^^^ expected [usize], got [usize; 3] | ||
788 | let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] }); | 380 | let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] }); |
381 | //^^^^^^^^^^^^^^^^^^^^^^^^^^ expected &Bar<[usize]>, got &Bar<[i32; 3]> | ||
789 | } | 382 | } |
790 | "#, | 383 | "#, |
791 | expect![[r#" | ||
792 | 58..166 '{ ... }); }': () | ||
793 | 68..69 '_': &Foo<[usize]> | ||
794 | 87..108 '&Foo {..., 3] }': &Foo<[usize]> | ||
795 | 88..108 'Foo { ..., 3] }': Foo<[usize]> | ||
796 | 97..106 '[1, 2, 3]': [usize; 3] | ||
797 | 98..99 '1': usize | ||
798 | 101..102 '2': usize | ||
799 | 104..105 '3': usize | ||
800 | 118..119 '_': &Bar<[usize]> | ||
801 | 137..163 '&Bar(F... 3] })': &Bar<[i32; 3]> | ||
802 | 138..141 'Bar': Bar<[i32; 3]>(Foo<[i32; 3]>) -> Bar<[i32; 3]> | ||
803 | 138..163 'Bar(Fo... 3] })': Bar<[i32; 3]> | ||
804 | 142..162 'Foo { ..., 3] }': Foo<[i32; 3]> | ||
805 | 151..160 '[1, 2, 3]': [i32; 3] | ||
806 | 152..153 '1': i32 | ||
807 | 155..156 '2': i32 | ||
808 | 158..159 '3': i32 | ||
809 | 97..106: expected [usize], got [usize; 3] | ||
810 | 137..163: expected &Bar<[usize]>, got &Bar<[i32; 3]> | ||
811 | "#]], | ||
812 | ); | 384 | ); |
813 | } | 385 | } |
814 | 386 | ||
815 | #[test] | 387 | #[test] |
816 | fn coerce_unsize_apit() { | 388 | fn coerce_unsize_apit() { |
817 | // FIXME: #8984 | 389 | // FIXME: #8984 |
818 | check_infer_with_mismatches( | 390 | check( |
819 | r#" | 391 | r#" |
820 | //- minicore: coerce_unsized | 392 | //- minicore: coerce_unsized |
821 | trait Foo {} | 393 | trait Foo {} |
822 | 394 | ||
823 | fn test(f: impl Foo) { | 395 | fn test(f: impl Foo) { |
824 | let _: &dyn Foo = &f; | 396 | let _: &dyn Foo = &f; |
397 | //^^ expected &dyn Foo, got &impl Foo | ||
825 | } | 398 | } |
826 | "#, | 399 | "#, |
827 | expect![[r#" | ||
828 | 22..23 'f': impl Foo | ||
829 | 35..64 '{ ... &f; }': () | ||
830 | 45..46 '_': &dyn Foo | ||
831 | 59..61 '&f': &impl Foo | ||
832 | 60..61 'f': impl Foo | ||
833 | 59..61: expected &dyn Foo, got &impl Foo | ||
834 | "#]], | ||
835 | ); | 400 | ); |
836 | } | 401 | } |
837 | 402 | ||
838 | #[test] | 403 | #[test] |
839 | fn infer_two_closures_lub() { | 404 | fn two_closures_lub() { |
840 | check_types( | 405 | check_types( |
841 | r#" | 406 | r#" |
842 | fn foo(c: i32) { | 407 | fn foo(c: i32) { |
843 | let add = |a: i32, b: i32| a + b; | 408 | let add = |a: i32, b: i32| a + b; |
844 | let sub = |a, b| a - b; | 409 | let sub = |a, b| a - b; |
845 | //^ |i32, i32| -> i32 | 410 | //^^^^^^^^^^^^ |i32, i32| -> i32 |
846 | if c > 42 { add } else { sub }; | 411 | if c > 42 { add } else { sub }; |
847 | //^ fn(i32, i32) -> i32 | 412 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ fn(i32, i32) -> i32 |
848 | } | 413 | } |
849 | "#, | 414 | "#, |
850 | ) | 415 | ) |
851 | } | 416 | } |
852 | 417 | ||
853 | #[test] | 418 | #[test] |
854 | fn infer_match_diverging_branch_1() { | 419 | fn match_diverging_branch_1() { |
855 | check_types( | 420 | check_types( |
856 | r#" | 421 | r#" |
857 | enum Result<T> { Ok(T), Err } | 422 | enum Result<T> { Ok(T), Err } |
@@ -870,7 +435,7 @@ fn test() -> i32 { | |||
870 | } | 435 | } |
871 | 436 | ||
872 | #[test] | 437 | #[test] |
873 | fn infer_match_diverging_branch_2() { | 438 | fn match_diverging_branch_2() { |
874 | // same as 1 except for order of branches | 439 | // same as 1 except for order of branches |
875 | check_types( | 440 | check_types( |
876 | r#" | 441 | r#" |