diff options
Diffstat (limited to 'crates/hir_ty/src/tests/coercion.rs')
-rw-r--r-- | crates/hir_ty/src/tests/coercion.rs | 1017 |
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 @@ | |||
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 | struct S<T> { a: T } | 21 | //- minicore: coerce_unsized |
22 | struct S<T> { a: T } | ||
27 | 23 | ||
28 | fn f<T>(_: &[T]) -> T { loop {} } | 24 | fn f<T>(_: &[T]) -> T { loop {} } |
29 | fn g<T>(_: S<&[T]>) -> T { loop {} } | 25 | fn g<T>(_: S<&[T]>) -> T { loop {} } |
30 | 26 | ||
31 | fn gen<T>() -> *mut [T; 2] { loop {} } | 27 | fn gen<T>() -> *mut [T; 2] { loop {} } |
32 | fn test1<U>() -> *mut [U] { | 28 | fn 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"] | 32 | fn 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] |
108 | fn infer_let_stmt_coerce() { | 48 | fn 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]; | 52 | fn 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] |
131 | fn infer_custom_coerce_unsized() { | 61 | fn 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); | 65 | use 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> {} | 67 | struct A<T: ?Sized>(*const T); |
139 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {} | 68 | struct B<T: ?Sized>(*const T); |
69 | struct C<T: ?Sized> { inner: *const T } | ||
140 | 70 | ||
141 | fn foo1<T>(x: A<[T]>) -> A<[T]> { x } | 71 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {} |
142 | fn foo2<T>(x: B<[T]>) -> B<[T]> { x } | 72 | impl<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]>) { | 74 | fn foo1<T>(x: A<[T]>) -> A<[T]> { x } |
146 | let d = foo1(a); | 75 | fn foo2<T>(x: B<[T]>) -> B<[T]> { x } |
147 | let e = foo2(b); | 76 | fn foo3<T>(x: C<[T]>) -> C<[T]> { x } |
148 | let f = foo3(c); | ||
149 | } | ||
150 | 77 | ||
151 | 78 | fn 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] |
193 | fn infer_if_coerce() { | 91 | fn 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() { | 95 | fn foo<T>(x: &[T]) -> &[T] { x } |
198 | let x = if true { | 96 | fn 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] |
235 | fn infer_if_else_coerce() { | 108 | fn 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() { | 112 | fn foo<T>(x: &[T]) -> &[T] { x } |
240 | let x = if true { | 113 | fn 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] |
281 | fn infer_match_first_coerce() { | 125 | fn 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) { | 129 | fn foo<T>(x: &[T]) -> &[T] { x } |
286 | let x = match i { | 130 | fn 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] |
329 | fn infer_match_second_coerce() { | 142 | fn 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) { | 146 | fn foo<T>(x: &[T]) -> &[T] { loop {} } |
334 | let x = match i { | 147 | fn 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() { | |||
382 | fn coerce_merge_one_by_one1() { | 159 | fn 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() { | 164 | fn 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] |
420 | fn return_coerce_unknown() { | 180 | fn return_coerce_unknown() { |
421 | check_infer_with_mismatches( | 181 | check_types( |
422 | r" | 182 | r" |
423 | fn foo() -> u32 { | 183 | fn 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] |
436 | fn coerce_autoderef() { | 192 | fn coerce_autoderef() { |
437 | check_infer_with_mismatches( | 193 | check_no_mismatches( |
438 | r" | 194 | r" |
439 | struct Foo; | 195 | struct Foo; |
440 | fn takes_ref_foo(x: &Foo) {} | 196 | fn takes_ref_foo(x: &Foo) {} |
441 | fn test() { | 197 | fn 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] |
471 | fn coerce_autoderef_generic() { | 206 | fn coerce_autoderef_generic() { |
472 | check_infer_with_mismatches( | 207 | check_no_mismatches( |
473 | r" | 208 | r#" |
474 | struct Foo; | 209 | struct Foo; |
475 | fn takes_ref<T>(x: &T) -> T { *x } | 210 | fn takes_ref<T>(x: &T) -> T { *x } |
476 | fn test() { | 211 | fn 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] |
508 | fn coerce_autoderef_block() { | 221 | fn 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"] | 225 | struct String {} |
513 | trait Deref { type Target; } | 226 | impl core::ops::Deref for String { type Target = str; } |
514 | impl Deref for String { type Target = str; } | 227 | fn takes_ref_str(x: &str) {} |
515 | fn takes_ref_str(x: &str) {} | 228 | fn returns_string() -> String { loop {} } |
516 | fn returns_string() -> String { loop {} } | 229 | fn 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] |
539 | fn closure_return_coerce() { | 237 | fn closure_return_coerce() { |
540 | check_infer_with_mismatches( | 238 | check_no_mismatches( |
541 | r" | 239 | r" |
542 | fn foo() { | 240 | fn 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] |
570 | fn coerce_fn_item_to_fn_ptr() { | 252 | fn 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 } | 255 | fn foo(x: u32) -> isize { 1 } |
574 | fn test() { | 256 | fn 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() { | |||
590 | fn coerce_fn_items_in_match_arms() { | 263 | fn 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 } | 268 | fn foo1(x: u32) -> isize { 1 } |
596 | fn foo2(x: u32) -> isize { 2 } | 269 | fn foo2(x: u32) -> isize { 2 } |
597 | fn foo3(x: u32) -> isize { 3 } | 270 | fn foo3(x: u32) -> isize { 3 } |
598 | fn test() { | 271 | fn 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] |
633 | fn coerce_closure_to_fn_ptr() { | 284 | fn coerce_closure_to_fn_ptr() { |
634 | check_infer_with_mismatches( | 285 | check_no_mismatches( |
635 | r" | 286 | r" |
636 | fn test() { | 287 | fn 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] |
652 | fn coerce_placeholder_ref() { | 294 | fn 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 } | 298 | struct S<T> { t: T } |
657 | impl<TT> S<TT> { | 299 | impl<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] |
674 | fn coerce_unsize_array() { | 308 | fn 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> {} | 312 | fn 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] |
701 | fn coerce_unsize_trait_object_simple() { | 320 | fn 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] | ||
747 | fn 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 {} | 324 | trait Foo<T, U> {} |
752 | #[lang = "unsize"] | 325 | trait Bar<U, T, X>: Foo<T, U> {} |
753 | pub trait Unsize<T> {} | 326 | trait Baz<T, X>: Bar<usize, T, X> {} |
754 | #[lang = "coerce_unsized"] | 327 | |
755 | pub trait CoerceUnsized<T> {} | 328 | struct S<T, X>; |
756 | 329 | impl<T, X> Foo<T, usize> for S<T, X> {} | |
757 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | 330 | impl<T, X> Bar<usize, T, X> for S<T, X> {} |
758 | 331 | impl<T, X> Baz<T, X> for S<T, X> {} | |
759 | trait Foo<T, U> {} | 332 | |
760 | trait Bar<U, T, X>: Foo<T, U> {} | 333 | fn 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] |
795 | fn coerce_unsize_super_trait_cycle() { | 345 | fn 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 {} | 349 | trait A {} |
800 | #[lang = "unsize"] | 350 | trait B: C + A {} |
801 | pub trait Unsize<T> {} | 351 | trait C: B {} |
802 | #[lang = "coerce_unsized"] | 352 | trait D: C |
803 | pub trait CoerceUnsized<T> {} | 353 | |
804 | 354 | struct S; | |
805 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | 355 | impl A for S {} |
806 | 356 | impl B for S {} | |
807 | trait A {} | 357 | impl C for S {} |
808 | trait B: C + A {} | 358 | impl D for S {} |
809 | trait C: B {} | 359 | |
810 | trait D: C | 360 | fn 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] |
836 | fn coerce_unsize_generic() { | 369 | fn 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> {} | 374 | struct Foo<T> { t: T }; |
842 | #[lang = "coerce_unsized"] | 375 | struct 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() { | 377 | fn 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] |
880 | fn coerce_unsize_apit() { | 388 | fn 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 |
885 | pub trait Sized {} | ||
886 | #[lang = "unsize"] | ||
887 | pub trait Unsize<T> {} | ||
888 | #[lang = "coerce_unsized"] | ||
889 | pub trait CoerceUnsized<T> {} | ||
890 | |||
891 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | ||
892 | |||
893 | trait Foo {} | 393 | trait Foo {} |
894 | 394 | ||
895 | fn test(f: impl Foo) { | 395 | fn 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] |
911 | fn infer_two_closures_lub() { | 404 | fn two_closures_lub() { |
912 | check_types( | 405 | check_types( |
913 | r#" | 406 | r#" |
914 | fn foo(c: i32) { | 407 | fn 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] |
926 | fn infer_match_diverging_branch_1() { | 419 | fn match_diverging_branch_1() { |
927 | check_types( | 420 | check_types( |
928 | r#" | 421 | r#" |
929 | enum Result<T> { Ok(T), Err } | 422 | enum Result<T> { Ok(T), Err } |
@@ -942,7 +435,7 @@ fn test() -> i32 { | |||
942 | } | 435 | } |
943 | 436 | ||
944 | #[test] | 437 | #[test] |
945 | fn infer_match_diverging_branch_2() { | 438 | fn 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() { | |||
998 | fn coerce_unsize_expected_type() { | 491 | fn coerce_unsize_expected_type() { |
999 | check_no_mismatches( | 492 | check_no_mismatches( |
1000 | r#" | 493 | r#" |
1001 | #[lang = "sized"] | 494 | //- minicore: coerce_unsized |
1002 | pub trait Sized {} | ||
1003 | #[lang = "unsize"] | ||
1004 | pub trait Unsize<T> {} | ||
1005 | #[lang = "coerce_unsized"] | ||
1006 | pub trait CoerceUnsized<T> {} | ||
1007 | |||
1008 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | ||
1009 | |||
1010 | fn main() { | 495 | fn 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 { |