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