diff options
Diffstat (limited to 'crates/ra_hir_ty/src/tests/traits.rs')
-rw-r--r-- | crates/ra_hir_ty/src/tests/traits.rs | 3274 |
1 files changed, 1634 insertions, 1640 deletions
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 27737fa94..d3c4d3f2a 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use insta::assert_snapshot; | 1 | use expect::expect; |
2 | use test_utils::mark; | 2 | use test_utils::mark; |
3 | 3 | ||
4 | use super::{check_types, infer, infer_with_mismatches}; | 4 | use super::{check_infer, check_infer_with_mismatches, check_types}; |
5 | 5 | ||
6 | #[test] | 6 | #[test] |
7 | fn infer_await() { | 7 | fn infer_await() { |
@@ -38,7 +38,7 @@ fn infer_async() { | |||
38 | r#" | 38 | r#" |
39 | //- /main.rs crate:main deps:core | 39 | //- /main.rs crate:main deps:core |
40 | async fn foo() -> u64 { | 40 | async fn foo() -> u64 { |
41 | 128 | 41 | 128 |
42 | } | 42 | } |
43 | 43 | ||
44 | fn test() { | 44 | fn test() { |
@@ -65,7 +65,7 @@ fn infer_desugar_async() { | |||
65 | r#" | 65 | r#" |
66 | //- /main.rs crate:main deps:core | 66 | //- /main.rs crate:main deps:core |
67 | async fn foo() -> u64 { | 67 | async fn foo() -> u64 { |
68 | 128 | 68 | 128 |
69 | } | 69 | } |
70 | 70 | ||
71 | fn test() { | 71 | fn test() { |
@@ -222,291 +222,291 @@ mod ops { | |||
222 | 222 | ||
223 | #[test] | 223 | #[test] |
224 | fn infer_from_bound_1() { | 224 | fn infer_from_bound_1() { |
225 | assert_snapshot!( | 225 | check_infer( |
226 | infer(r#" | 226 | r#" |
227 | trait Trait<T> {} | 227 | trait Trait<T> {} |
228 | struct S<T>(T); | 228 | struct S<T>(T); |
229 | impl<U> Trait<U> for S<U> {} | 229 | impl<U> Trait<U> for S<U> {} |
230 | fn foo<T: Trait<u32>>(t: T) {} | 230 | fn foo<T: Trait<u32>>(t: T) {} |
231 | fn test() { | 231 | fn test() { |
232 | let s = S(unknown); | 232 | let s = S(unknown); |
233 | foo(s); | 233 | foo(s); |
234 | } | 234 | } |
235 | "#), | 235 | "#, |
236 | @r###" | 236 | expect![[r#" |
237 | 85..86 't': T | 237 | 85..86 't': T |
238 | 91..93 '{}': () | 238 | 91..93 '{}': () |
239 | 104..143 '{ ...(s); }': () | 239 | 104..143 '{ ...(s); }': () |
240 | 114..115 's': S<u32> | 240 | 114..115 's': S<u32> |
241 | 118..119 'S': S<u32>(u32) -> S<u32> | 241 | 118..119 'S': S<u32>(u32) -> S<u32> |
242 | 118..128 'S(unknown)': S<u32> | 242 | 118..128 'S(unknown)': S<u32> |
243 | 120..127 'unknown': u32 | 243 | 120..127 'unknown': u32 |
244 | 134..137 'foo': fn foo<S<u32>>(S<u32>) | 244 | 134..137 'foo': fn foo<S<u32>>(S<u32>) |
245 | 134..140 'foo(s)': () | 245 | 134..140 'foo(s)': () |
246 | 138..139 's': S<u32> | 246 | 138..139 's': S<u32> |
247 | "### | 247 | "#]], |
248 | ); | 248 | ); |
249 | } | 249 | } |
250 | 250 | ||
251 | #[test] | 251 | #[test] |
252 | fn infer_from_bound_2() { | 252 | fn infer_from_bound_2() { |
253 | assert_snapshot!( | 253 | check_infer( |
254 | infer(r#" | 254 | r#" |
255 | trait Trait<T> {} | 255 | trait Trait<T> {} |
256 | struct S<T>(T); | 256 | struct S<T>(T); |
257 | impl<U> Trait<U> for S<U> {} | 257 | impl<U> Trait<U> for S<U> {} |
258 | fn foo<U, T: Trait<U>>(t: T) -> U {} | 258 | fn foo<U, T: Trait<U>>(t: T) -> U {} |
259 | fn test() { | 259 | fn test() { |
260 | let s = S(unknown); | 260 | let s = S(unknown); |
261 | let x: u32 = foo(s); | 261 | let x: u32 = foo(s); |
262 | } | 262 | } |
263 | "#), | 263 | "#, |
264 | @r###" | 264 | expect![[r#" |
265 | 86..87 't': T | 265 | 86..87 't': T |
266 | 97..99 '{}': () | 266 | 97..99 '{}': () |
267 | 110..162 '{ ...(s); }': () | 267 | 110..162 '{ ...(s); }': () |
268 | 120..121 's': S<u32> | 268 | 120..121 's': S<u32> |
269 | 124..125 'S': S<u32>(u32) -> S<u32> | 269 | 124..125 'S': S<u32>(u32) -> S<u32> |
270 | 124..134 'S(unknown)': S<u32> | 270 | 124..134 'S(unknown)': S<u32> |
271 | 126..133 'unknown': u32 | 271 | 126..133 'unknown': u32 |
272 | 144..145 'x': u32 | 272 | 144..145 'x': u32 |
273 | 153..156 'foo': fn foo<u32, S<u32>>(S<u32>) -> u32 | 273 | 153..156 'foo': fn foo<u32, S<u32>>(S<u32>) -> u32 |
274 | 153..159 'foo(s)': u32 | 274 | 153..159 'foo(s)': u32 |
275 | 157..158 's': S<u32> | 275 | 157..158 's': S<u32> |
276 | "### | 276 | "#]], |
277 | ); | 277 | ); |
278 | } | 278 | } |
279 | 279 | ||
280 | #[test] | 280 | #[test] |
281 | fn trait_default_method_self_bound_implements_trait() { | 281 | fn trait_default_method_self_bound_implements_trait() { |
282 | mark::check!(trait_self_implements_self); | 282 | mark::check!(trait_self_implements_self); |
283 | assert_snapshot!( | 283 | check_infer( |
284 | infer(r#" | 284 | r#" |
285 | trait Trait { | 285 | trait Trait { |
286 | fn foo(&self) -> i64; | 286 | fn foo(&self) -> i64; |
287 | fn bar(&self) -> { | 287 | fn bar(&self) -> { |
288 | let x = self.foo(); | 288 | let x = self.foo(); |
289 | } | 289 | } |
290 | } | 290 | } |
291 | "#), | 291 | "#, |
292 | @r###" | 292 | expect![[r#" |
293 | 26..30 'self': &Self | 293 | 26..30 'self': &Self |
294 | 52..56 'self': &Self | 294 | 52..56 'self': &Self |
295 | 61..96 '{ ... }': () | 295 | 61..96 '{ ... }': () |
296 | 75..76 'x': i64 | 296 | 75..76 'x': i64 |
297 | 79..83 'self': &Self | 297 | 79..83 'self': &Self |
298 | 79..89 'self.foo()': i64 | 298 | 79..89 'self.foo()': i64 |
299 | "### | 299 | "#]], |
300 | ); | 300 | ); |
301 | } | 301 | } |
302 | 302 | ||
303 | #[test] | 303 | #[test] |
304 | fn trait_default_method_self_bound_implements_super_trait() { | 304 | fn trait_default_method_self_bound_implements_super_trait() { |
305 | assert_snapshot!( | 305 | check_infer( |
306 | infer(r#" | 306 | r#" |
307 | trait SuperTrait { | 307 | trait SuperTrait { |
308 | fn foo(&self) -> i64; | 308 | fn foo(&self) -> i64; |
309 | } | 309 | } |
310 | trait Trait: SuperTrait { | 310 | trait Trait: SuperTrait { |
311 | fn bar(&self) -> { | 311 | fn bar(&self) -> { |
312 | let x = self.foo(); | 312 | let x = self.foo(); |
313 | } | 313 | } |
314 | } | 314 | } |
315 | "#), | 315 | "#, |
316 | @r###" | 316 | expect![[r#" |
317 | 31..35 'self': &Self | 317 | 31..35 'self': &Self |
318 | 85..89 'self': &Self | 318 | 85..89 'self': &Self |
319 | 94..129 '{ ... }': () | 319 | 94..129 '{ ... }': () |
320 | 108..109 'x': i64 | 320 | 108..109 'x': i64 |
321 | 112..116 'self': &Self | 321 | 112..116 'self': &Self |
322 | 112..122 'self.foo()': i64 | 322 | 112..122 'self.foo()': i64 |
323 | "### | 323 | "#]], |
324 | ); | 324 | ); |
325 | } | 325 | } |
326 | 326 | ||
327 | #[test] | 327 | #[test] |
328 | fn infer_project_associated_type() { | 328 | fn infer_project_associated_type() { |
329 | assert_snapshot!( | 329 | check_infer( |
330 | infer(r#" | 330 | r#" |
331 | trait Iterable { | 331 | trait Iterable { |
332 | type Item; | 332 | type Item; |
333 | } | 333 | } |
334 | struct S; | 334 | struct S; |
335 | impl Iterable for S { type Item = u32; } | 335 | impl Iterable for S { type Item = u32; } |
336 | fn test<T: Iterable>() { | 336 | fn test<T: Iterable>() { |
337 | let x: <S as Iterable>::Item = 1; | 337 | let x: <S as Iterable>::Item = 1; |
338 | let y: <T as Iterable>::Item = no_matter; | 338 | let y: <T as Iterable>::Item = no_matter; |
339 | let z: T::Item = no_matter; | 339 | let z: T::Item = no_matter; |
340 | let a: <T>::Item = no_matter; | 340 | let a: <T>::Item = no_matter; |
341 | } | 341 | } |
342 | "#), | 342 | "#, |
343 | @r###" | 343 | expect![[r#" |
344 | 107..260 '{ ...ter; }': () | 344 | 108..261 '{ ...ter; }': () |
345 | 117..118 'x': u32 | 345 | 118..119 'x': u32 |
346 | 144..145 '1': u32 | 346 | 145..146 '1': u32 |
347 | 155..156 'y': Iterable::Item<T> | 347 | 156..157 'y': Iterable::Item<T> |
348 | 182..191 'no_matter': Iterable::Item<T> | 348 | 183..192 'no_matter': Iterable::Item<T> |
349 | 201..202 'z': Iterable::Item<T> | 349 | 202..203 'z': Iterable::Item<T> |
350 | 214..223 'no_matter': Iterable::Item<T> | 350 | 215..224 'no_matter': Iterable::Item<T> |
351 | 233..234 'a': Iterable::Item<T> | 351 | 234..235 'a': Iterable::Item<T> |
352 | 248..257 'no_matter': Iterable::Item<T> | 352 | 249..258 'no_matter': Iterable::Item<T> |
353 | "### | 353 | "#]], |
354 | ); | 354 | ); |
355 | } | 355 | } |
356 | 356 | ||
357 | #[test] | 357 | #[test] |
358 | fn infer_return_associated_type() { | 358 | fn infer_return_associated_type() { |
359 | assert_snapshot!( | 359 | check_infer( |
360 | infer(r#" | 360 | r#" |
361 | trait Iterable { | 361 | trait Iterable { |
362 | type Item; | 362 | type Item; |
363 | } | 363 | } |
364 | struct S; | 364 | struct S; |
365 | impl Iterable for S { type Item = u32; } | 365 | impl Iterable for S { type Item = u32; } |
366 | fn foo1<T: Iterable>(t: T) -> T::Item {} | 366 | fn foo1<T: Iterable>(t: T) -> T::Item {} |
367 | fn foo2<T: Iterable>(t: T) -> <T as Iterable>::Item {} | 367 | fn foo2<T: Iterable>(t: T) -> <T as Iterable>::Item {} |
368 | fn foo3<T: Iterable>(t: T) -> <T>::Item {} | 368 | fn foo3<T: Iterable>(t: T) -> <T>::Item {} |
369 | fn test() { | 369 | fn test() { |
370 | let x = foo1(S); | 370 | let x = foo1(S); |
371 | let y = foo2(S); | 371 | let y = foo2(S); |
372 | let z = foo3(S); | 372 | let z = foo3(S); |
373 | } | 373 | } |
374 | "#), | 374 | "#, |
375 | @r###" | 375 | expect![[r#" |
376 | 105..106 't': T | 376 | 106..107 't': T |
377 | 122..124 '{}': () | 377 | 123..125 '{}': () |
378 | 146..147 't': T | 378 | 147..148 't': T |
379 | 177..179 '{}': () | 379 | 178..180 '{}': () |
380 | 201..202 't': T | 380 | 202..203 't': T |
381 | 220..222 '{}': () | 381 | 221..223 '{}': () |
382 | 233..299 '{ ...(S); }': () | 382 | 234..300 '{ ...(S); }': () |
383 | 243..244 'x': u32 | 383 | 244..245 'x': u32 |
384 | 247..251 'foo1': fn foo1<S>(S) -> <S as Iterable>::Item | 384 | 248..252 'foo1': fn foo1<S>(S) -> <S as Iterable>::Item |
385 | 247..254 'foo1(S)': u32 | 385 | 248..255 'foo1(S)': u32 |
386 | 252..253 'S': S | 386 | 253..254 'S': S |
387 | 264..265 'y': u32 | 387 | 265..266 'y': u32 |
388 | 268..272 'foo2': fn foo2<S>(S) -> <S as Iterable>::Item | 388 | 269..273 'foo2': fn foo2<S>(S) -> <S as Iterable>::Item |
389 | 268..275 'foo2(S)': u32 | 389 | 269..276 'foo2(S)': u32 |
390 | 273..274 'S': S | 390 | 274..275 'S': S |
391 | 285..286 'z': u32 | 391 | 286..287 'z': u32 |
392 | 289..293 'foo3': fn foo3<S>(S) -> <S as Iterable>::Item | 392 | 290..294 'foo3': fn foo3<S>(S) -> <S as Iterable>::Item |
393 | 289..296 'foo3(S)': u32 | 393 | 290..297 'foo3(S)': u32 |
394 | 294..295 'S': S | 394 | 295..296 'S': S |
395 | "### | 395 | "#]], |
396 | ); | 396 | ); |
397 | } | 397 | } |
398 | 398 | ||
399 | #[test] | 399 | #[test] |
400 | fn infer_associated_type_bound() { | 400 | fn infer_associated_type_bound() { |
401 | assert_snapshot!( | 401 | check_infer( |
402 | infer(r#" | 402 | r#" |
403 | trait Iterable { | 403 | trait Iterable { |
404 | type Item; | 404 | type Item; |
405 | } | 405 | } |
406 | fn test<T: Iterable<Item=u32>>() { | 406 | fn test<T: Iterable<Item=u32>>() { |
407 | let y: T::Item = unknown; | 407 | let y: T::Item = unknown; |
408 | } | 408 | } |
409 | "#), | 409 | "#, |
410 | @r###" | 410 | expect![[r#" |
411 | 66..99 '{ ...own; }': () | 411 | 67..100 '{ ...own; }': () |
412 | 76..77 'y': u32 | 412 | 77..78 'y': u32 |
413 | 89..96 'unknown': u32 | 413 | 90..97 'unknown': u32 |
414 | "### | 414 | "#]], |
415 | ); | 415 | ); |
416 | } | 416 | } |
417 | 417 | ||
418 | #[test] | 418 | #[test] |
419 | fn infer_const_body() { | 419 | fn infer_const_body() { |
420 | assert_snapshot!( | 420 | check_infer( |
421 | infer(r#" | 421 | r#" |
422 | const A: u32 = 1 + 1; | 422 | const A: u32 = 1 + 1; |
423 | static B: u64 = { let x = 1; x }; | 423 | static B: u64 = { let x = 1; x }; |
424 | "#), | 424 | "#, |
425 | @r###" | 425 | expect![[r#" |
426 | 15..16 '1': u32 | 426 | 15..16 '1': u32 |
427 | 15..20 '1 + 1': u32 | 427 | 15..20 '1 + 1': u32 |
428 | 19..20 '1': u32 | 428 | 19..20 '1': u32 |
429 | 38..54 '{ let ...1; x }': u64 | 429 | 38..54 '{ let ...1; x }': u64 |
430 | 44..45 'x': u64 | 430 | 44..45 'x': u64 |
431 | 48..49 '1': u64 | 431 | 48..49 '1': u64 |
432 | 51..52 'x': u64 | 432 | 51..52 'x': u64 |
433 | "### | 433 | "#]], |
434 | ); | 434 | ); |
435 | } | 435 | } |
436 | 436 | ||
437 | #[test] | 437 | #[test] |
438 | fn tuple_struct_fields() { | 438 | fn tuple_struct_fields() { |
439 | assert_snapshot!( | 439 | check_infer( |
440 | infer(r#" | 440 | r#" |
441 | struct S(i32, u64); | 441 | struct S(i32, u64); |
442 | fn test() -> u64 { | 442 | fn test() -> u64 { |
443 | let a = S(4, 6); | 443 | let a = S(4, 6); |
444 | let b = a.0; | 444 | let b = a.0; |
445 | a.1 | 445 | a.1 |
446 | } | 446 | } |
447 | "#), | 447 | "#, |
448 | @r###" | 448 | expect![[r#" |
449 | 37..86 '{ ... a.1 }': u64 | 449 | 37..86 '{ ... a.1 }': u64 |
450 | 47..48 'a': S | 450 | 47..48 'a': S |
451 | 51..52 'S': S(i32, u64) -> S | 451 | 51..52 'S': S(i32, u64) -> S |
452 | 51..58 'S(4, 6)': S | 452 | 51..58 'S(4, 6)': S |
453 | 53..54 '4': i32 | 453 | 53..54 '4': i32 |
454 | 56..57 '6': u64 | 454 | 56..57 '6': u64 |
455 | 68..69 'b': i32 | 455 | 68..69 'b': i32 |
456 | 72..73 'a': S | 456 | 72..73 'a': S |
457 | 72..75 'a.0': i32 | 457 | 72..75 'a.0': i32 |
458 | 81..82 'a': S | 458 | 81..82 'a': S |
459 | 81..84 'a.1': u64 | 459 | 81..84 'a.1': u64 |
460 | "### | 460 | "#]], |
461 | ); | 461 | ); |
462 | } | 462 | } |
463 | 463 | ||
464 | #[test] | 464 | #[test] |
465 | fn tuple_struct_with_fn() { | 465 | fn tuple_struct_with_fn() { |
466 | assert_snapshot!( | 466 | check_infer( |
467 | infer(r#" | 467 | r#" |
468 | struct S(fn(u32) -> u64); | 468 | struct S(fn(u32) -> u64); |
469 | fn test() -> u64 { | 469 | fn test() -> u64 { |
470 | let a = S(|i| 2*i); | 470 | let a = S(|i| 2*i); |
471 | let b = a.0(4); | 471 | let b = a.0(4); |
472 | a.0(2) | 472 | a.0(2) |
473 | } | 473 | } |
474 | "#), | 474 | "#, |
475 | @r###" | 475 | expect![[r#" |
476 | 43..101 '{ ...0(2) }': u64 | 476 | 43..101 '{ ...0(2) }': u64 |
477 | 53..54 'a': S | 477 | 53..54 'a': S |
478 | 57..58 'S': S(fn(u32) -> u64) -> S | 478 | 57..58 'S': S(fn(u32) -> u64) -> S |
479 | 57..67 'S(|i| 2*i)': S | 479 | 57..67 'S(|i| 2*i)': S |
480 | 59..66 '|i| 2*i': |u32| -> u64 | 480 | 59..66 '|i| 2*i': |u32| -> u64 |
481 | 60..61 'i': u32 | 481 | 60..61 'i': u32 |
482 | 63..64 '2': u32 | 482 | 63..64 '2': u32 |
483 | 63..66 '2*i': u32 | 483 | 63..66 '2*i': u32 |
484 | 65..66 'i': u32 | 484 | 65..66 'i': u32 |
485 | 77..78 'b': u64 | 485 | 77..78 'b': u64 |
486 | 81..82 'a': S | 486 | 81..82 'a': S |
487 | 81..84 'a.0': fn(u32) -> u64 | 487 | 81..84 'a.0': fn(u32) -> u64 |
488 | 81..87 'a.0(4)': u64 | 488 | 81..87 'a.0(4)': u64 |
489 | 85..86 '4': u32 | 489 | 85..86 '4': u32 |
490 | 93..94 'a': S | 490 | 93..94 'a': S |
491 | 93..96 'a.0': fn(u32) -> u64 | 491 | 93..96 'a.0': fn(u32) -> u64 |
492 | 93..99 'a.0(2)': u64 | 492 | 93..99 'a.0(2)': u64 |
493 | 97..98 '2': u32 | 493 | 97..98 '2': u32 |
494 | "### | 494 | "#]], |
495 | ); | 495 | ); |
496 | } | 496 | } |
497 | 497 | ||
498 | #[test] | 498 | #[test] |
499 | fn indexing_arrays() { | 499 | fn indexing_arrays() { |
500 | assert_snapshot!( | 500 | check_infer( |
501 | infer("fn main() { &mut [9][2]; }"), | 501 | "fn main() { &mut [9][2]; }", |
502 | @r###" | 502 | expect![[r#" |
503 | 10..26 '{ &mut...[2]; }': () | 503 | 10..26 '{ &mut...[2]; }': () |
504 | 12..23 '&mut [9][2]': &mut {unknown} | 504 | 12..23 '&mut [9][2]': &mut {unknown} |
505 | 17..20 '[9]': [i32; _] | 505 | 17..20 '[9]': [i32; _] |
506 | 17..23 '[9][2]': {unknown} | 506 | 17..23 '[9][2]': {unknown} |
507 | 18..19 '9': i32 | 507 | 18..19 '9': i32 |
508 | 21..22 '2': i32 | 508 | 21..22 '2': i32 |
509 | "### | 509 | "#]], |
510 | ) | 510 | ) |
511 | } | 511 | } |
512 | 512 | ||
@@ -908,476 +908,475 @@ fn test<T: ApplyL>(t: T) { | |||
908 | 908 | ||
909 | #[test] | 909 | #[test] |
910 | fn argument_impl_trait() { | 910 | fn argument_impl_trait() { |
911 | assert_snapshot!( | 911 | check_infer_with_mismatches( |
912 | infer_with_mismatches(r#" | 912 | r#" |
913 | trait Trait<T> { | 913 | trait Trait<T> { |
914 | fn foo(&self) -> T; | 914 | fn foo(&self) -> T; |
915 | fn foo2(&self) -> i64; | 915 | fn foo2(&self) -> i64; |
916 | } | 916 | } |
917 | fn bar(x: impl Trait<u16>) {} | 917 | fn bar(x: impl Trait<u16>) {} |
918 | struct S<T>(T); | 918 | struct S<T>(T); |
919 | impl<T> Trait<T> for S<T> {} | 919 | impl<T> Trait<T> for S<T> {} |
920 | 920 | ||
921 | fn test(x: impl Trait<u64>, y: &impl Trait<u32>) { | 921 | fn test(x: impl Trait<u64>, y: &impl Trait<u32>) { |
922 | x; | 922 | x; |
923 | y; | 923 | y; |
924 | let z = S(1); | 924 | let z = S(1); |
925 | bar(z); | 925 | bar(z); |
926 | x.foo(); | 926 | x.foo(); |
927 | y.foo(); | 927 | y.foo(); |
928 | z.foo(); | 928 | z.foo(); |
929 | x.foo2(); | 929 | x.foo2(); |
930 | y.foo2(); | 930 | y.foo2(); |
931 | z.foo2(); | 931 | z.foo2(); |
932 | } | 932 | } |
933 | "#, true), | 933 | "#, |
934 | @r###" | 934 | expect![[r#" |
935 | 29..33 'self': &Self | 935 | 29..33 'self': &Self |
936 | 54..58 'self': &Self | 936 | 54..58 'self': &Self |
937 | 77..78 'x': impl Trait<u16> | 937 | 77..78 'x': impl Trait<u16> |
938 | 97..99 '{}': () | 938 | 97..99 '{}': () |
939 | 154..155 'x': impl Trait<u64> | 939 | 154..155 'x': impl Trait<u64> |
940 | 174..175 'y': &impl Trait<u32> | 940 | 174..175 'y': &impl Trait<u32> |
941 | 195..323 '{ ...2(); }': () | 941 | 195..323 '{ ...2(); }': () |
942 | 201..202 'x': impl Trait<u64> | 942 | 201..202 'x': impl Trait<u64> |
943 | 208..209 'y': &impl Trait<u32> | 943 | 208..209 'y': &impl Trait<u32> |
944 | 219..220 'z': S<u16> | 944 | 219..220 'z': S<u16> |
945 | 223..224 'S': S<u16>(u16) -> S<u16> | 945 | 223..224 'S': S<u16>(u16) -> S<u16> |
946 | 223..227 'S(1)': S<u16> | 946 | 223..227 'S(1)': S<u16> |
947 | 225..226 '1': u16 | 947 | 225..226 '1': u16 |
948 | 233..236 'bar': fn bar(S<u16>) | 948 | 233..236 'bar': fn bar(S<u16>) |
949 | 233..239 'bar(z)': () | 949 | 233..239 'bar(z)': () |
950 | 237..238 'z': S<u16> | 950 | 237..238 'z': S<u16> |
951 | 245..246 'x': impl Trait<u64> | 951 | 245..246 'x': impl Trait<u64> |
952 | 245..252 'x.foo()': u64 | 952 | 245..252 'x.foo()': u64 |
953 | 258..259 'y': &impl Trait<u32> | 953 | 258..259 'y': &impl Trait<u32> |
954 | 258..265 'y.foo()': u32 | 954 | 258..265 'y.foo()': u32 |
955 | 271..272 'z': S<u16> | 955 | 271..272 'z': S<u16> |
956 | 271..278 'z.foo()': u16 | 956 | 271..278 'z.foo()': u16 |
957 | 284..285 'x': impl Trait<u64> | 957 | 284..285 'x': impl Trait<u64> |
958 | 284..292 'x.foo2()': i64 | 958 | 284..292 'x.foo2()': i64 |
959 | 298..299 'y': &impl Trait<u32> | 959 | 298..299 'y': &impl Trait<u32> |
960 | 298..306 'y.foo2()': i64 | 960 | 298..306 'y.foo2()': i64 |
961 | 312..313 'z': S<u16> | 961 | 312..313 'z': S<u16> |
962 | 312..320 'z.foo2()': i64 | 962 | 312..320 'z.foo2()': i64 |
963 | "### | 963 | "#]], |
964 | ); | 964 | ); |
965 | } | 965 | } |
966 | 966 | ||
967 | #[test] | 967 | #[test] |
968 | fn argument_impl_trait_type_args_1() { | 968 | fn argument_impl_trait_type_args_1() { |
969 | assert_snapshot!( | 969 | check_infer_with_mismatches( |
970 | infer_with_mismatches(r#" | 970 | r#" |
971 | trait Trait {} | 971 | trait Trait {} |
972 | trait Foo { | 972 | trait Foo { |
973 | // this function has an implicit Self param, an explicit type param, | 973 | // this function has an implicit Self param, an explicit type param, |
974 | // and an implicit impl Trait param! | 974 | // and an implicit impl Trait param! |
975 | fn bar<T>(x: impl Trait) -> T { loop {} } | 975 | fn bar<T>(x: impl Trait) -> T { loop {} } |
976 | } | 976 | } |
977 | fn foo<T>(x: impl Trait) -> T { loop {} } | 977 | fn foo<T>(x: impl Trait) -> T { loop {} } |
978 | struct S; | 978 | struct S; |
979 | impl Trait for S {} | 979 | impl Trait for S {} |
980 | struct F; | 980 | struct F; |
981 | impl Foo for F {} | 981 | impl Foo for F {} |
982 | 982 | ||
983 | fn test() { | 983 | fn test() { |
984 | Foo::bar(S); | 984 | Foo::bar(S); |
985 | <F as Foo>::bar(S); | 985 | <F as Foo>::bar(S); |
986 | F::bar(S); | 986 | F::bar(S); |
987 | Foo::bar::<u32>(S); | 987 | Foo::bar::<u32>(S); |
988 | <F as Foo>::bar::<u32>(S); | 988 | <F as Foo>::bar::<u32>(S); |
989 | 989 | ||
990 | foo(S); | 990 | foo(S); |
991 | foo::<u32>(S); | 991 | foo::<u32>(S); |
992 | foo::<u32, i32>(S); // we should ignore the extraneous i32 | 992 | foo::<u32, i32>(S); // we should ignore the extraneous i32 |
993 | } | 993 | } |
994 | "#, true), | 994 | "#, |
995 | @r###" | 995 | expect![[r#" |
996 | 155..156 'x': impl Trait | 996 | 155..156 'x': impl Trait |
997 | 175..186 '{ loop {} }': T | 997 | 175..186 '{ loop {} }': T |
998 | 177..184 'loop {}': ! | 998 | 177..184 'loop {}': ! |
999 | 182..184 '{}': () | 999 | 182..184 '{}': () |
1000 | 199..200 'x': impl Trait | 1000 | 199..200 'x': impl Trait |
1001 | 219..230 '{ loop {} }': T | 1001 | 219..230 '{ loop {} }': T |
1002 | 221..228 'loop {}': ! | 1002 | 221..228 'loop {}': ! |
1003 | 226..228 '{}': () | 1003 | 226..228 '{}': () |
1004 | 300..509 '{ ... i32 }': () | 1004 | 300..509 '{ ... i32 }': () |
1005 | 306..314 'Foo::bar': fn bar<{unknown}, {unknown}>(S) -> {unknown} | 1005 | 306..314 'Foo::bar': fn bar<{unknown}, {unknown}>(S) -> {unknown} |
1006 | 306..317 'Foo::bar(S)': {unknown} | 1006 | 306..317 'Foo::bar(S)': {unknown} |
1007 | 315..316 'S': S | 1007 | 315..316 'S': S |
1008 | 323..338 '<F as Foo>::bar': fn bar<F, {unknown}>(S) -> {unknown} | 1008 | 323..338 '<F as Foo>::bar': fn bar<F, {unknown}>(S) -> {unknown} |
1009 | 323..341 '<F as ...bar(S)': {unknown} | 1009 | 323..341 '<F as ...bar(S)': {unknown} |
1010 | 339..340 'S': S | 1010 | 339..340 'S': S |
1011 | 347..353 'F::bar': fn bar<F, {unknown}>(S) -> {unknown} | 1011 | 347..353 'F::bar': fn bar<F, {unknown}>(S) -> {unknown} |
1012 | 347..356 'F::bar(S)': {unknown} | 1012 | 347..356 'F::bar(S)': {unknown} |
1013 | 354..355 'S': S | 1013 | 354..355 'S': S |
1014 | 362..377 'Foo::bar::<u32>': fn bar<{unknown}, u32>(S) -> u32 | 1014 | 362..377 'Foo::bar::<u32>': fn bar<{unknown}, u32>(S) -> u32 |
1015 | 362..380 'Foo::b...32>(S)': u32 | 1015 | 362..380 'Foo::b...32>(S)': u32 |
1016 | 378..379 'S': S | 1016 | 378..379 'S': S |
1017 | 386..408 '<F as ...:<u32>': fn bar<F, u32>(S) -> u32 | 1017 | 386..408 '<F as ...:<u32>': fn bar<F, u32>(S) -> u32 |
1018 | 386..411 '<F as ...32>(S)': u32 | 1018 | 386..411 '<F as ...32>(S)': u32 |
1019 | 409..410 'S': S | 1019 | 409..410 'S': S |
1020 | 418..421 'foo': fn foo<{unknown}>(S) -> {unknown} | 1020 | 418..421 'foo': fn foo<{unknown}>(S) -> {unknown} |
1021 | 418..424 'foo(S)': {unknown} | 1021 | 418..424 'foo(S)': {unknown} |
1022 | 422..423 'S': S | 1022 | 422..423 'S': S |
1023 | 430..440 'foo::<u32>': fn foo<u32>(S) -> u32 | 1023 | 430..440 'foo::<u32>': fn foo<u32>(S) -> u32 |
1024 | 430..443 'foo::<u32>(S)': u32 | 1024 | 430..443 'foo::<u32>(S)': u32 |
1025 | 441..442 'S': S | 1025 | 441..442 'S': S |
1026 | 449..464 'foo::<u32, i32>': fn foo<u32>(S) -> u32 | 1026 | 449..464 'foo::<u32, i32>': fn foo<u32>(S) -> u32 |
1027 | 449..467 'foo::<...32>(S)': u32 | 1027 | 449..467 'foo::<...32>(S)': u32 |
1028 | 465..466 'S': S | 1028 | 465..466 'S': S |
1029 | "### | 1029 | "#]], |
1030 | ); | 1030 | ); |
1031 | } | 1031 | } |
1032 | 1032 | ||
1033 | #[test] | 1033 | #[test] |
1034 | fn argument_impl_trait_type_args_2() { | 1034 | fn argument_impl_trait_type_args_2() { |
1035 | assert_snapshot!( | 1035 | check_infer_with_mismatches( |
1036 | infer_with_mismatches(r#" | 1036 | r#" |
1037 | trait Trait {} | 1037 | trait Trait {} |
1038 | struct S; | 1038 | struct S; |
1039 | impl Trait for S {} | 1039 | impl Trait for S {} |
1040 | struct F<T>; | 1040 | struct F<T>; |
1041 | impl<T> F<T> { | 1041 | impl<T> F<T> { |
1042 | fn foo<U>(self, x: impl Trait) -> (T, U) { loop {} } | 1042 | fn foo<U>(self, x: impl Trait) -> (T, U) { loop {} } |
1043 | } | 1043 | } |
1044 | 1044 | ||
1045 | fn test() { | 1045 | fn test() { |
1046 | F.foo(S); | 1046 | F.foo(S); |
1047 | F::<u32>.foo(S); | 1047 | F::<u32>.foo(S); |
1048 | F::<u32>.foo::<i32>(S); | 1048 | F::<u32>.foo::<i32>(S); |
1049 | F::<u32>.foo::<i32, u32>(S); // extraneous argument should be ignored | 1049 | F::<u32>.foo::<i32, u32>(S); // extraneous argument should be ignored |
1050 | } | 1050 | } |
1051 | "#, true), | 1051 | "#, |
1052 | @r###" | 1052 | expect![[r#" |
1053 | 87..91 'self': F<T> | 1053 | 87..91 'self': F<T> |
1054 | 93..94 'x': impl Trait | 1054 | 93..94 'x': impl Trait |
1055 | 118..129 '{ loop {} }': (T, U) | 1055 | 118..129 '{ loop {} }': (T, U) |
1056 | 120..127 'loop {}': ! | 1056 | 120..127 'loop {}': ! |
1057 | 125..127 '{}': () | 1057 | 125..127 '{}': () |
1058 | 143..283 '{ ...ored }': () | 1058 | 143..283 '{ ...ored }': () |
1059 | 149..150 'F': F<{unknown}> | 1059 | 149..150 'F': F<{unknown}> |
1060 | 149..157 'F.foo(S)': ({unknown}, {unknown}) | 1060 | 149..157 'F.foo(S)': ({unknown}, {unknown}) |
1061 | 155..156 'S': S | 1061 | 155..156 'S': S |
1062 | 163..171 'F::<u32>': F<u32> | 1062 | 163..171 'F::<u32>': F<u32> |
1063 | 163..178 'F::<u32>.foo(S)': (u32, {unknown}) | 1063 | 163..178 'F::<u32>.foo(S)': (u32, {unknown}) |
1064 | 176..177 'S': S | 1064 | 176..177 'S': S |
1065 | 184..192 'F::<u32>': F<u32> | 1065 | 184..192 'F::<u32>': F<u32> |
1066 | 184..206 'F::<u3...32>(S)': (u32, i32) | 1066 | 184..206 'F::<u3...32>(S)': (u32, i32) |
1067 | 204..205 'S': S | 1067 | 204..205 'S': S |
1068 | 212..220 'F::<u32>': F<u32> | 1068 | 212..220 'F::<u32>': F<u32> |
1069 | 212..239 'F::<u3...32>(S)': (u32, i32) | 1069 | 212..239 'F::<u3...32>(S)': (u32, i32) |
1070 | 237..238 'S': S | 1070 | 237..238 'S': S |
1071 | "### | 1071 | "#]], |
1072 | ); | 1072 | ); |
1073 | } | 1073 | } |
1074 | 1074 | ||
1075 | #[test] | 1075 | #[test] |
1076 | fn argument_impl_trait_to_fn_pointer() { | 1076 | fn argument_impl_trait_to_fn_pointer() { |
1077 | assert_snapshot!( | 1077 | check_infer_with_mismatches( |
1078 | infer_with_mismatches(r#" | 1078 | r#" |
1079 | trait Trait {} | 1079 | trait Trait {} |
1080 | fn foo(x: impl Trait) { loop {} } | 1080 | fn foo(x: impl Trait) { loop {} } |
1081 | struct S; | 1081 | struct S; |
1082 | impl Trait for S {} | 1082 | impl Trait for S {} |
1083 | 1083 | ||
1084 | fn test() { | 1084 | fn test() { |
1085 | let f: fn(S) -> () = foo; | 1085 | let f: fn(S) -> () = foo; |
1086 | } | 1086 | } |
1087 | "#, true), | 1087 | "#, |
1088 | @r###" | 1088 | expect![[r#" |
1089 | 22..23 'x': impl Trait | 1089 | 22..23 'x': impl Trait |
1090 | 37..48 '{ loop {} }': () | 1090 | 37..48 '{ loop {} }': () |
1091 | 39..46 'loop {}': ! | 1091 | 39..46 'loop {}': ! |
1092 | 44..46 '{}': () | 1092 | 44..46 '{}': () |
1093 | 90..123 '{ ...foo; }': () | 1093 | 90..123 '{ ...foo; }': () |
1094 | 100..101 'f': fn(S) | 1094 | 100..101 'f': fn(S) |
1095 | 117..120 'foo': fn foo(S) | 1095 | 117..120 'foo': fn foo(S) |
1096 | "### | 1096 | "#]], |
1097 | ); | 1097 | ); |
1098 | } | 1098 | } |
1099 | 1099 | ||
1100 | #[test] | 1100 | #[test] |
1101 | fn impl_trait() { | 1101 | fn impl_trait() { |
1102 | assert_snapshot!( | 1102 | check_infer( |
1103 | infer(r#" | 1103 | r#" |
1104 | trait Trait<T> { | 1104 | trait Trait<T> { |
1105 | fn foo(&self) -> T; | 1105 | fn foo(&self) -> T; |
1106 | fn foo2(&self) -> i64; | 1106 | fn foo2(&self) -> i64; |
1107 | } | 1107 | } |
1108 | fn bar() -> impl Trait<u64> {} | 1108 | fn bar() -> impl Trait<u64> {} |
1109 | 1109 | ||
1110 | fn test(x: impl Trait<u64>, y: &impl Trait<u64>) { | 1110 | fn test(x: impl Trait<u64>, y: &impl Trait<u64>) { |
1111 | x; | 1111 | x; |
1112 | y; | 1112 | y; |
1113 | let z = bar(); | 1113 | let z = bar(); |
1114 | x.foo(); | 1114 | x.foo(); |
1115 | y.foo(); | 1115 | y.foo(); |
1116 | z.foo(); | 1116 | z.foo(); |
1117 | x.foo2(); | 1117 | x.foo2(); |
1118 | y.foo2(); | 1118 | y.foo2(); |
1119 | z.foo2(); | 1119 | z.foo2(); |
1120 | } | 1120 | } |
1121 | "#), | 1121 | "#, |
1122 | @r###" | 1122 | expect![[r#" |
1123 | 29..33 'self': &Self | 1123 | 29..33 'self': &Self |
1124 | 54..58 'self': &Self | 1124 | 54..58 'self': &Self |
1125 | 98..100 '{}': () | 1125 | 98..100 '{}': () |
1126 | 110..111 'x': impl Trait<u64> | 1126 | 110..111 'x': impl Trait<u64> |
1127 | 130..131 'y': &impl Trait<u64> | 1127 | 130..131 'y': &impl Trait<u64> |
1128 | 151..268 '{ ...2(); }': () | 1128 | 151..268 '{ ...2(); }': () |
1129 | 157..158 'x': impl Trait<u64> | 1129 | 157..158 'x': impl Trait<u64> |
1130 | 164..165 'y': &impl Trait<u64> | 1130 | 164..165 'y': &impl Trait<u64> |
1131 | 175..176 'z': impl Trait<u64> | 1131 | 175..176 'z': impl Trait<u64> |
1132 | 179..182 'bar': fn bar() -> impl Trait<u64> | 1132 | 179..182 'bar': fn bar() -> impl Trait<u64> |
1133 | 179..184 'bar()': impl Trait<u64> | 1133 | 179..184 'bar()': impl Trait<u64> |
1134 | 190..191 'x': impl Trait<u64> | 1134 | 190..191 'x': impl Trait<u64> |
1135 | 190..197 'x.foo()': u64 | 1135 | 190..197 'x.foo()': u64 |
1136 | 203..204 'y': &impl Trait<u64> | 1136 | 203..204 'y': &impl Trait<u64> |
1137 | 203..210 'y.foo()': u64 | 1137 | 203..210 'y.foo()': u64 |
1138 | 216..217 'z': impl Trait<u64> | 1138 | 216..217 'z': impl Trait<u64> |
1139 | 216..223 'z.foo()': u64 | 1139 | 216..223 'z.foo()': u64 |
1140 | 229..230 'x': impl Trait<u64> | 1140 | 229..230 'x': impl Trait<u64> |
1141 | 229..237 'x.foo2()': i64 | 1141 | 229..237 'x.foo2()': i64 |
1142 | 243..244 'y': &impl Trait<u64> | 1142 | 243..244 'y': &impl Trait<u64> |
1143 | 243..251 'y.foo2()': i64 | 1143 | 243..251 'y.foo2()': i64 |
1144 | 257..258 'z': impl Trait<u64> | 1144 | 257..258 'z': impl Trait<u64> |
1145 | 257..265 'z.foo2()': i64 | 1145 | 257..265 'z.foo2()': i64 |
1146 | "### | 1146 | "#]], |
1147 | ); | 1147 | ); |
1148 | } | 1148 | } |
1149 | 1149 | ||
1150 | #[test] | 1150 | #[test] |
1151 | fn simple_return_pos_impl_trait() { | 1151 | fn simple_return_pos_impl_trait() { |
1152 | mark::check!(lower_rpit); | 1152 | mark::check!(lower_rpit); |
1153 | assert_snapshot!( | 1153 | check_infer( |
1154 | infer(r#" | 1154 | r#" |
1155 | trait Trait<T> { | 1155 | trait Trait<T> { |
1156 | fn foo(&self) -> T; | 1156 | fn foo(&self) -> T; |
1157 | } | 1157 | } |
1158 | fn bar() -> impl Trait<u64> { loop {} } | 1158 | fn bar() -> impl Trait<u64> { loop {} } |
1159 | 1159 | ||
1160 | fn test() { | 1160 | fn test() { |
1161 | let a = bar(); | 1161 | let a = bar(); |
1162 | a.foo(); | 1162 | a.foo(); |
1163 | } | 1163 | } |
1164 | "#), | 1164 | "#, |
1165 | @r###" | 1165 | expect![[r#" |
1166 | 29..33 'self': &Self | 1166 | 29..33 'self': &Self |
1167 | 71..82 '{ loop {} }': ! | 1167 | 71..82 '{ loop {} }': ! |
1168 | 73..80 'loop {}': ! | 1168 | 73..80 'loop {}': ! |
1169 | 78..80 '{}': () | 1169 | 78..80 '{}': () |
1170 | 94..129 '{ ...o(); }': () | 1170 | 94..129 '{ ...o(); }': () |
1171 | 104..105 'a': impl Trait<u64> | 1171 | 104..105 'a': impl Trait<u64> |
1172 | 108..111 'bar': fn bar() -> impl Trait<u64> | 1172 | 108..111 'bar': fn bar() -> impl Trait<u64> |
1173 | 108..113 'bar()': impl Trait<u64> | 1173 | 108..113 'bar()': impl Trait<u64> |
1174 | 119..120 'a': impl Trait<u64> | 1174 | 119..120 'a': impl Trait<u64> |
1175 | 119..126 'a.foo()': u64 | 1175 | 119..126 'a.foo()': u64 |
1176 | "### | 1176 | "#]], |
1177 | ); | 1177 | ); |
1178 | } | 1178 | } |
1179 | 1179 | ||
1180 | #[test] | 1180 | #[test] |
1181 | fn more_return_pos_impl_trait() { | 1181 | fn more_return_pos_impl_trait() { |
1182 | assert_snapshot!( | 1182 | check_infer( |
1183 | infer(r#" | 1183 | r#" |
1184 | trait Iterator { | 1184 | trait Iterator { |
1185 | type Item; | 1185 | type Item; |
1186 | fn next(&mut self) -> Self::Item; | 1186 | fn next(&mut self) -> Self::Item; |
1187 | } | 1187 | } |
1188 | trait Trait<T> { | 1188 | trait Trait<T> { |
1189 | fn foo(&self) -> T; | 1189 | fn foo(&self) -> T; |
1190 | } | 1190 | } |
1191 | fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) { loop {} } | 1191 | fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) { loop {} } |
1192 | fn baz<T>(t: T) -> (impl Iterator<Item = impl Trait<T>>, impl Trait<T>) { loop {} } | 1192 | fn baz<T>(t: T) -> (impl Iterator<Item = impl Trait<T>>, impl Trait<T>) { loop {} } |
1193 | 1193 | ||
1194 | fn test() { | 1194 | fn test() { |
1195 | let (a, b) = bar(); | 1195 | let (a, b) = bar(); |
1196 | a.next().foo(); | 1196 | a.next().foo(); |
1197 | b.foo(); | 1197 | b.foo(); |
1198 | let (c, d) = baz(1u128); | 1198 | let (c, d) = baz(1u128); |
1199 | c.next().foo(); | 1199 | c.next().foo(); |
1200 | d.foo(); | 1200 | d.foo(); |
1201 | } | 1201 | } |
1202 | "#), | 1202 | "#, |
1203 | @r###" | 1203 | expect![[r#" |
1204 | 49..53 'self': &mut Self | 1204 | 49..53 'self': &mut Self |
1205 | 101..105 'self': &Self | 1205 | 101..105 'self': &Self |
1206 | 184..195 '{ loop {} }': ({unknown}, {unknown}) | 1206 | 184..195 '{ loop {} }': ({unknown}, {unknown}) |
1207 | 186..193 'loop {}': ! | 1207 | 186..193 'loop {}': ! |
1208 | 191..193 '{}': () | 1208 | 191..193 '{}': () |
1209 | 206..207 't': T | 1209 | 206..207 't': T |
1210 | 268..279 '{ loop {} }': ({unknown}, {unknown}) | 1210 | 268..279 '{ loop {} }': ({unknown}, {unknown}) |
1211 | 270..277 'loop {}': ! | 1211 | 270..277 'loop {}': ! |
1212 | 275..277 '{}': () | 1212 | 275..277 '{}': () |
1213 | 291..413 '{ ...o(); }': () | 1213 | 291..413 '{ ...o(); }': () |
1214 | 301..307 '(a, b)': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) | 1214 | 301..307 '(a, b)': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) |
1215 | 302..303 'a': impl Iterator<Item = impl Trait<u32>> | 1215 | 302..303 'a': impl Iterator<Item = impl Trait<u32>> |
1216 | 305..306 'b': impl Trait<u64> | 1216 | 305..306 'b': impl Trait<u64> |
1217 | 310..313 'bar': fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) | 1217 | 310..313 'bar': fn bar() -> (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) |
1218 | 310..315 'bar()': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) | 1218 | 310..315 'bar()': (impl Iterator<Item = impl Trait<u32>>, impl Trait<u64>) |
1219 | 321..322 'a': impl Iterator<Item = impl Trait<u32>> | 1219 | 321..322 'a': impl Iterator<Item = impl Trait<u32>> |
1220 | 321..329 'a.next()': impl Trait<u32> | 1220 | 321..329 'a.next()': impl Trait<u32> |
1221 | 321..335 'a.next().foo()': u32 | 1221 | 321..335 'a.next().foo()': u32 |
1222 | 341..342 'b': impl Trait<u64> | 1222 | 341..342 'b': impl Trait<u64> |
1223 | 341..348 'b.foo()': u64 | 1223 | 341..348 'b.foo()': u64 |
1224 | 358..364 '(c, d)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) | 1224 | 358..364 '(c, d)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) |
1225 | 359..360 'c': impl Iterator<Item = impl Trait<u128>> | 1225 | 359..360 'c': impl Iterator<Item = impl Trait<u128>> |
1226 | 362..363 'd': impl Trait<u128> | 1226 | 362..363 'd': impl Trait<u128> |
1227 | 367..370 'baz': fn baz<u128>(u128) -> (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) | 1227 | 367..370 'baz': fn baz<u128>(u128) -> (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) |
1228 | 367..377 'baz(1u128)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) | 1228 | 367..377 'baz(1u128)': (impl Iterator<Item = impl Trait<u128>>, impl Trait<u128>) |
1229 | 371..376 '1u128': u128 | 1229 | 371..376 '1u128': u128 |
1230 | 383..384 'c': impl Iterator<Item = impl Trait<u128>> | 1230 | 383..384 'c': impl Iterator<Item = impl Trait<u128>> |
1231 | 383..391 'c.next()': impl Trait<u128> | 1231 | 383..391 'c.next()': impl Trait<u128> |
1232 | 383..397 'c.next().foo()': u128 | 1232 | 383..397 'c.next().foo()': u128 |
1233 | 403..404 'd': impl Trait<u128> | 1233 | 403..404 'd': impl Trait<u128> |
1234 | 403..410 'd.foo()': u128 | 1234 | 403..410 'd.foo()': u128 |
1235 | "### | 1235 | "#]], |
1236 | ); | 1236 | ); |
1237 | } | 1237 | } |
1238 | 1238 | ||
1239 | #[test] | 1239 | #[test] |
1240 | fn dyn_trait() { | 1240 | fn dyn_trait() { |
1241 | assert_snapshot!( | 1241 | check_infer( |
1242 | infer(r#" | 1242 | r#" |
1243 | trait Trait<T> { | 1243 | trait Trait<T> { |
1244 | fn foo(&self) -> T; | 1244 | fn foo(&self) -> T; |
1245 | fn foo2(&self) -> i64; | 1245 | fn foo2(&self) -> i64; |
1246 | } | 1246 | } |
1247 | fn bar() -> dyn Trait<u64> {} | 1247 | fn bar() -> dyn Trait<u64> {} |
1248 | 1248 | ||
1249 | fn test(x: dyn Trait<u64>, y: &dyn Trait<u64>) { | 1249 | fn test(x: dyn Trait<u64>, y: &dyn Trait<u64>) { |
1250 | x; | 1250 | x; |
1251 | y; | 1251 | y; |
1252 | let z = bar(); | 1252 | let z = bar(); |
1253 | x.foo(); | 1253 | x.foo(); |
1254 | y.foo(); | 1254 | y.foo(); |
1255 | z.foo(); | 1255 | z.foo(); |
1256 | x.foo2(); | 1256 | x.foo2(); |
1257 | y.foo2(); | 1257 | y.foo2(); |
1258 | z.foo2(); | 1258 | z.foo2(); |
1259 | } | 1259 | } |
1260 | "#), | 1260 | "#, |
1261 | @r###" | 1261 | expect![[r#" |
1262 | 29..33 'self': &Self | 1262 | 29..33 'self': &Self |
1263 | 54..58 'self': &Self | 1263 | 54..58 'self': &Self |
1264 | 97..99 '{}': () | 1264 | 97..99 '{}': () |
1265 | 109..110 'x': dyn Trait<u64> | 1265 | 109..110 'x': dyn Trait<u64> |
1266 | 128..129 'y': &dyn Trait<u64> | 1266 | 128..129 'y': &dyn Trait<u64> |
1267 | 148..265 '{ ...2(); }': () | 1267 | 148..265 '{ ...2(); }': () |
1268 | 154..155 'x': dyn Trait<u64> | 1268 | 154..155 'x': dyn Trait<u64> |
1269 | 161..162 'y': &dyn Trait<u64> | 1269 | 161..162 'y': &dyn Trait<u64> |
1270 | 172..173 'z': dyn Trait<u64> | 1270 | 172..173 'z': dyn Trait<u64> |
1271 | 176..179 'bar': fn bar() -> dyn Trait<u64> | 1271 | 176..179 'bar': fn bar() -> dyn Trait<u64> |
1272 | 176..181 'bar()': dyn Trait<u64> | 1272 | 176..181 'bar()': dyn Trait<u64> |
1273 | 187..188 'x': dyn Trait<u64> | 1273 | 187..188 'x': dyn Trait<u64> |
1274 | 187..194 'x.foo()': u64 | 1274 | 187..194 'x.foo()': u64 |
1275 | 200..201 'y': &dyn Trait<u64> | 1275 | 200..201 'y': &dyn Trait<u64> |
1276 | 200..207 'y.foo()': u64 | 1276 | 200..207 'y.foo()': u64 |
1277 | 213..214 'z': dyn Trait<u64> | 1277 | 213..214 'z': dyn Trait<u64> |
1278 | 213..220 'z.foo()': u64 | 1278 | 213..220 'z.foo()': u64 |
1279 | 226..227 'x': dyn Trait<u64> | 1279 | 226..227 'x': dyn Trait<u64> |
1280 | 226..234 'x.foo2()': i64 | 1280 | 226..234 'x.foo2()': i64 |
1281 | 240..241 'y': &dyn Trait<u64> | 1281 | 240..241 'y': &dyn Trait<u64> |
1282 | 240..248 'y.foo2()': i64 | 1282 | 240..248 'y.foo2()': i64 |
1283 | 254..255 'z': dyn Trait<u64> | 1283 | 254..255 'z': dyn Trait<u64> |
1284 | 254..262 'z.foo2()': i64 | 1284 | 254..262 'z.foo2()': i64 |
1285 | "### | 1285 | "#]], |
1286 | ); | 1286 | ); |
1287 | } | 1287 | } |
1288 | 1288 | ||
1289 | #[test] | 1289 | #[test] |
1290 | fn dyn_trait_in_impl() { | 1290 | fn dyn_trait_in_impl() { |
1291 | assert_snapshot!( | 1291 | check_infer( |
1292 | infer(r#" | 1292 | r#" |
1293 | trait Trait<T, U> { | 1293 | trait Trait<T, U> { |
1294 | fn foo(&self) -> (T, U); | 1294 | fn foo(&self) -> (T, U); |
1295 | } | 1295 | } |
1296 | struct S<T, U> {} | 1296 | struct S<T, U> {} |
1297 | impl<T, U> S<T, U> { | 1297 | impl<T, U> S<T, U> { |
1298 | fn bar(&self) -> &dyn Trait<T, U> { loop {} } | 1298 | fn bar(&self) -> &dyn Trait<T, U> { loop {} } |
1299 | } | 1299 | } |
1300 | trait Trait2<T, U> { | 1300 | trait Trait2<T, U> { |
1301 | fn baz(&self) -> (T, U); | 1301 | fn baz(&self) -> (T, U); |
1302 | } | 1302 | } |
1303 | impl<T, U> Trait2<T, U> for dyn Trait<T, U> { } | 1303 | impl<T, U> Trait2<T, U> for dyn Trait<T, U> { } |
1304 | 1304 | ||
1305 | fn test(s: S<u32, i32>) { | 1305 | fn test(s: S<u32, i32>) { |
1306 | s.bar().baz(); | 1306 | s.bar().baz(); |
1307 | } | 1307 | } |
1308 | "#), | 1308 | "#, |
1309 | @r###" | 1309 | expect![[r#" |
1310 | 32..36 'self': &Self | 1310 | 32..36 'self': &Self |
1311 | 102..106 'self': &S<T, U> | 1311 | 102..106 'self': &S<T, U> |
1312 | 128..139 '{ loop {} }': &dyn Trait<T, U> | 1312 | 128..139 '{ loop {} }': &dyn Trait<T, U> |
1313 | 130..137 'loop {}': ! | 1313 | 130..137 'loop {}': ! |
1314 | 135..137 '{}': () | 1314 | 135..137 '{}': () |
1315 | 175..179 'self': &Self | 1315 | 175..179 'self': &Self |
1316 | 251..252 's': S<u32, i32> | 1316 | 251..252 's': S<u32, i32> |
1317 | 267..289 '{ ...z(); }': () | 1317 | 267..289 '{ ...z(); }': () |
1318 | 273..274 's': S<u32, i32> | 1318 | 273..274 's': S<u32, i32> |
1319 | 273..280 's.bar()': &dyn Trait<u32, i32> | 1319 | 273..280 's.bar()': &dyn Trait<u32, i32> |
1320 | 273..286 's.bar().baz()': (u32, i32) | 1320 | 273..286 's.bar().baz()': (u32, i32) |
1321 | "### | 1321 | "#]], |
1322 | ); | 1322 | ); |
1323 | } | 1323 | } |
1324 | 1324 | ||
1325 | #[test] | 1325 | #[test] |
1326 | fn dyn_trait_bare() { | 1326 | fn dyn_trait_bare() { |
1327 | assert_snapshot!( | 1327 | check_infer( |
1328 | infer(r#" | 1328 | r#" |
1329 | trait Trait { | 1329 | trait Trait { |
1330 | fn foo(&self) -> u64; | 1330 | fn foo(&self) -> u64; |
1331 | } | 1331 | } |
1332 | fn bar() -> Trait {} | 1332 | fn bar() -> Trait {} |
1333 | 1333 | ||
1334 | fn test(x: Trait, y: &Trait) -> u64 { | 1334 | fn test(x: Trait, y: &Trait) -> u64 { |
1335 | x; | 1335 | x; |
1336 | y; | 1336 | y; |
1337 | let z = bar(); | 1337 | let z = bar(); |
1338 | x.foo(); | 1338 | x.foo(); |
1339 | y.foo(); | 1339 | y.foo(); |
1340 | z.foo(); | 1340 | z.foo(); |
1341 | } | 1341 | } |
1342 | "#), | 1342 | "#, |
1343 | @r###" | 1343 | expect![[r#" |
1344 | 26..30 'self': &Self | 1344 | 26..30 'self': &Self |
1345 | 60..62 '{}': () | 1345 | 60..62 '{}': () |
1346 | 72..73 'x': dyn Trait | 1346 | 72..73 'x': dyn Trait |
1347 | 82..83 'y': &dyn Trait | 1347 | 82..83 'y': &dyn Trait |
1348 | 100..175 '{ ...o(); }': () | 1348 | 100..175 '{ ...o(); }': () |
1349 | 106..107 'x': dyn Trait | 1349 | 106..107 'x': dyn Trait |
1350 | 113..114 'y': &dyn Trait | 1350 | 113..114 'y': &dyn Trait |
1351 | 124..125 'z': dyn Trait | 1351 | 124..125 'z': dyn Trait |
1352 | 128..131 'bar': fn bar() -> dyn Trait | 1352 | 128..131 'bar': fn bar() -> dyn Trait |
1353 | 128..133 'bar()': dyn Trait | 1353 | 128..133 'bar()': dyn Trait |
1354 | 139..140 'x': dyn Trait | 1354 | 139..140 'x': dyn Trait |
1355 | 139..146 'x.foo()': u64 | 1355 | 139..146 'x.foo()': u64 |
1356 | 152..153 'y': &dyn Trait | 1356 | 152..153 'y': &dyn Trait |
1357 | 152..159 'y.foo()': u64 | 1357 | 152..159 'y.foo()': u64 |
1358 | 165..166 'z': dyn Trait | 1358 | 165..166 'z': dyn Trait |
1359 | 165..172 'z.foo()': u64 | 1359 | 165..172 'z.foo()': u64 |
1360 | "### | 1360 | "#]], |
1361 | ); | 1361 | ); |
1362 | } | 1362 | } |
1363 | 1363 | ||
1364 | #[test] | 1364 | #[test] |
1365 | fn weird_bounds() { | 1365 | fn weird_bounds() { |
1366 | assert_snapshot!( | 1366 | check_infer( |
1367 | infer(r#" | 1367 | r#" |
1368 | trait Trait {} | 1368 | trait Trait {} |
1369 | fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) { | 1369 | fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) {} |
1370 | } | 1370 | "#, |
1371 | "#), | 1371 | expect![[r#" |
1372 | @r###" | 1372 | 23..24 'a': impl Trait + {error} |
1373 | 23..24 'a': impl Trait + {error} | 1373 | 50..51 'b': impl {error} |
1374 | 50..51 'b': impl {error} | 1374 | 69..70 'c': impl Trait |
1375 | 69..70 'c': impl Trait | 1375 | 86..87 'd': impl {error} |
1376 | 86..87 'd': impl {error} | 1376 | 107..108 'e': impl {error} |
1377 | 107..108 'e': impl {error} | 1377 | 123..124 'f': impl Trait + {error} |
1378 | 123..124 'f': impl Trait + {error} | 1378 | 147..149 '{}': () |
1379 | 147..150 '{ }': () | 1379 | "#]], |
1380 | "### | ||
1381 | ); | 1380 | ); |
1382 | } | 1381 | } |
1383 | 1382 | ||
@@ -1399,66 +1398,66 @@ fn test(x: (impl Trait + UnknownTrait)) { | |||
1399 | 1398 | ||
1400 | #[test] | 1399 | #[test] |
1401 | fn assoc_type_bindings() { | 1400 | fn assoc_type_bindings() { |
1402 | assert_snapshot!( | 1401 | check_infer( |
1403 | infer(r#" | 1402 | r#" |
1404 | trait Trait { | 1403 | trait Trait { |
1405 | type Type; | 1404 | type Type; |
1406 | } | 1405 | } |
1407 | |||
1408 | fn get<T: Trait>(t: T) -> <T as Trait>::Type {} | ||
1409 | fn get2<U, T: Trait<Type = U>>(t: T) -> U {} | ||
1410 | fn set<T: Trait<Type = u64>>(t: T) -> T {t} | ||
1411 | 1406 | ||
1412 | struct S<T>; | 1407 | fn get<T: Trait>(t: T) -> <T as Trait>::Type {} |
1413 | impl<T> Trait for S<T> { type Type = T; } | 1408 | fn get2<U, T: Trait<Type = U>>(t: T) -> U {} |
1414 | 1409 | fn set<T: Trait<Type = u64>>(t: T) -> T {t} | |
1415 | fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) { | 1410 | |
1416 | get(x); | 1411 | struct S<T>; |
1417 | get2(x); | 1412 | impl<T> Trait for S<T> { type Type = T; } |
1418 | get(y); | 1413 | |
1419 | get2(y); | 1414 | fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) { |
1420 | get(set(S)); | 1415 | get(x); |
1421 | get2(set(S)); | 1416 | get2(x); |
1422 | get2(S::<str>); | 1417 | get(y); |
1423 | } | 1418 | get2(y); |
1424 | "#), | 1419 | get(set(S)); |
1425 | @r###" | 1420 | get2(set(S)); |
1426 | 49..50 't': T | 1421 | get2(S::<str>); |
1427 | 77..79 '{}': () | 1422 | } |
1428 | 111..112 't': T | 1423 | "#, |
1429 | 122..124 '{}': () | 1424 | expect![[r#" |
1430 | 154..155 't': T | 1425 | 49..50 't': T |
1431 | 165..168 '{t}': T | 1426 | 77..79 '{}': () |
1432 | 166..167 't': T | 1427 | 111..112 't': T |
1433 | 256..257 'x': T | 1428 | 122..124 '{}': () |
1434 | 262..263 'y': impl Trait<Type = i64> | 1429 | 154..155 't': T |
1435 | 289..397 '{ ...r>); }': () | 1430 | 165..168 '{t}': T |
1436 | 295..298 'get': fn get<T>(T) -> <T as Trait>::Type | 1431 | 166..167 't': T |
1437 | 295..301 'get(x)': u32 | 1432 | 256..257 'x': T |
1438 | 299..300 'x': T | 1433 | 262..263 'y': impl Trait<Type = i64> |
1439 | 307..311 'get2': fn get2<u32, T>(T) -> u32 | 1434 | 289..397 '{ ...r>); }': () |
1440 | 307..314 'get2(x)': u32 | 1435 | 295..298 'get': fn get<T>(T) -> <T as Trait>::Type |
1441 | 312..313 'x': T | 1436 | 295..301 'get(x)': u32 |
1442 | 320..323 'get': fn get<impl Trait<Type = i64>>(impl Trait<Type = i64>) -> <impl Trait<Type = i64> as Trait>::Type | 1437 | 299..300 'x': T |
1443 | 320..326 'get(y)': i64 | 1438 | 307..311 'get2': fn get2<u32, T>(T) -> u32 |
1444 | 324..325 'y': impl Trait<Type = i64> | 1439 | 307..314 'get2(x)': u32 |
1445 | 332..336 'get2': fn get2<i64, impl Trait<Type = i64>>(impl Trait<Type = i64>) -> i64 | 1440 | 312..313 'x': T |
1446 | 332..339 'get2(y)': i64 | 1441 | 320..323 'get': fn get<impl Trait<Type = i64>>(impl Trait<Type = i64>) -> <impl Trait<Type = i64> as Trait>::Type |
1447 | 337..338 'y': impl Trait<Type = i64> | 1442 | 320..326 'get(y)': i64 |
1448 | 345..348 'get': fn get<S<u64>>(S<u64>) -> <S<u64> as Trait>::Type | 1443 | 324..325 'y': impl Trait<Type = i64> |
1449 | 345..356 'get(set(S))': u64 | 1444 | 332..336 'get2': fn get2<i64, impl Trait<Type = i64>>(impl Trait<Type = i64>) -> i64 |
1450 | 349..352 'set': fn set<S<u64>>(S<u64>) -> S<u64> | 1445 | 332..339 'get2(y)': i64 |
1451 | 349..355 'set(S)': S<u64> | 1446 | 337..338 'y': impl Trait<Type = i64> |
1452 | 353..354 'S': S<u64> | 1447 | 345..348 'get': fn get<S<u64>>(S<u64>) -> <S<u64> as Trait>::Type |
1453 | 362..366 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64 | 1448 | 345..356 'get(set(S))': u64 |
1454 | 362..374 'get2(set(S))': u64 | 1449 | 349..352 'set': fn set<S<u64>>(S<u64>) -> S<u64> |
1455 | 367..370 'set': fn set<S<u64>>(S<u64>) -> S<u64> | 1450 | 349..355 'set(S)': S<u64> |
1456 | 367..373 'set(S)': S<u64> | 1451 | 353..354 'S': S<u64> |
1457 | 371..372 'S': S<u64> | 1452 | 362..366 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64 |
1458 | 380..384 'get2': fn get2<str, S<str>>(S<str>) -> str | 1453 | 362..374 'get2(set(S))': u64 |
1459 | 380..394 'get2(S::<str>)': str | 1454 | 367..370 'set': fn set<S<u64>>(S<u64>) -> S<u64> |
1460 | 385..393 'S::<str>': S<str> | 1455 | 367..373 'set(S)': S<u64> |
1461 | "### | 1456 | 371..372 'S': S<u64> |
1457 | 380..384 'get2': fn get2<str, S<str>>(S<str>) -> str | ||
1458 | 380..394 'get2(S::<str>)': str | ||
1459 | 385..393 'S::<str>': S<str> | ||
1460 | "#]], | ||
1462 | ); | 1461 | ); |
1463 | } | 1462 | } |
1464 | 1463 | ||
@@ -1506,27 +1505,27 @@ mod iter { | |||
1506 | 1505 | ||
1507 | #[test] | 1506 | #[test] |
1508 | fn projection_eq_within_chalk() { | 1507 | fn projection_eq_within_chalk() { |
1509 | assert_snapshot!( | 1508 | check_infer( |
1510 | infer(r#" | 1509 | r#" |
1511 | trait Trait1 { | 1510 | trait Trait1 { |
1512 | type Type; | 1511 | type Type; |
1513 | } | 1512 | } |
1514 | trait Trait2<T> { | 1513 | trait Trait2<T> { |
1515 | fn foo(self) -> T; | 1514 | fn foo(self) -> T; |
1516 | } | 1515 | } |
1517 | impl<T, U> Trait2<T> for U where U: Trait1<Type = T> {} | 1516 | impl<T, U> Trait2<T> for U where U: Trait1<Type = T> {} |
1518 | 1517 | ||
1519 | fn test<T: Trait1<Type = u32>>(x: T) { | 1518 | fn test<T: Trait1<Type = u32>>(x: T) { |
1520 | x.foo(); | 1519 | x.foo(); |
1521 | } | 1520 | } |
1522 | "#), | 1521 | "#, |
1523 | @r###" | 1522 | expect![[r#" |
1524 | 61..65 'self': Self | 1523 | 61..65 'self': Self |
1525 | 163..164 'x': T | 1524 | 163..164 'x': T |
1526 | 169..185 '{ ...o(); }': () | 1525 | 169..185 '{ ...o(); }': () |
1527 | 175..176 'x': T | 1526 | 175..176 'x': T |
1528 | 175..182 'x.foo()': u32 | 1527 | 175..182 'x.foo()': u32 |
1529 | "### | 1528 | "#]], |
1530 | ); | 1529 | ); |
1531 | } | 1530 | } |
1532 | 1531 | ||
@@ -1549,445 +1548,445 @@ fn test<T: foo::Trait>(x: T) { | |||
1549 | 1548 | ||
1550 | #[test] | 1549 | #[test] |
1551 | fn super_trait_method_resolution() { | 1550 | fn super_trait_method_resolution() { |
1552 | assert_snapshot!( | 1551 | check_infer( |
1553 | infer(r#" | 1552 | r#" |
1554 | mod foo { | 1553 | mod foo { |
1555 | trait SuperTrait { | 1554 | trait SuperTrait { |
1556 | fn foo(&self) -> u32 {} | 1555 | fn foo(&self) -> u32 {} |
1557 | } | 1556 | } |
1558 | } | 1557 | } |
1559 | trait Trait1: foo::SuperTrait {} | 1558 | trait Trait1: foo::SuperTrait {} |
1560 | trait Trait2 where Self: foo::SuperTrait {} | 1559 | trait Trait2 where Self: foo::SuperTrait {} |
1561 | 1560 | ||
1562 | fn test<T: Trait1, U: Trait2>(x: T, y: U) { | 1561 | fn test<T: Trait1, U: Trait2>(x: T, y: U) { |
1563 | x.foo(); | 1562 | x.foo(); |
1564 | y.foo(); | 1563 | y.foo(); |
1565 | } | 1564 | } |
1566 | "#), | 1565 | "#, |
1567 | @r###" | 1566 | expect![[r#" |
1568 | 49..53 'self': &Self | 1567 | 49..53 'self': &Self |
1569 | 62..64 '{}': () | 1568 | 62..64 '{}': () |
1570 | 181..182 'x': T | 1569 | 181..182 'x': T |
1571 | 187..188 'y': U | 1570 | 187..188 'y': U |
1572 | 193..222 '{ ...o(); }': () | 1571 | 193..222 '{ ...o(); }': () |
1573 | 199..200 'x': T | 1572 | 199..200 'x': T |
1574 | 199..206 'x.foo()': u32 | 1573 | 199..206 'x.foo()': u32 |
1575 | 212..213 'y': U | 1574 | 212..213 'y': U |
1576 | 212..219 'y.foo()': u32 | 1575 | 212..219 'y.foo()': u32 |
1577 | "### | 1576 | "#]], |
1578 | ); | 1577 | ); |
1579 | } | 1578 | } |
1580 | 1579 | ||
1581 | #[test] | 1580 | #[test] |
1582 | fn super_trait_impl_trait_method_resolution() { | 1581 | fn super_trait_impl_trait_method_resolution() { |
1583 | assert_snapshot!( | 1582 | check_infer( |
1584 | infer(r#" | 1583 | r#" |
1585 | mod foo { | 1584 | mod foo { |
1586 | trait SuperTrait { | 1585 | trait SuperTrait { |
1587 | fn foo(&self) -> u32 {} | 1586 | fn foo(&self) -> u32 {} |
1588 | } | 1587 | } |
1589 | } | 1588 | } |
1590 | trait Trait1: foo::SuperTrait {} | 1589 | trait Trait1: foo::SuperTrait {} |
1591 | 1590 | ||
1592 | fn test(x: &impl Trait1) { | 1591 | fn test(x: &impl Trait1) { |
1593 | x.foo(); | 1592 | x.foo(); |
1594 | } | 1593 | } |
1595 | "#), | 1594 | "#, |
1596 | @r###" | 1595 | expect![[r#" |
1597 | 49..53 'self': &Self | 1596 | 49..53 'self': &Self |
1598 | 62..64 '{}': () | 1597 | 62..64 '{}': () |
1599 | 115..116 'x': &impl Trait1 | 1598 | 115..116 'x': &impl Trait1 |
1600 | 132..148 '{ ...o(); }': () | 1599 | 132..148 '{ ...o(); }': () |
1601 | 138..139 'x': &impl Trait1 | 1600 | 138..139 'x': &impl Trait1 |
1602 | 138..145 'x.foo()': u32 | 1601 | 138..145 'x.foo()': u32 |
1603 | "### | 1602 | "#]], |
1604 | ); | 1603 | ); |
1605 | } | 1604 | } |
1606 | 1605 | ||
1607 | #[test] | 1606 | #[test] |
1608 | fn super_trait_cycle() { | 1607 | fn super_trait_cycle() { |
1609 | // This just needs to not crash | 1608 | // This just needs to not crash |
1610 | assert_snapshot!( | 1609 | check_infer( |
1611 | infer(r#" | 1610 | r#" |
1612 | trait A: B {} | 1611 | trait A: B {} |
1613 | trait B: A {} | 1612 | trait B: A {} |
1614 | 1613 | ||
1615 | fn test<T: A>(x: T) { | 1614 | fn test<T: A>(x: T) { |
1616 | x.foo(); | 1615 | x.foo(); |
1617 | } | 1616 | } |
1618 | "#), | 1617 | "#, |
1619 | @r###" | 1618 | expect![[r#" |
1620 | 43..44 'x': T | 1619 | 43..44 'x': T |
1621 | 49..65 '{ ...o(); }': () | 1620 | 49..65 '{ ...o(); }': () |
1622 | 55..56 'x': T | 1621 | 55..56 'x': T |
1623 | 55..62 'x.foo()': {unknown} | 1622 | 55..62 'x.foo()': {unknown} |
1624 | "### | 1623 | "#]], |
1625 | ); | 1624 | ); |
1626 | } | 1625 | } |
1627 | 1626 | ||
1628 | #[test] | 1627 | #[test] |
1629 | fn super_trait_assoc_type_bounds() { | 1628 | fn super_trait_assoc_type_bounds() { |
1630 | assert_snapshot!( | 1629 | check_infer( |
1631 | infer(r#" | 1630 | r#" |
1632 | trait SuperTrait { type Type; } | 1631 | trait SuperTrait { type Type; } |
1633 | trait Trait where Self: SuperTrait {} | 1632 | trait Trait where Self: SuperTrait {} |
1634 | 1633 | ||
1635 | fn get2<U, T: Trait<Type = U>>(t: T) -> U {} | 1634 | fn get2<U, T: Trait<Type = U>>(t: T) -> U {} |
1636 | fn set<T: Trait<Type = u64>>(t: T) -> T {t} | 1635 | fn set<T: Trait<Type = u64>>(t: T) -> T {t} |
1637 | 1636 | ||
1638 | struct S<T>; | 1637 | struct S<T>; |
1639 | impl<T> SuperTrait for S<T> { type Type = T; } | 1638 | impl<T> SuperTrait for S<T> { type Type = T; } |
1640 | impl<T> Trait for S<T> {} | 1639 | impl<T> Trait for S<T> {} |
1641 | 1640 | ||
1642 | fn test() { | 1641 | fn test() { |
1643 | get2(set(S)); | 1642 | get2(set(S)); |
1644 | } | 1643 | } |
1645 | "#), | 1644 | "#, |
1646 | @r###" | 1645 | expect![[r#" |
1647 | 102..103 't': T | 1646 | 102..103 't': T |
1648 | 113..115 '{}': () | 1647 | 113..115 '{}': () |
1649 | 145..146 't': T | 1648 | 145..146 't': T |
1650 | 156..159 '{t}': T | 1649 | 156..159 '{t}': T |
1651 | 157..158 't': T | 1650 | 157..158 't': T |
1652 | 258..279 '{ ...S)); }': () | 1651 | 258..279 '{ ...S)); }': () |
1653 | 264..268 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64 | 1652 | 264..268 'get2': fn get2<u64, S<u64>>(S<u64>) -> u64 |
1654 | 264..276 'get2(set(S))': u64 | 1653 | 264..276 'get2(set(S))': u64 |
1655 | 269..272 'set': fn set<S<u64>>(S<u64>) -> S<u64> | 1654 | 269..272 'set': fn set<S<u64>>(S<u64>) -> S<u64> |
1656 | 269..275 'set(S)': S<u64> | 1655 | 269..275 'set(S)': S<u64> |
1657 | 273..274 'S': S<u64> | 1656 | 273..274 'S': S<u64> |
1658 | "### | 1657 | "#]], |
1659 | ); | 1658 | ); |
1660 | } | 1659 | } |
1661 | 1660 | ||
1662 | #[test] | 1661 | #[test] |
1663 | fn fn_trait() { | 1662 | fn fn_trait() { |
1664 | assert_snapshot!( | 1663 | check_infer( |
1665 | infer(r#" | 1664 | r#" |
1666 | trait FnOnce<Args> { | 1665 | trait FnOnce<Args> { |
1667 | type Output; | 1666 | type Output; |
1668 | 1667 | ||
1669 | fn call_once(self, args: Args) -> <Self as FnOnce<Args>>::Output; | 1668 | fn call_once(self, args: Args) -> <Self as FnOnce<Args>>::Output; |
1670 | } | 1669 | } |
1671 | 1670 | ||
1672 | fn test<F: FnOnce(u32, u64) -> u128>(f: F) { | 1671 | fn test<F: FnOnce(u32, u64) -> u128>(f: F) { |
1673 | f.call_once((1, 2)); | 1672 | f.call_once((1, 2)); |
1674 | } | 1673 | } |
1675 | "#), | 1674 | "#, |
1676 | @r###" | 1675 | expect![[r#" |
1677 | 56..60 'self': Self | 1676 | 56..60 'self': Self |
1678 | 62..66 'args': Args | 1677 | 62..66 'args': Args |
1679 | 149..150 'f': F | 1678 | 149..150 'f': F |
1680 | 155..183 '{ ...2)); }': () | 1679 | 155..183 '{ ...2)); }': () |
1681 | 161..162 'f': F | 1680 | 161..162 'f': F |
1682 | 161..180 'f.call...1, 2))': u128 | 1681 | 161..180 'f.call...1, 2))': u128 |
1683 | 173..179 '(1, 2)': (u32, u64) | 1682 | 173..179 '(1, 2)': (u32, u64) |
1684 | 174..175 '1': u32 | 1683 | 174..175 '1': u32 |
1685 | 177..178 '2': u64 | 1684 | 177..178 '2': u64 |
1686 | "### | 1685 | "#]], |
1687 | ); | 1686 | ); |
1688 | } | 1687 | } |
1689 | 1688 | ||
1690 | #[test] | 1689 | #[test] |
1691 | fn fn_ptr_and_item() { | 1690 | fn fn_ptr_and_item() { |
1692 | assert_snapshot!( | 1691 | check_infer( |
1693 | infer(r#" | 1692 | r#" |
1694 | #[lang="fn_once"] | 1693 | #[lang="fn_once"] |
1695 | trait FnOnce<Args> { | 1694 | trait FnOnce<Args> { |
1696 | type Output; | 1695 | type Output; |
1697 | 1696 | ||
1698 | fn call_once(self, args: Args) -> Self::Output; | 1697 | fn call_once(self, args: Args) -> Self::Output; |
1699 | } | 1698 | } |
1700 | 1699 | ||
1701 | trait Foo<T> { | 1700 | trait Foo<T> { |
1702 | fn foo(&self) -> T; | 1701 | fn foo(&self) -> T; |
1703 | } | 1702 | } |
1704 | 1703 | ||
1705 | struct Bar<T>(T); | 1704 | struct Bar<T>(T); |
1706 | 1705 | ||
1707 | impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> { | 1706 | impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> { |
1708 | fn foo(&self) -> (A1, R) {} | 1707 | fn foo(&self) -> (A1, R) {} |
1709 | } | 1708 | } |
1710 | 1709 | ||
1711 | enum Opt<T> { None, Some(T) } | 1710 | enum Opt<T> { None, Some(T) } |
1712 | impl<T> Opt<T> { | 1711 | impl<T> Opt<T> { |
1713 | fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> {} | 1712 | fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> {} |
1714 | } | 1713 | } |
1715 | 1714 | ||
1716 | fn test() { | 1715 | fn test() { |
1717 | let bar: Bar<fn(u8) -> u32>; | 1716 | let bar: Bar<fn(u8) -> u32>; |
1718 | bar.foo(); | 1717 | bar.foo(); |
1719 | 1718 | ||
1720 | let opt: Opt<u8>; | 1719 | let opt: Opt<u8>; |
1721 | let f: fn(u8) -> u32; | 1720 | let f: fn(u8) -> u32; |
1722 | opt.map(f); | 1721 | opt.map(f); |
1723 | } | 1722 | } |
1724 | "#), | 1723 | "#, |
1725 | @r###" | 1724 | expect![[r#" |
1726 | 74..78 'self': Self | 1725 | 74..78 'self': Self |
1727 | 80..84 'args': Args | 1726 | 80..84 'args': Args |
1728 | 139..143 'self': &Self | 1727 | 139..143 'self': &Self |
1729 | 243..247 'self': &Bar<F> | 1728 | 243..247 'self': &Bar<F> |
1730 | 260..262 '{}': () | 1729 | 260..262 '{}': () |
1731 | 346..350 'self': Opt<T> | 1730 | 346..350 'self': Opt<T> |
1732 | 352..353 'f': F | 1731 | 352..353 'f': F |
1733 | 368..370 '{}': () | 1732 | 368..370 '{}': () |
1734 | 384..500 '{ ...(f); }': () | 1733 | 384..500 '{ ...(f); }': () |
1735 | 394..397 'bar': Bar<fn(u8) -> u32> | 1734 | 394..397 'bar': Bar<fn(u8) -> u32> |
1736 | 423..426 'bar': Bar<fn(u8) -> u32> | 1735 | 423..426 'bar': Bar<fn(u8) -> u32> |
1737 | 423..432 'bar.foo()': (u8, u32) | 1736 | 423..432 'bar.foo()': (u8, u32) |
1738 | 443..446 'opt': Opt<u8> | 1737 | 443..446 'opt': Opt<u8> |
1739 | 465..466 'f': fn(u8) -> u32 | 1738 | 465..466 'f': fn(u8) -> u32 |
1740 | 487..490 'opt': Opt<u8> | 1739 | 487..490 'opt': Opt<u8> |
1741 | 487..497 'opt.map(f)': Opt<u32> | 1740 | 487..497 'opt.map(f)': Opt<u32> |
1742 | 495..496 'f': fn(u8) -> u32 | 1741 | 495..496 'f': fn(u8) -> u32 |
1743 | "### | 1742 | "#]], |
1744 | ); | 1743 | ); |
1745 | } | 1744 | } |
1746 | 1745 | ||
1747 | #[test] | 1746 | #[test] |
1748 | fn fn_trait_deref_with_ty_default() { | 1747 | fn fn_trait_deref_with_ty_default() { |
1749 | assert_snapshot!( | 1748 | check_infer( |
1750 | infer(r#" | 1749 | r#" |
1751 | #[lang = "deref"] | 1750 | #[lang = "deref"] |
1752 | trait Deref { | 1751 | trait Deref { |
1753 | type Target; | 1752 | type Target; |
1754 | 1753 | ||
1755 | fn deref(&self) -> &Self::Target; | 1754 | fn deref(&self) -> &Self::Target; |
1756 | } | 1755 | } |
1757 | 1756 | ||
1758 | #[lang="fn_once"] | 1757 | #[lang="fn_once"] |
1759 | trait FnOnce<Args> { | 1758 | trait FnOnce<Args> { |
1760 | type Output; | 1759 | type Output; |
1761 | 1760 | ||
1762 | fn call_once(self, args: Args) -> Self::Output; | 1761 | fn call_once(self, args: Args) -> Self::Output; |
1763 | } | 1762 | } |
1764 | 1763 | ||
1765 | struct Foo; | 1764 | struct Foo; |
1766 | 1765 | ||
1767 | impl Foo { | 1766 | impl Foo { |
1768 | fn foo(&self) -> usize {} | 1767 | fn foo(&self) -> usize {} |
1769 | } | 1768 | } |
1770 | 1769 | ||
1771 | struct Lazy<T, F = fn() -> T>(F); | 1770 | struct Lazy<T, F = fn() -> T>(F); |
1772 | 1771 | ||
1773 | impl<T, F> Lazy<T, F> { | 1772 | impl<T, F> Lazy<T, F> { |
1774 | pub fn new(f: F) -> Lazy<T, F> {} | 1773 | pub fn new(f: F) -> Lazy<T, F> {} |
1775 | } | 1774 | } |
1776 | 1775 | ||
1777 | impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> { | 1776 | impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> { |
1778 | type Target = T; | 1777 | type Target = T; |
1779 | } | 1778 | } |
1780 | 1779 | ||
1781 | fn test() { | 1780 | fn test() { |
1782 | let lazy1: Lazy<Foo, _> = Lazy::new(|| Foo); | 1781 | let lazy1: Lazy<Foo, _> = Lazy::new(|| Foo); |
1783 | let r1 = lazy1.foo(); | 1782 | let r1 = lazy1.foo(); |
1784 | 1783 | ||
1785 | fn make_foo_fn() -> Foo {} | 1784 | fn make_foo_fn() -> Foo {} |
1786 | let make_foo_fn_ptr: fn() -> Foo = make_foo_fn; | 1785 | let make_foo_fn_ptr: fn() -> Foo = make_foo_fn; |
1787 | let lazy2: Lazy<Foo, _> = Lazy::new(make_foo_fn_ptr); | 1786 | let lazy2: Lazy<Foo, _> = Lazy::new(make_foo_fn_ptr); |
1788 | let r2 = lazy2.foo(); | 1787 | let r2 = lazy2.foo(); |
1789 | } | 1788 | } |
1790 | "#), | 1789 | "#, |
1791 | @r###" | 1790 | expect![[r#" |
1792 | 64..68 'self': &Self | 1791 | 64..68 'self': &Self |
1793 | 165..169 'self': Self | 1792 | 165..169 'self': Self |
1794 | 171..175 'args': Args | 1793 | 171..175 'args': Args |
1795 | 239..243 'self': &Foo | 1794 | 239..243 'self': &Foo |
1796 | 254..256 '{}': () | 1795 | 254..256 '{}': () |
1797 | 334..335 'f': F | 1796 | 334..335 'f': F |
1798 | 354..356 '{}': () | 1797 | 354..356 '{}': () |
1799 | 443..689 '{ ...o(); }': () | 1798 | 443..689 '{ ...o(); }': () |
1800 | 453..458 'lazy1': Lazy<Foo, || -> Foo> | 1799 | 453..458 'lazy1': Lazy<Foo, || -> Foo> |
1801 | 475..484 'Lazy::new': fn new<Foo, || -> Foo>(|| -> Foo) -> Lazy<Foo, || -> Foo> | 1800 | 475..484 'Lazy::new': fn new<Foo, || -> Foo>(|| -> Foo) -> Lazy<Foo, || -> Foo> |
1802 | 475..492 'Lazy::...| Foo)': Lazy<Foo, || -> Foo> | 1801 | 475..492 'Lazy::...| Foo)': Lazy<Foo, || -> Foo> |
1803 | 485..491 '|| Foo': || -> Foo | 1802 | 485..491 '|| Foo': || -> Foo |
1804 | 488..491 'Foo': Foo | 1803 | 488..491 'Foo': Foo |
1805 | 502..504 'r1': usize | 1804 | 502..504 'r1': usize |
1806 | 507..512 'lazy1': Lazy<Foo, || -> Foo> | 1805 | 507..512 'lazy1': Lazy<Foo, || -> Foo> |
1807 | 507..518 'lazy1.foo()': usize | 1806 | 507..518 'lazy1.foo()': usize |
1808 | 560..575 'make_foo_fn_ptr': fn() -> Foo | 1807 | 560..575 'make_foo_fn_ptr': fn() -> Foo |
1809 | 591..602 'make_foo_fn': fn make_foo_fn() -> Foo | 1808 | 591..602 'make_foo_fn': fn make_foo_fn() -> Foo |
1810 | 612..617 'lazy2': Lazy<Foo, fn() -> Foo> | 1809 | 612..617 'lazy2': Lazy<Foo, fn() -> Foo> |
1811 | 634..643 'Lazy::new': fn new<Foo, fn() -> Foo>(fn() -> Foo) -> Lazy<Foo, fn() -> Foo> | 1810 | 634..643 'Lazy::new': fn new<Foo, fn() -> Foo>(fn() -> Foo) -> Lazy<Foo, fn() -> Foo> |
1812 | 634..660 'Lazy::...n_ptr)': Lazy<Foo, fn() -> Foo> | 1811 | 634..660 'Lazy::...n_ptr)': Lazy<Foo, fn() -> Foo> |
1813 | 644..659 'make_foo_fn_ptr': fn() -> Foo | 1812 | 644..659 'make_foo_fn_ptr': fn() -> Foo |
1814 | 670..672 'r2': usize | 1813 | 670..672 'r2': usize |
1815 | 675..680 'lazy2': Lazy<Foo, fn() -> Foo> | 1814 | 675..680 'lazy2': Lazy<Foo, fn() -> Foo> |
1816 | 675..686 'lazy2.foo()': usize | 1815 | 675..686 'lazy2.foo()': usize |
1817 | 549..551 '{}': () | 1816 | 549..551 '{}': () |
1818 | "### | 1817 | "#]], |
1819 | ); | 1818 | ); |
1820 | } | 1819 | } |
1821 | 1820 | ||
1822 | #[test] | 1821 | #[test] |
1823 | fn closure_1() { | 1822 | fn closure_1() { |
1824 | assert_snapshot!( | 1823 | check_infer( |
1825 | infer(r#" | 1824 | r#" |
1826 | #[lang = "fn_once"] | 1825 | #[lang = "fn_once"] |
1827 | trait FnOnce<Args> { | 1826 | trait FnOnce<Args> { |
1828 | type Output; | 1827 | type Output; |
1829 | } | 1828 | } |
1830 | 1829 | ||
1831 | enum Option<T> { Some(T), None } | 1830 | enum Option<T> { Some(T), None } |
1832 | impl<T> Option<T> { | 1831 | impl<T> Option<T> { |
1833 | fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {} | 1832 | fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {} |
1834 | } | 1833 | } |
1835 | 1834 | ||
1836 | fn test() { | 1835 | fn test() { |
1837 | let x = Option::Some(1u32); | 1836 | let x = Option::Some(1u32); |
1838 | x.map(|v| v + 1); | 1837 | x.map(|v| v + 1); |
1839 | x.map(|_v| 1u64); | 1838 | x.map(|_v| 1u64); |
1840 | let y: Option<i64> = x.map(|_v| 1); | 1839 | let y: Option<i64> = x.map(|_v| 1); |
1841 | } | 1840 | } |
1842 | "#), | 1841 | "#, |
1843 | @r###" | 1842 | expect![[r#" |
1844 | 147..151 'self': Option<T> | 1843 | 147..151 'self': Option<T> |
1845 | 153..154 'f': F | 1844 | 153..154 'f': F |
1846 | 172..174 '{}': () | 1845 | 172..174 '{}': () |
1847 | 188..307 '{ ... 1); }': () | 1846 | 188..307 '{ ... 1); }': () |
1848 | 198..199 'x': Option<u32> | 1847 | 198..199 'x': Option<u32> |
1849 | 202..214 'Option::Some': Some<u32>(u32) -> Option<u32> | 1848 | 202..214 'Option::Some': Some<u32>(u32) -> Option<u32> |
1850 | 202..220 'Option...(1u32)': Option<u32> | 1849 | 202..220 'Option...(1u32)': Option<u32> |
1851 | 215..219 '1u32': u32 | 1850 | 215..219 '1u32': u32 |
1852 | 226..227 'x': Option<u32> | 1851 | 226..227 'x': Option<u32> |
1853 | 226..242 'x.map(...v + 1)': Option<u32> | 1852 | 226..242 'x.map(...v + 1)': Option<u32> |
1854 | 232..241 '|v| v + 1': |u32| -> u32 | 1853 | 232..241 '|v| v + 1': |u32| -> u32 |
1855 | 233..234 'v': u32 | 1854 | 233..234 'v': u32 |
1856 | 236..237 'v': u32 | 1855 | 236..237 'v': u32 |
1857 | 236..241 'v + 1': u32 | 1856 | 236..241 'v + 1': u32 |
1858 | 240..241 '1': u32 | 1857 | 240..241 '1': u32 |
1859 | 248..249 'x': Option<u32> | 1858 | 248..249 'x': Option<u32> |
1860 | 248..264 'x.map(... 1u64)': Option<u64> | 1859 | 248..264 'x.map(... 1u64)': Option<u64> |
1861 | 254..263 '|_v| 1u64': |u32| -> u64 | 1860 | 254..263 '|_v| 1u64': |u32| -> u64 |
1862 | 255..257 '_v': u32 | 1861 | 255..257 '_v': u32 |
1863 | 259..263 '1u64': u64 | 1862 | 259..263 '1u64': u64 |
1864 | 274..275 'y': Option<i64> | 1863 | 274..275 'y': Option<i64> |
1865 | 291..292 'x': Option<u32> | 1864 | 291..292 'x': Option<u32> |
1866 | 291..304 'x.map(|_v| 1)': Option<i64> | 1865 | 291..304 'x.map(|_v| 1)': Option<i64> |
1867 | 297..303 '|_v| 1': |u32| -> i64 | 1866 | 297..303 '|_v| 1': |u32| -> i64 |
1868 | 298..300 '_v': u32 | 1867 | 298..300 '_v': u32 |
1869 | 302..303 '1': i64 | 1868 | 302..303 '1': i64 |
1870 | "### | 1869 | "#]], |
1871 | ); | 1870 | ); |
1872 | } | 1871 | } |
1873 | 1872 | ||
1874 | #[test] | 1873 | #[test] |
1875 | fn closure_2() { | 1874 | fn closure_2() { |
1876 | assert_snapshot!( | 1875 | check_infer( |
1877 | infer(r#" | 1876 | r#" |
1878 | trait FnOnce<Args> { | 1877 | trait FnOnce<Args> { |
1879 | type Output; | 1878 | type Output; |
1880 | } | 1879 | } |
1881 | 1880 | ||
1882 | fn test<F: FnOnce(u32) -> u64>(f: F) { | 1881 | fn test<F: FnOnce(u32) -> u64>(f: F) { |
1883 | f(1); | 1882 | f(1); |
1884 | let g = |v| v + 1; | 1883 | let g = |v| v + 1; |
1885 | g(1u64); | 1884 | g(1u64); |
1886 | let h = |v| 1u128 + v; | 1885 | let h = |v| 1u128 + v; |
1887 | } | 1886 | } |
1888 | "#), | 1887 | "#, |
1889 | @r###" | 1888 | expect![[r#" |
1890 | 72..73 'f': F | 1889 | 72..73 'f': F |
1891 | 78..154 '{ ...+ v; }': () | 1890 | 78..154 '{ ...+ v; }': () |
1892 | 84..85 'f': F | 1891 | 84..85 'f': F |
1893 | 84..88 'f(1)': {unknown} | 1892 | 84..88 'f(1)': {unknown} |
1894 | 86..87 '1': i32 | 1893 | 86..87 '1': i32 |
1895 | 98..99 'g': |u64| -> i32 | 1894 | 98..99 'g': |u64| -> i32 |
1896 | 102..111 '|v| v + 1': |u64| -> i32 | 1895 | 102..111 '|v| v + 1': |u64| -> i32 |
1897 | 103..104 'v': u64 | 1896 | 103..104 'v': u64 |
1898 | 106..107 'v': u64 | 1897 | 106..107 'v': u64 |
1899 | 106..111 'v + 1': i32 | 1898 | 106..111 'v + 1': i32 |
1900 | 110..111 '1': i32 | 1899 | 110..111 '1': i32 |
1901 | 117..118 'g': |u64| -> i32 | 1900 | 117..118 'g': |u64| -> i32 |
1902 | 117..124 'g(1u64)': i32 | 1901 | 117..124 'g(1u64)': i32 |
1903 | 119..123 '1u64': u64 | 1902 | 119..123 '1u64': u64 |
1904 | 134..135 'h': |u128| -> u128 | 1903 | 134..135 'h': |u128| -> u128 |
1905 | 138..151 '|v| 1u128 + v': |u128| -> u128 | 1904 | 138..151 '|v| 1u128 + v': |u128| -> u128 |
1906 | 139..140 'v': u128 | 1905 | 139..140 'v': u128 |
1907 | 142..147 '1u128': u128 | 1906 | 142..147 '1u128': u128 |
1908 | 142..151 '1u128 + v': u128 | 1907 | 142..151 '1u128 + v': u128 |
1909 | 150..151 'v': u128 | 1908 | 150..151 'v': u128 |
1910 | "### | 1909 | "#]], |
1911 | ); | 1910 | ); |
1912 | } | 1911 | } |
1913 | 1912 | ||
1914 | #[test] | 1913 | #[test] |
1915 | fn closure_as_argument_inference_order() { | 1914 | fn closure_as_argument_inference_order() { |
1916 | assert_snapshot!( | 1915 | check_infer( |
1917 | infer(r#" | 1916 | r#" |
1918 | #[lang = "fn_once"] | 1917 | #[lang = "fn_once"] |
1919 | trait FnOnce<Args> { | 1918 | trait FnOnce<Args> { |
1920 | type Output; | 1919 | type Output; |
1921 | } | 1920 | } |
1922 | 1921 | ||
1923 | fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U {} | 1922 | fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U {} |
1924 | fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U {} | 1923 | fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U {} |
1925 | 1924 | ||
1926 | struct S; | 1925 | struct S; |
1927 | impl S { | 1926 | impl S { |
1928 | fn method(self) -> u64; | 1927 | fn method(self) -> u64; |
1929 | 1928 | ||
1930 | fn foo1<T, U, F: FnOnce(T) -> U>(self, x: T, f: F) -> U {} | 1929 | fn foo1<T, U, F: FnOnce(T) -> U>(self, x: T, f: F) -> U {} |
1931 | fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U {} | 1930 | fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U {} |
1932 | } | 1931 | } |
1933 | 1932 | ||
1934 | fn test() { | 1933 | fn test() { |
1935 | let x1 = foo1(S, |s| s.method()); | 1934 | let x1 = foo1(S, |s| s.method()); |
1936 | let x2 = foo2(|s| s.method(), S); | 1935 | let x2 = foo2(|s| s.method(), S); |
1937 | let x3 = S.foo1(S, |s| s.method()); | 1936 | let x3 = S.foo1(S, |s| s.method()); |
1938 | let x4 = S.foo2(|s| s.method(), S); | 1937 | let x4 = S.foo2(|s| s.method(), S); |
1939 | } | 1938 | } |
1940 | "#), | 1939 | "#, |
1941 | @r###" | 1940 | expect![[r#" |
1942 | 94..95 'x': T | 1941 | 94..95 'x': T |
1943 | 100..101 'f': F | 1942 | 100..101 'f': F |
1944 | 111..113 '{}': () | 1943 | 111..113 '{}': () |
1945 | 147..148 'f': F | 1944 | 147..148 'f': F |
1946 | 153..154 'x': T | 1945 | 153..154 'x': T |
1947 | 164..166 '{}': () | 1946 | 164..166 '{}': () |
1948 | 201..205 'self': S | 1947 | 201..205 'self': S |
1949 | 253..257 'self': S | 1948 | 253..257 'self': S |
1950 | 259..260 'x': T | 1949 | 259..260 'x': T |
1951 | 265..266 'f': F | 1950 | 265..266 'f': F |
1952 | 276..278 '{}': () | 1951 | 276..278 '{}': () |
1953 | 316..320 'self': S | 1952 | 316..320 'self': S |
1954 | 322..323 'f': F | 1953 | 322..323 'f': F |
1955 | 328..329 'x': T | 1954 | 328..329 'x': T |
1956 | 339..341 '{}': () | 1955 | 339..341 '{}': () |
1957 | 355..514 '{ ... S); }': () | 1956 | 355..514 '{ ... S); }': () |
1958 | 365..367 'x1': u64 | 1957 | 365..367 'x1': u64 |
1959 | 370..374 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64 | 1958 | 370..374 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64 |
1960 | 370..393 'foo1(S...hod())': u64 | 1959 | 370..393 'foo1(S...hod())': u64 |
1961 | 375..376 'S': S | 1960 | 375..376 'S': S |
1962 | 378..392 '|s| s.method()': |S| -> u64 | 1961 | 378..392 '|s| s.method()': |S| -> u64 |
1963 | 379..380 's': S | 1962 | 379..380 's': S |
1964 | 382..383 's': S | 1963 | 382..383 's': S |
1965 | 382..392 's.method()': u64 | 1964 | 382..392 's.method()': u64 |
1966 | 403..405 'x2': u64 | 1965 | 403..405 'x2': u64 |
1967 | 408..412 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64 | 1966 | 408..412 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64 |
1968 | 408..431 'foo2(|...(), S)': u64 | 1967 | 408..431 'foo2(|...(), S)': u64 |
1969 | 413..427 '|s| s.method()': |S| -> u64 | 1968 | 413..427 '|s| s.method()': |S| -> u64 |
1970 | 414..415 's': S | 1969 | 414..415 's': S |
1971 | 417..418 's': S | 1970 | 417..418 's': S |
1972 | 417..427 's.method()': u64 | 1971 | 417..427 's.method()': u64 |
1973 | 429..430 'S': S | 1972 | 429..430 'S': S |
1974 | 441..443 'x3': u64 | 1973 | 441..443 'x3': u64 |
1975 | 446..447 'S': S | 1974 | 446..447 'S': S |
1976 | 446..471 'S.foo1...hod())': u64 | 1975 | 446..471 'S.foo1...hod())': u64 |
1977 | 453..454 'S': S | 1976 | 453..454 'S': S |
1978 | 456..470 '|s| s.method()': |S| -> u64 | 1977 | 456..470 '|s| s.method()': |S| -> u64 |
1979 | 457..458 's': S | 1978 | 457..458 's': S |
1980 | 460..461 's': S | 1979 | 460..461 's': S |
1981 | 460..470 's.method()': u64 | 1980 | 460..470 's.method()': u64 |
1982 | 481..483 'x4': u64 | 1981 | 481..483 'x4': u64 |
1983 | 486..487 'S': S | 1982 | 486..487 'S': S |
1984 | 486..511 'S.foo2...(), S)': u64 | 1983 | 486..511 'S.foo2...(), S)': u64 |
1985 | 493..507 '|s| s.method()': |S| -> u64 | 1984 | 493..507 '|s| s.method()': |S| -> u64 |
1986 | 494..495 's': S | 1985 | 494..495 's': S |
1987 | 497..498 's': S | 1986 | 497..498 's': S |
1988 | 497..507 's.method()': u64 | 1987 | 497..507 's.method()': u64 |
1989 | 509..510 'S': S | 1988 | 509..510 'S': S |
1990 | "### | 1989 | "#]], |
1991 | ); | 1990 | ); |
1992 | } | 1991 | } |
1993 | 1992 | ||
@@ -2056,43 +2055,44 @@ fn test<T, U>() where T::Item: Trait2, T: Trait<U::Item>, U: Trait<()> { | |||
2056 | 2055 | ||
2057 | #[test] | 2056 | #[test] |
2058 | fn unselected_projection_on_impl_self() { | 2057 | fn unselected_projection_on_impl_self() { |
2059 | assert_snapshot!(infer( | 2058 | check_infer( |
2060 | r#" | 2059 | r#" |
2061 | //- /main.rs | 2060 | //- /main.rs |
2062 | trait Trait { | 2061 | trait Trait { |
2063 | type Item; | 2062 | type Item; |
2064 | 2063 | ||
2065 | fn f(&self, x: Self::Item); | 2064 | fn f(&self, x: Self::Item); |
2066 | } | 2065 | } |
2067 | 2066 | ||
2068 | struct S; | 2067 | struct S; |
2069 | 2068 | ||
2070 | impl Trait for S { | 2069 | impl Trait for S { |
2071 | type Item = u32; | 2070 | type Item = u32; |
2072 | fn f(&self, x: Self::Item) { let y = x; } | 2071 | fn f(&self, x: Self::Item) { let y = x; } |
2073 | } | 2072 | } |
2074 | 2073 | ||
2075 | struct S2; | 2074 | struct S2; |
2076 | 2075 | ||
2077 | impl Trait for S2 { | 2076 | impl Trait for S2 { |
2078 | type Item = i32; | 2077 | type Item = i32; |
2079 | fn f(&self, x: <Self>::Item) { let y = x; } | 2078 | fn f(&self, x: <Self>::Item) { let y = x; } |
2080 | } | 2079 | } |
2081 | "#, | 2080 | "#, |
2082 | ), @r###" | 2081 | expect![[r#" |
2083 | 40..44 'self': &Self | 2082 | 40..44 'self': &Self |
2084 | 46..47 'x': Trait::Item<Self> | 2083 | 46..47 'x': Trait::Item<Self> |
2085 | 126..130 'self': &S | 2084 | 126..130 'self': &S |
2086 | 132..133 'x': u32 | 2085 | 132..133 'x': u32 |
2087 | 147..161 '{ let y = x; }': () | 2086 | 147..161 '{ let y = x; }': () |
2088 | 153..154 'y': u32 | 2087 | 153..154 'y': u32 |
2089 | 157..158 'x': u32 | 2088 | 157..158 'x': u32 |
2090 | 228..232 'self': &S2 | 2089 | 228..232 'self': &S2 |
2091 | 234..235 'x': i32 | 2090 | 234..235 'x': i32 |
2092 | 251..265 '{ let y = x; }': () | 2091 | 251..265 '{ let y = x; }': () |
2093 | 257..258 'y': i32 | 2092 | 257..258 'y': i32 |
2094 | 261..262 'x': i32 | 2093 | 261..262 'x': i32 |
2095 | "###); | 2094 | "#]], |
2095 | ); | ||
2096 | } | 2096 | } |
2097 | 2097 | ||
2098 | #[test] | 2098 | #[test] |
@@ -2261,170 +2261,170 @@ fn test<I: Iterator<Item: Iterator<Item = u32>>>() { | |||
2261 | 2261 | ||
2262 | #[test] | 2262 | #[test] |
2263 | fn proc_macro_server_types() { | 2263 | fn proc_macro_server_types() { |
2264 | assert_snapshot!( | 2264 | check_infer( |
2265 | infer(r#" | 2265 | r#" |
2266 | macro_rules! with_api { | 2266 | macro_rules! with_api { |
2267 | ($S:ident, $self:ident, $m:ident) => { | 2267 | ($S:ident, $self:ident, $m:ident) => { |
2268 | $m! { | 2268 | $m! { |
2269 | TokenStream { | 2269 | TokenStream { |
2270 | fn new() -> $S::TokenStream; | 2270 | fn new() -> $S::TokenStream; |
2271 | }, | 2271 | }, |
2272 | Group { | 2272 | Group { |
2273 | }, | 2273 | }, |
2274 | } | 2274 | } |
2275 | }; | 2275 | }; |
2276 | } | 2276 | } |
2277 | macro_rules! associated_item { | 2277 | macro_rules! associated_item { |
2278 | (type TokenStream) => | 2278 | (type TokenStream) => |
2279 | (type TokenStream: 'static;); | 2279 | (type TokenStream: 'static;); |
2280 | (type Group) => | 2280 | (type Group) => |
2281 | (type Group: 'static;); | 2281 | (type Group: 'static;); |
2282 | ($($item:tt)*) => ($($item)*;) | 2282 | ($($item:tt)*) => ($($item)*;) |
2283 | } | 2283 | } |
2284 | macro_rules! declare_server_traits { | 2284 | macro_rules! declare_server_traits { |
2285 | ($($name:ident { | 2285 | ($($name:ident { |
2286 | $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)* | 2286 | $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)* |
2287 | }),* $(,)?) => { | 2287 | }),* $(,)?) => { |
2288 | pub trait Types { | 2288 | pub trait Types { |
2289 | $(associated_item!(type $name);)* | 2289 | $(associated_item!(type $name);)* |
2290 | } | 2290 | } |
2291 | |||
2292 | $(pub trait $name: Types { | ||
2293 | $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)* | ||
2294 | })* | ||
2295 | |||
2296 | pub trait Server: Types $(+ $name)* {} | ||
2297 | impl<S: Types $(+ $name)*> Server for S {} | ||
2298 | } | ||
2299 | } | ||
2300 | 2291 | ||
2301 | with_api!(Self, self_, declare_server_traits); | 2292 | $(pub trait $name: Types { |
2302 | struct G {} | 2293 | $(associated_item!(fn $method($($arg: $arg_ty),*) $(-> $ret_ty)?);)* |
2303 | struct T {} | 2294 | })* |
2304 | struct Rustc; | ||
2305 | impl Types for Rustc { | ||
2306 | type TokenStream = T; | ||
2307 | type Group = G; | ||
2308 | } | ||
2309 | 2295 | ||
2310 | fn make<T>() -> T { loop {} } | 2296 | pub trait Server: Types $(+ $name)* {} |
2311 | impl TokenStream for Rustc { | 2297 | impl<S: Types $(+ $name)*> Server for S {} |
2312 | fn new() -> Self::TokenStream { | 2298 | } |
2313 | let group: Self::Group = make(); | 2299 | } |
2314 | make() | 2300 | |
2315 | } | 2301 | with_api!(Self, self_, declare_server_traits); |
2316 | } | 2302 | struct G {} |
2317 | "#), | 2303 | struct T {} |
2318 | @r###" | 2304 | struct Rustc; |
2319 | 1061..1072 '{ loop {} }': T | 2305 | impl Types for Rustc { |
2320 | 1063..1070 'loop {}': ! | 2306 | type TokenStream = T; |
2321 | 1068..1070 '{}': () | 2307 | type Group = G; |
2322 | 1136..1199 '{ ... }': T | 2308 | } |
2323 | 1150..1155 'group': G | 2309 | |
2324 | 1171..1175 'make': fn make<G>() -> G | 2310 | fn make<T>() -> T { loop {} } |
2325 | 1171..1177 'make()': G | 2311 | impl TokenStream for Rustc { |
2326 | 1187..1191 'make': fn make<T>() -> T | 2312 | fn new() -> Self::TokenStream { |
2327 | 1187..1193 'make()': T | 2313 | let group: Self::Group = make(); |
2328 | "### | 2314 | make() |
2315 | } | ||
2316 | } | ||
2317 | "#, | ||
2318 | expect![[r#" | ||
2319 | 1061..1072 '{ loop {} }': T | ||
2320 | 1063..1070 'loop {}': ! | ||
2321 | 1068..1070 '{}': () | ||
2322 | 1136..1199 '{ ... }': T | ||
2323 | 1150..1155 'group': G | ||
2324 | 1171..1175 'make': fn make<G>() -> G | ||
2325 | 1171..1177 'make()': G | ||
2326 | 1187..1191 'make': fn make<T>() -> T | ||
2327 | 1187..1193 'make()': T | ||
2328 | "#]], | ||
2329 | ); | 2329 | ); |
2330 | } | 2330 | } |
2331 | 2331 | ||
2332 | #[test] | 2332 | #[test] |
2333 | fn unify_impl_trait() { | 2333 | fn unify_impl_trait() { |
2334 | assert_snapshot!( | 2334 | check_infer_with_mismatches( |
2335 | infer_with_mismatches(r#" | 2335 | r#" |
2336 | trait Trait<T> {} | 2336 | trait Trait<T> {} |
2337 | |||
2338 | fn foo(x: impl Trait<u32>) { loop {} } | ||
2339 | fn bar<T>(x: impl Trait<T>) -> T { loop {} } | ||
2340 | |||
2341 | struct S<T>(T); | ||
2342 | impl<T> Trait<T> for S<T> {} | ||
2343 | |||
2344 | fn default<T>() -> T { loop {} } | ||
2337 | 2345 | ||
2338 | fn foo(x: impl Trait<u32>) { loop {} } | 2346 | fn test() -> impl Trait<i32> { |
2339 | fn bar<T>(x: impl Trait<T>) -> T { loop {} } | 2347 | let s1 = S(default()); |
2340 | 2348 | foo(s1); | |
2341 | struct S<T>(T); | 2349 | let x: i32 = bar(S(default())); |
2342 | impl<T> Trait<T> for S<T> {} | 2350 | S(default()) |
2343 | 2351 | } | |
2344 | fn default<T>() -> T { loop {} } | 2352 | "#, |
2345 | 2353 | expect![[r#" | |
2346 | fn test() -> impl Trait<i32> { | 2354 | 26..27 'x': impl Trait<u32> |
2347 | let s1 = S(default()); | 2355 | 46..57 '{ loop {} }': () |
2348 | foo(s1); | 2356 | 48..55 'loop {}': ! |
2349 | let x: i32 = bar(S(default())); | 2357 | 53..55 '{}': () |
2350 | S(default()) | 2358 | 68..69 'x': impl Trait<T> |
2351 | } | 2359 | 91..102 '{ loop {} }': T |
2352 | "#, true), | 2360 | 93..100 'loop {}': ! |
2353 | @r###" | 2361 | 98..100 '{}': () |
2354 | 26..27 'x': impl Trait<u32> | 2362 | 171..182 '{ loop {} }': T |
2355 | 46..57 '{ loop {} }': () | 2363 | 173..180 'loop {}': ! |
2356 | 48..55 'loop {}': ! | 2364 | 178..180 '{}': () |
2357 | 53..55 '{}': () | 2365 | 213..309 '{ ...t()) }': S<{unknown}> |
2358 | 68..69 'x': impl Trait<T> | 2366 | 223..225 's1': S<u32> |
2359 | 91..102 '{ loop {} }': T | 2367 | 228..229 'S': S<u32>(u32) -> S<u32> |
2360 | 93..100 'loop {}': ! | 2368 | 228..240 'S(default())': S<u32> |
2361 | 98..100 '{}': () | 2369 | 230..237 'default': fn default<u32>() -> u32 |
2362 | 171..182 '{ loop {} }': T | 2370 | 230..239 'default()': u32 |
2363 | 173..180 'loop {}': ! | 2371 | 246..249 'foo': fn foo(S<u32>) |
2364 | 178..180 '{}': () | 2372 | 246..253 'foo(s1)': () |
2365 | 213..309 '{ ...t()) }': S<{unknown}> | 2373 | 250..252 's1': S<u32> |
2366 | 223..225 's1': S<u32> | 2374 | 263..264 'x': i32 |
2367 | 228..229 'S': S<u32>(u32) -> S<u32> | 2375 | 272..275 'bar': fn bar<i32>(S<i32>) -> i32 |
2368 | 228..240 'S(default())': S<u32> | 2376 | 272..289 'bar(S(...lt()))': i32 |
2369 | 230..237 'default': fn default<u32>() -> u32 | 2377 | 276..277 'S': S<i32>(i32) -> S<i32> |
2370 | 230..239 'default()': u32 | 2378 | 276..288 'S(default())': S<i32> |
2371 | 246..249 'foo': fn foo(S<u32>) | 2379 | 278..285 'default': fn default<i32>() -> i32 |
2372 | 246..253 'foo(s1)': () | 2380 | 278..287 'default()': i32 |
2373 | 250..252 's1': S<u32> | 2381 | 295..296 'S': S<{unknown}>({unknown}) -> S<{unknown}> |
2374 | 263..264 'x': i32 | 2382 | 295..307 'S(default())': S<{unknown}> |
2375 | 272..275 'bar': fn bar<i32>(S<i32>) -> i32 | 2383 | 297..304 'default': fn default<{unknown}>() -> {unknown} |
2376 | 272..289 'bar(S(...lt()))': i32 | 2384 | 297..306 'default()': {unknown} |
2377 | 276..277 'S': S<i32>(i32) -> S<i32> | 2385 | "#]], |
2378 | 276..288 'S(default())': S<i32> | ||
2379 | 278..285 'default': fn default<i32>() -> i32 | ||
2380 | 278..287 'default()': i32 | ||
2381 | 295..296 'S': S<{unknown}>({unknown}) -> S<{unknown}> | ||
2382 | 295..307 'S(default())': S<{unknown}> | ||
2383 | 297..304 'default': fn default<{unknown}>() -> {unknown} | ||
2384 | 297..306 'default()': {unknown} | ||
2385 | "### | ||
2386 | ); | 2386 | ); |
2387 | } | 2387 | } |
2388 | 2388 | ||
2389 | #[test] | 2389 | #[test] |
2390 | fn assoc_types_from_bounds() { | 2390 | fn assoc_types_from_bounds() { |
2391 | assert_snapshot!( | 2391 | check_infer( |
2392 | infer(r#" | 2392 | r#" |
2393 | //- /main.rs | 2393 | //- /main.rs |
2394 | #[lang = "fn_once"] | 2394 | #[lang = "fn_once"] |
2395 | trait FnOnce<Args> { | 2395 | trait FnOnce<Args> { |
2396 | type Output; | 2396 | type Output; |
2397 | } | 2397 | } |
2398 | 2398 | ||
2399 | trait T { | 2399 | trait T { |
2400 | type O; | 2400 | type O; |
2401 | } | 2401 | } |
2402 | 2402 | ||
2403 | impl T for () { | 2403 | impl T for () { |
2404 | type O = (); | 2404 | type O = (); |
2405 | } | 2405 | } |
2406 | 2406 | ||
2407 | fn f<X, F>(_v: F) | 2407 | fn f<X, F>(_v: F) |
2408 | where | 2408 | where |
2409 | X: T, | 2409 | X: T, |
2410 | F: FnOnce(&X::O), | 2410 | F: FnOnce(&X::O), |
2411 | { } | 2411 | { } |
2412 | 2412 | ||
2413 | fn main() { | 2413 | fn main() { |
2414 | f::<(), _>(|z| { z; }); | 2414 | f::<(), _>(|z| { z; }); |
2415 | } | 2415 | } |
2416 | "#), | 2416 | "#, |
2417 | @r###" | 2417 | expect![[r#" |
2418 | 133..135 '_v': F | 2418 | 133..135 '_v': F |
2419 | 178..181 '{ }': () | 2419 | 178..181 '{ }': () |
2420 | 193..224 '{ ... }); }': () | 2420 | 193..224 '{ ... }); }': () |
2421 | 199..209 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ()) | 2421 | 199..209 'f::<(), _>': fn f<(), |&()| -> ()>(|&()| -> ()) |
2422 | 199..221 'f::<()... z; })': () | 2422 | 199..221 'f::<()... z; })': () |
2423 | 210..220 '|z| { z; }': |&()| -> () | 2423 | 210..220 '|z| { z; }': |&()| -> () |
2424 | 211..212 'z': &() | 2424 | 211..212 'z': &() |
2425 | 214..220 '{ z; }': () | 2425 | 214..220 '{ z; }': () |
2426 | 216..217 'z': &() | 2426 | 216..217 'z': &() |
2427 | "### | 2427 | "#]], |
2428 | ); | 2428 | ); |
2429 | } | 2429 | } |
2430 | 2430 | ||
@@ -2497,120 +2497,120 @@ fn test() { | |||
2497 | 2497 | ||
2498 | #[test] | 2498 | #[test] |
2499 | fn iterator_chain() { | 2499 | fn iterator_chain() { |
2500 | assert_snapshot!( | 2500 | check_infer( |
2501 | infer(r#" | 2501 | r#" |
2502 | //- /main.rs | 2502 | //- /main.rs |
2503 | #[lang = "fn_once"] | 2503 | #[lang = "fn_once"] |
2504 | trait FnOnce<Args> { | 2504 | trait FnOnce<Args> { |
2505 | type Output; | 2505 | type Output; |
2506 | } | 2506 | } |
2507 | #[lang = "fn_mut"] | 2507 | #[lang = "fn_mut"] |
2508 | trait FnMut<Args>: FnOnce<Args> { } | 2508 | trait FnMut<Args>: FnOnce<Args> { } |
2509 | 2509 | ||
2510 | enum Option<T> { Some(T), None } | 2510 | enum Option<T> { Some(T), None } |
2511 | use Option::*; | 2511 | use Option::*; |
2512 | 2512 | ||
2513 | pub trait Iterator { | 2513 | pub trait Iterator { |
2514 | type Item; | 2514 | type Item; |
2515 | 2515 | ||
2516 | fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> | 2516 | fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> |
2517 | where | 2517 | where |
2518 | F: FnMut(Self::Item) -> Option<B>, | 2518 | F: FnMut(Self::Item) -> Option<B>, |
2519 | { loop {} } | 2519 | { loop {} } |
2520 | 2520 | ||
2521 | fn for_each<F>(self, f: F) | 2521 | fn for_each<F>(self, f: F) |
2522 | where | 2522 | where |
2523 | F: FnMut(Self::Item), | 2523 | F: FnMut(Self::Item), |
2524 | { loop {} } | 2524 | { loop {} } |
2525 | } | 2525 | } |
2526 | 2526 | ||
2527 | pub trait IntoIterator { | 2527 | pub trait IntoIterator { |
2528 | type Item; | 2528 | type Item; |
2529 | type IntoIter: Iterator<Item = Self::Item>; | 2529 | type IntoIter: Iterator<Item = Self::Item>; |
2530 | fn into_iter(self) -> Self::IntoIter; | 2530 | fn into_iter(self) -> Self::IntoIter; |
2531 | } | 2531 | } |
2532 | 2532 | ||
2533 | pub struct FilterMap<I, F> { } | 2533 | pub struct FilterMap<I, F> { } |
2534 | impl<B, I: Iterator, F> Iterator for FilterMap<I, F> | 2534 | impl<B, I: Iterator, F> Iterator for FilterMap<I, F> |
2535 | where | 2535 | where |
2536 | F: FnMut(I::Item) -> Option<B>, | 2536 | F: FnMut(I::Item) -> Option<B>, |
2537 | { | 2537 | { |
2538 | type Item = B; | 2538 | type Item = B; |
2539 | } | 2539 | } |
2540 | 2540 | ||
2541 | #[stable(feature = "rust1", since = "1.0.0")] | 2541 | #[stable(feature = "rust1", since = "1.0.0")] |
2542 | impl<I: Iterator> IntoIterator for I { | 2542 | impl<I: Iterator> IntoIterator for I { |
2543 | type Item = I::Item; | 2543 | type Item = I::Item; |
2544 | type IntoIter = I; | 2544 | type IntoIter = I; |
2545 | 2545 | ||
2546 | fn into_iter(self) -> I { | 2546 | fn into_iter(self) -> I { |
2547 | self | 2547 | self |
2548 | } | 2548 | } |
2549 | } | 2549 | } |
2550 | 2550 | ||
2551 | struct Vec<T> {} | 2551 | struct Vec<T> {} |
2552 | impl<T> Vec<T> { | 2552 | impl<T> Vec<T> { |
2553 | fn new() -> Self { loop {} } | 2553 | fn new() -> Self { loop {} } |
2554 | } | 2554 | } |
2555 | 2555 | ||
2556 | impl<T> IntoIterator for Vec<T> { | 2556 | impl<T> IntoIterator for Vec<T> { |
2557 | type Item = T; | 2557 | type Item = T; |
2558 | type IntoIter = IntoIter<T>; | 2558 | type IntoIter = IntoIter<T>; |
2559 | } | 2559 | } |
2560 | 2560 | ||
2561 | pub struct IntoIter<T> { } | 2561 | pub struct IntoIter<T> { } |
2562 | impl<T> Iterator for IntoIter<T> { | 2562 | impl<T> Iterator for IntoIter<T> { |
2563 | type Item = T; | 2563 | type Item = T; |
2564 | } | 2564 | } |
2565 | 2565 | ||
2566 | fn main() { | 2566 | fn main() { |
2567 | Vec::<i32>::new().into_iter() | 2567 | Vec::<i32>::new().into_iter() |
2568 | .filter_map(|x| if x > 0 { Some(x as u32) } else { None }) | 2568 | .filter_map(|x| if x > 0 { Some(x as u32) } else { None }) |
2569 | .for_each(|y| { y; }); | 2569 | .for_each(|y| { y; }); |
2570 | } | 2570 | } |
2571 | "#), | 2571 | "#, |
2572 | @r###" | 2572 | expect![[r#" |
2573 | 226..230 'self': Self | 2573 | 226..230 'self': Self |
2574 | 232..233 'f': F | 2574 | 232..233 'f': F |
2575 | 317..328 '{ loop {} }': FilterMap<Self, F> | 2575 | 317..328 '{ loop {} }': FilterMap<Self, F> |
2576 | 319..326 'loop {}': ! | 2576 | 319..326 'loop {}': ! |
2577 | 324..326 '{}': () | 2577 | 324..326 '{}': () |
2578 | 349..353 'self': Self | 2578 | 349..353 'self': Self |
2579 | 355..356 'f': F | 2579 | 355..356 'f': F |
2580 | 405..416 '{ loop {} }': () | 2580 | 405..416 '{ loop {} }': () |
2581 | 407..414 'loop {}': ! | 2581 | 407..414 'loop {}': ! |
2582 | 412..414 '{}': () | 2582 | 412..414 '{}': () |
2583 | 525..529 'self': Self | 2583 | 525..529 'self': Self |
2584 | 854..858 'self': I | 2584 | 854..858 'self': I |
2585 | 865..885 '{ ... }': I | 2585 | 865..885 '{ ... }': I |
2586 | 875..879 'self': I | 2586 | 875..879 'self': I |
2587 | 944..955 '{ loop {} }': Vec<T> | 2587 | 944..955 '{ loop {} }': Vec<T> |
2588 | 946..953 'loop {}': ! | 2588 | 946..953 'loop {}': ! |
2589 | 951..953 '{}': () | 2589 | 951..953 '{}': () |
2590 | 1142..1273 '{ ... }); }': () | 2590 | 1142..1269 '{ ... }); }': () |
2591 | 1148..1163 'Vec::<i32>::new': fn new<i32>() -> Vec<i32> | 2591 | 1148..1163 'Vec::<i32>::new': fn new<i32>() -> Vec<i32> |
2592 | 1148..1165 'Vec::<...:new()': Vec<i32> | 2592 | 1148..1165 'Vec::<...:new()': Vec<i32> |
2593 | 1148..1177 'Vec::<...iter()': IntoIter<i32> | 2593 | 1148..1177 'Vec::<...iter()': IntoIter<i32> |
2594 | 1148..1242 'Vec::<...one })': FilterMap<IntoIter<i32>, |i32| -> Option<u32>> | 2594 | 1148..1240 'Vec::<...one })': FilterMap<IntoIter<i32>, |i32| -> Option<u32>> |
2595 | 1148..1270 'Vec::<... y; })': () | 2595 | 1148..1266 'Vec::<... y; })': () |
2596 | 1196..1241 '|x| if...None }': |i32| -> Option<u32> | 2596 | 1194..1239 '|x| if...None }': |i32| -> Option<u32> |
2597 | 1197..1198 'x': i32 | 2597 | 1195..1196 'x': i32 |
2598 | 1200..1241 'if x >...None }': Option<u32> | 2598 | 1198..1239 'if x >...None }': Option<u32> |
2599 | 1203..1204 'x': i32 | 2599 | 1201..1202 'x': i32 |
2600 | 1203..1208 'x > 0': bool | 2600 | 1201..1206 'x > 0': bool |
2601 | 1207..1208 '0': i32 | 2601 | 1205..1206 '0': i32 |
2602 | 1209..1227 '{ Some...u32) }': Option<u32> | 2602 | 1207..1225 '{ Some...u32) }': Option<u32> |
2603 | 1211..1215 'Some': Some<u32>(u32) -> Option<u32> | 2603 | 1209..1213 'Some': Some<u32>(u32) -> Option<u32> |
2604 | 1211..1225 'Some(x as u32)': Option<u32> | 2604 | 1209..1223 'Some(x as u32)': Option<u32> |
2605 | 1216..1217 'x': i32 | 2605 | 1214..1215 'x': i32 |
2606 | 1216..1224 'x as u32': u32 | 2606 | 1214..1222 'x as u32': u32 |
2607 | 1233..1241 '{ None }': Option<u32> | 2607 | 1231..1239 '{ None }': Option<u32> |
2608 | 1235..1239 'None': Option<u32> | 2608 | 1233..1237 'None': Option<u32> |
2609 | 1259..1269 '|y| { y; }': |u32| -> () | 2609 | 1255..1265 '|y| { y; }': |u32| -> () |
2610 | 1260..1261 'y': u32 | 2610 | 1256..1257 'y': u32 |
2611 | 1263..1269 '{ y; }': () | 2611 | 1259..1265 '{ y; }': () |
2612 | 1265..1266 'y': u32 | 2612 | 1261..1262 'y': u32 |
2613 | "### | 2613 | "#]], |
2614 | ); | 2614 | ); |
2615 | } | 2615 | } |
2616 | 2616 | ||
@@ -2648,176 +2648,176 @@ fn main() { | |||
2648 | 2648 | ||
2649 | #[test] | 2649 | #[test] |
2650 | fn trait_object_no_coercion() { | 2650 | fn trait_object_no_coercion() { |
2651 | assert_snapshot!( | 2651 | check_infer_with_mismatches( |
2652 | infer_with_mismatches(r#" | 2652 | r#" |
2653 | trait Foo {} | 2653 | trait Foo {} |
2654 | 2654 | ||
2655 | fn foo(x: &dyn Foo) {} | 2655 | fn foo(x: &dyn Foo) {} |
2656 | 2656 | ||
2657 | fn test(x: &dyn Foo) { | 2657 | fn test(x: &dyn Foo) { |
2658 | foo(x); | 2658 | foo(x); |
2659 | } | 2659 | } |
2660 | "#, true), | 2660 | "#, |
2661 | @r###" | 2661 | expect![[r#" |
2662 | 21..22 'x': &dyn Foo | 2662 | 21..22 'x': &dyn Foo |
2663 | 34..36 '{}': () | 2663 | 34..36 '{}': () |
2664 | 46..47 'x': &dyn Foo | 2664 | 46..47 'x': &dyn Foo |
2665 | 59..74 '{ foo(x); }': () | 2665 | 59..74 '{ foo(x); }': () |
2666 | 65..68 'foo': fn foo(&dyn Foo) | 2666 | 65..68 'foo': fn foo(&dyn Foo) |
2667 | 65..71 'foo(x)': () | 2667 | 65..71 'foo(x)': () |
2668 | 69..70 'x': &dyn Foo | 2668 | 69..70 'x': &dyn Foo |
2669 | "### | 2669 | "#]], |
2670 | ); | 2670 | ); |
2671 | } | 2671 | } |
2672 | 2672 | ||
2673 | #[test] | 2673 | #[test] |
2674 | fn builtin_copy() { | 2674 | fn builtin_copy() { |
2675 | assert_snapshot!( | 2675 | check_infer_with_mismatches( |
2676 | infer_with_mismatches(r#" | 2676 | r#" |
2677 | #[lang = "copy"] | 2677 | #[lang = "copy"] |
2678 | trait Copy {} | 2678 | trait Copy {} |
2679 | 2679 | ||
2680 | struct IsCopy; | 2680 | struct IsCopy; |
2681 | impl Copy for IsCopy {} | 2681 | impl Copy for IsCopy {} |
2682 | struct NotCopy; | 2682 | struct NotCopy; |
2683 | 2683 | ||
2684 | trait Test { fn test(&self) -> bool; } | 2684 | trait Test { fn test(&self) -> bool; } |
2685 | impl<T: Copy> Test for T {} | 2685 | impl<T: Copy> Test for T {} |
2686 | 2686 | ||
2687 | fn test() { | 2687 | fn test() { |
2688 | IsCopy.test(); | 2688 | IsCopy.test(); |
2689 | NotCopy.test(); | 2689 | NotCopy.test(); |
2690 | (IsCopy, IsCopy).test(); | 2690 | (IsCopy, IsCopy).test(); |
2691 | (IsCopy, NotCopy).test(); | 2691 | (IsCopy, NotCopy).test(); |
2692 | } | 2692 | } |
2693 | "#, true), | 2693 | "#, |
2694 | @r###" | 2694 | expect![[r#" |
2695 | 110..114 'self': &Self | 2695 | 110..114 'self': &Self |
2696 | 166..267 '{ ...t(); }': () | 2696 | 166..267 '{ ...t(); }': () |
2697 | 172..178 'IsCopy': IsCopy | 2697 | 172..178 'IsCopy': IsCopy |
2698 | 172..185 'IsCopy.test()': bool | 2698 | 172..185 'IsCopy.test()': bool |
2699 | 191..198 'NotCopy': NotCopy | 2699 | 191..198 'NotCopy': NotCopy |
2700 | 191..205 'NotCopy.test()': {unknown} | 2700 | 191..205 'NotCopy.test()': {unknown} |
2701 | 211..227 '(IsCop...sCopy)': (IsCopy, IsCopy) | 2701 | 211..227 '(IsCop...sCopy)': (IsCopy, IsCopy) |
2702 | 211..234 '(IsCop...test()': bool | 2702 | 211..234 '(IsCop...test()': bool |
2703 | 212..218 'IsCopy': IsCopy | 2703 | 212..218 'IsCopy': IsCopy |
2704 | 220..226 'IsCopy': IsCopy | 2704 | 220..226 'IsCopy': IsCopy |
2705 | 240..257 '(IsCop...tCopy)': (IsCopy, NotCopy) | 2705 | 240..257 '(IsCop...tCopy)': (IsCopy, NotCopy) |
2706 | 240..264 '(IsCop...test()': {unknown} | 2706 | 240..264 '(IsCop...test()': {unknown} |
2707 | 241..247 'IsCopy': IsCopy | 2707 | 241..247 'IsCopy': IsCopy |
2708 | 249..256 'NotCopy': NotCopy | 2708 | 249..256 'NotCopy': NotCopy |
2709 | "### | 2709 | "#]], |
2710 | ); | 2710 | ); |
2711 | } | 2711 | } |
2712 | 2712 | ||
2713 | #[test] | 2713 | #[test] |
2714 | fn builtin_fn_def_copy() { | 2714 | fn builtin_fn_def_copy() { |
2715 | assert_snapshot!( | 2715 | check_infer_with_mismatches( |
2716 | infer_with_mismatches(r#" | 2716 | r#" |
2717 | #[lang = "copy"] | 2717 | #[lang = "copy"] |
2718 | trait Copy {} | 2718 | trait Copy {} |
2719 | 2719 | ||
2720 | fn foo() {} | 2720 | fn foo() {} |
2721 | fn bar<T: Copy>(T) -> T {} | 2721 | fn bar<T: Copy>(T) -> T {} |
2722 | struct Struct(usize); | 2722 | struct Struct(usize); |
2723 | enum Enum { Variant(usize) } | 2723 | enum Enum { Variant(usize) } |
2724 | 2724 | ||
2725 | trait Test { fn test(&self) -> bool; } | 2725 | trait Test { fn test(&self) -> bool; } |
2726 | impl<T: Copy> Test for T {} | 2726 | impl<T: Copy> Test for T {} |
2727 | 2727 | ||
2728 | fn test() { | 2728 | fn test() { |
2729 | foo.test(); | 2729 | foo.test(); |
2730 | bar.test(); | 2730 | bar.test(); |
2731 | Struct.test(); | 2731 | Struct.test(); |
2732 | Enum::Variant.test(); | 2732 | Enum::Variant.test(); |
2733 | } | 2733 | } |
2734 | "#, true), | 2734 | "#, |
2735 | @r###" | 2735 | expect![[r#" |
2736 | 41..43 '{}': () | 2736 | 41..43 '{}': () |
2737 | 60..61 'T': {unknown} | 2737 | 60..61 'T': {unknown} |
2738 | 68..70 '{}': () | 2738 | 68..70 '{}': () |
2739 | 68..70: expected T, got () | 2739 | 68..70: expected T, got () |
2740 | 145..149 'self': &Self | 2740 | 145..149 'self': &Self |
2741 | 201..281 '{ ...t(); }': () | 2741 | 201..281 '{ ...t(); }': () |
2742 | 207..210 'foo': fn foo() | 2742 | 207..210 'foo': fn foo() |
2743 | 207..217 'foo.test()': bool | 2743 | 207..217 'foo.test()': bool |
2744 | 223..226 'bar': fn bar<{unknown}>({unknown}) -> {unknown} | 2744 | 223..226 'bar': fn bar<{unknown}>({unknown}) -> {unknown} |
2745 | 223..233 'bar.test()': bool | 2745 | 223..233 'bar.test()': bool |
2746 | 239..245 'Struct': Struct(usize) -> Struct | 2746 | 239..245 'Struct': Struct(usize) -> Struct |
2747 | 239..252 'Struct.test()': bool | 2747 | 239..252 'Struct.test()': bool |
2748 | 258..271 'Enum::Variant': Variant(usize) -> Enum | 2748 | 258..271 'Enum::Variant': Variant(usize) -> Enum |
2749 | 258..278 'Enum::...test()': bool | 2749 | 258..278 'Enum::...test()': bool |
2750 | "### | 2750 | "#]], |
2751 | ); | 2751 | ); |
2752 | } | 2752 | } |
2753 | 2753 | ||
2754 | #[test] | 2754 | #[test] |
2755 | fn builtin_fn_ptr_copy() { | 2755 | fn builtin_fn_ptr_copy() { |
2756 | assert_snapshot!( | 2756 | check_infer_with_mismatches( |
2757 | infer_with_mismatches(r#" | 2757 | r#" |
2758 | #[lang = "copy"] | 2758 | #[lang = "copy"] |
2759 | trait Copy {} | 2759 | trait Copy {} |
2760 | 2760 | ||
2761 | trait Test { fn test(&self) -> bool; } | 2761 | trait Test { fn test(&self) -> bool; } |
2762 | impl<T: Copy> Test for T {} | 2762 | impl<T: Copy> Test for T {} |
2763 | 2763 | ||
2764 | fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) { | 2764 | fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) { |
2765 | f1.test(); | 2765 | f1.test(); |
2766 | f2.test(); | 2766 | f2.test(); |
2767 | f3.test(); | 2767 | f3.test(); |
2768 | } | 2768 | } |
2769 | "#, true), | 2769 | "#, |
2770 | @r###" | 2770 | expect![[r#" |
2771 | 54..58 'self': &Self | 2771 | 54..58 'self': &Self |
2772 | 108..110 'f1': fn() | 2772 | 108..110 'f1': fn() |
2773 | 118..120 'f2': fn(usize) -> u8 | 2773 | 118..120 'f2': fn(usize) -> u8 |
2774 | 139..141 'f3': fn(u8, u8) -> &u8 | 2774 | 139..141 'f3': fn(u8, u8) -> &u8 |
2775 | 162..210 '{ ...t(); }': () | 2775 | 162..210 '{ ...t(); }': () |
2776 | 168..170 'f1': fn() | 2776 | 168..170 'f1': fn() |
2777 | 168..177 'f1.test()': bool | 2777 | 168..177 'f1.test()': bool |
2778 | 183..185 'f2': fn(usize) -> u8 | 2778 | 183..185 'f2': fn(usize) -> u8 |
2779 | 183..192 'f2.test()': bool | 2779 | 183..192 'f2.test()': bool |
2780 | 198..200 'f3': fn(u8, u8) -> &u8 | 2780 | 198..200 'f3': fn(u8, u8) -> &u8 |
2781 | 198..207 'f3.test()': bool | 2781 | 198..207 'f3.test()': bool |
2782 | "### | 2782 | "#]], |
2783 | ); | 2783 | ); |
2784 | } | 2784 | } |
2785 | 2785 | ||
2786 | #[test] | 2786 | #[test] |
2787 | fn builtin_sized() { | 2787 | fn builtin_sized() { |
2788 | assert_snapshot!( | 2788 | check_infer_with_mismatches( |
2789 | infer_with_mismatches(r#" | 2789 | r#" |
2790 | #[lang = "sized"] | 2790 | #[lang = "sized"] |
2791 | trait Sized {} | 2791 | trait Sized {} |
2792 | 2792 | ||
2793 | trait Test { fn test(&self) -> bool; } | 2793 | trait Test { fn test(&self) -> bool; } |
2794 | impl<T: Sized> Test for T {} | 2794 | impl<T: Sized> Test for T {} |
2795 | 2795 | ||
2796 | fn test() { | 2796 | fn test() { |
2797 | 1u8.test(); | 2797 | 1u8.test(); |
2798 | (*"foo").test(); // not Sized | 2798 | (*"foo").test(); // not Sized |
2799 | (1u8, 1u8).test(); | 2799 | (1u8, 1u8).test(); |
2800 | (1u8, *"foo").test(); // not Sized | 2800 | (1u8, *"foo").test(); // not Sized |
2801 | } | 2801 | } |
2802 | "#, true), | 2802 | "#, |
2803 | @r###" | 2803 | expect![[r#" |
2804 | 56..60 'self': &Self | 2804 | 56..60 'self': &Self |
2805 | 113..228 '{ ...ized }': () | 2805 | 113..228 '{ ...ized }': () |
2806 | 119..122 '1u8': u8 | 2806 | 119..122 '1u8': u8 |
2807 | 119..129 '1u8.test()': bool | 2807 | 119..129 '1u8.test()': bool |
2808 | 135..150 '(*"foo").test()': {unknown} | 2808 | 135..150 '(*"foo").test()': {unknown} |
2809 | 136..142 '*"foo"': str | 2809 | 136..142 '*"foo"': str |
2810 | 137..142 '"foo"': &str | 2810 | 137..142 '"foo"': &str |
2811 | 169..179 '(1u8, 1u8)': (u8, u8) | 2811 | 169..179 '(1u8, 1u8)': (u8, u8) |
2812 | 169..186 '(1u8, ...test()': bool | 2812 | 169..186 '(1u8, ...test()': bool |
2813 | 170..173 '1u8': u8 | 2813 | 170..173 '1u8': u8 |
2814 | 175..178 '1u8': u8 | 2814 | 175..178 '1u8': u8 |
2815 | 192..205 '(1u8, *"foo")': (u8, str) | 2815 | 192..205 '(1u8, *"foo")': (u8, str) |
2816 | 192..212 '(1u8, ...test()': {unknown} | 2816 | 192..212 '(1u8, ...test()': {unknown} |
2817 | 193..196 '1u8': u8 | 2817 | 193..196 '1u8': u8 |
2818 | 198..204 '*"foo"': str | 2818 | 198..204 '*"foo"': str |
2819 | 199..204 '"foo"': &str | 2819 | 199..204 '"foo"': &str |
2820 | "### | 2820 | "#]], |
2821 | ); | 2821 | ); |
2822 | } | 2822 | } |
2823 | 2823 | ||
@@ -2867,156 +2867,150 @@ impl<A: Step> iter::Iterator for ops::Range<A> { | |||
2867 | 2867 | ||
2868 | #[test] | 2868 | #[test] |
2869 | fn infer_closure_arg() { | 2869 | fn infer_closure_arg() { |
2870 | assert_snapshot!( | 2870 | check_infer( |
2871 | infer( | 2871 | r#" |
2872 | r#" | 2872 | //- /lib.rs |
2873 | //- /lib.rs | ||
2874 | |||
2875 | enum Option<T> { | ||
2876 | None, | ||
2877 | Some(T) | ||
2878 | } | ||
2879 | 2873 | ||
2880 | fn foo() { | 2874 | enum Option<T> { |
2881 | let s = Option::None; | 2875 | None, |
2882 | let f = |x: Option<i32>| {}; | 2876 | Some(T) |
2883 | (&f)(s) | 2877 | } |
2884 | } | 2878 | |
2885 | "# | 2879 | fn foo() { |
2886 | ), | 2880 | let s = Option::None; |
2887 | @r###" | 2881 | let f = |x: Option<i32>| {}; |
2888 | 52..126 '{ ...)(s) }': () | 2882 | (&f)(s) |
2889 | 62..63 's': Option<i32> | 2883 | } |
2890 | 66..78 'Option::None': Option<i32> | 2884 | "#, |
2891 | 88..89 'f': |Option<i32>| -> () | 2885 | expect![[r#" |
2892 | 92..111 '|x: Op...2>| {}': |Option<i32>| -> () | 2886 | 52..126 '{ ...)(s) }': () |
2893 | 93..94 'x': Option<i32> | 2887 | 62..63 's': Option<i32> |
2894 | 109..111 '{}': () | 2888 | 66..78 'Option::None': Option<i32> |
2895 | 117..124 '(&f)(s)': () | 2889 | 88..89 'f': |Option<i32>| -> () |
2896 | 118..120 '&f': &|Option<i32>| -> () | 2890 | 92..111 '|x: Op...2>| {}': |Option<i32>| -> () |
2897 | 119..120 'f': |Option<i32>| -> () | 2891 | 93..94 'x': Option<i32> |
2898 | 122..123 's': Option<i32> | 2892 | 109..111 '{}': () |
2899 | "### | 2893 | 117..124 '(&f)(s)': () |
2894 | 118..120 '&f': &|Option<i32>| -> () | ||
2895 | 119..120 'f': |Option<i32>| -> () | ||
2896 | 122..123 's': Option<i32> | ||
2897 | "#]], | ||
2900 | ); | 2898 | ); |
2901 | } | 2899 | } |
2902 | 2900 | ||
2903 | #[test] | 2901 | #[test] |
2904 | fn infer_fn_trait_arg() { | 2902 | fn infer_fn_trait_arg() { |
2905 | assert_snapshot!( | 2903 | check_infer( |
2906 | infer( | 2904 | r#" |
2907 | r#" | 2905 | //- /lib.rs deps:std |
2908 | //- /lib.rs deps:std | ||
2909 | 2906 | ||
2910 | #[lang = "fn_once"] | 2907 | #[lang = "fn_once"] |
2911 | pub trait FnOnce<Args> { | 2908 | pub trait FnOnce<Args> { |
2912 | type Output; | 2909 | type Output; |
2913 | 2910 | ||
2914 | extern "rust-call" fn call_once(&self, args: Args) -> Self::Output; | 2911 | extern "rust-call" fn call_once(&self, args: Args) -> Self::Output; |
2915 | } | 2912 | } |
2916 | 2913 | ||
2917 | #[lang = "fn"] | 2914 | #[lang = "fn"] |
2918 | pub trait Fn<Args>:FnOnce<Args> { | 2915 | pub trait Fn<Args>:FnOnce<Args> { |
2919 | extern "rust-call" fn call(&self, args: Args) -> Self::Output; | 2916 | extern "rust-call" fn call(&self, args: Args) -> Self::Output; |
2920 | } | 2917 | } |
2921 | 2918 | ||
2922 | enum Option<T> { | 2919 | enum Option<T> { |
2923 | None, | 2920 | None, |
2924 | Some(T) | 2921 | Some(T) |
2925 | } | 2922 | } |
2926 | 2923 | ||
2927 | fn foo<F, T>(f: F) -> T | 2924 | fn foo<F, T>(f: F) -> T |
2928 | where | 2925 | where |
2929 | F: Fn(Option<i32>) -> T, | 2926 | F: Fn(Option<i32>) -> T, |
2930 | { | 2927 | { |
2931 | let s = None; | 2928 | let s = None; |
2932 | f(s) | 2929 | f(s) |
2933 | } | 2930 | } |
2934 | "# | 2931 | "#, |
2935 | ), | 2932 | expect![[r#" |
2936 | @r###" | 2933 | 101..105 'self': &Self |
2937 | 101..105 'self': &Self | 2934 | 107..111 'args': Args |
2938 | 107..111 'args': Args | 2935 | 220..224 'self': &Self |
2939 | 220..224 'self': &Self | 2936 | 226..230 'args': Args |
2940 | 226..230 'args': Args | 2937 | 313..314 'f': F |
2941 | 313..314 'f': F | 2938 | 359..389 '{ ...f(s) }': T |
2942 | 359..389 '{ ...f(s) }': T | 2939 | 369..370 's': Option<i32> |
2943 | 369..370 's': Option<i32> | 2940 | 373..377 'None': Option<i32> |
2944 | 373..377 'None': Option<i32> | 2941 | 383..384 'f': F |
2945 | 383..384 'f': F | 2942 | 383..387 'f(s)': T |
2946 | 383..387 'f(s)': T | 2943 | 385..386 's': Option<i32> |
2947 | 385..386 's': Option<i32> | 2944 | "#]], |
2948 | "### | ||
2949 | ); | 2945 | ); |
2950 | } | 2946 | } |
2951 | 2947 | ||
2952 | #[test] | 2948 | #[test] |
2953 | fn infer_box_fn_arg() { | 2949 | fn infer_box_fn_arg() { |
2954 | assert_snapshot!( | 2950 | check_infer( |
2955 | infer( | 2951 | r#" |
2956 | r#" | 2952 | //- /lib.rs deps:std |
2957 | //- /lib.rs deps:std | ||
2958 | 2953 | ||
2959 | #[lang = "fn_once"] | 2954 | #[lang = "fn_once"] |
2960 | pub trait FnOnce<Args> { | 2955 | pub trait FnOnce<Args> { |
2961 | type Output; | 2956 | type Output; |
2962 | 2957 | ||
2963 | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; | 2958 | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; |
2964 | } | 2959 | } |
2965 | 2960 | ||
2966 | #[lang = "deref"] | 2961 | #[lang = "deref"] |
2967 | pub trait Deref { | 2962 | pub trait Deref { |
2968 | type Target: ?Sized; | 2963 | type Target: ?Sized; |
2969 | 2964 | ||
2970 | fn deref(&self) -> &Self::Target; | 2965 | fn deref(&self) -> &Self::Target; |
2971 | } | 2966 | } |
2972 | 2967 | ||
2973 | #[lang = "owned_box"] | 2968 | #[lang = "owned_box"] |
2974 | pub struct Box<T: ?Sized> { | 2969 | pub struct Box<T: ?Sized> { |
2975 | inner: *mut T, | 2970 | inner: *mut T, |
2976 | } | 2971 | } |
2977 | 2972 | ||
2978 | impl<T: ?Sized> Deref for Box<T> { | 2973 | impl<T: ?Sized> Deref for Box<T> { |
2979 | type Target = T; | 2974 | type Target = T; |
2980 | 2975 | ||
2981 | fn deref(&self) -> &T { | 2976 | fn deref(&self) -> &T { |
2982 | &self.inner | 2977 | &self.inner |
2983 | } | ||
2984 | } | 2978 | } |
2979 | } | ||
2985 | 2980 | ||
2986 | enum Option<T> { | 2981 | enum Option<T> { |
2987 | None, | 2982 | None, |
2988 | Some(T) | 2983 | Some(T) |
2989 | } | 2984 | } |
2990 | 2985 | ||
2991 | fn foo() { | 2986 | fn foo() { |
2992 | let s = Option::None; | 2987 | let s = Option::None; |
2993 | let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {}); | 2988 | let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {}); |
2994 | f(&s) | 2989 | f(&s) |
2995 | } | 2990 | } |
2996 | "# | 2991 | "#, |
2997 | ), | 2992 | expect![[r#" |
2998 | @r###" | 2993 | 100..104 'self': Self |
2999 | 100..104 'self': Self | 2994 | 106..110 'args': Args |
3000 | 106..110 'args': Args | 2995 | 214..218 'self': &Self |
3001 | 214..218 'self': &Self | 2996 | 384..388 'self': &Box<T> |
3002 | 384..388 'self': &Box<T> | 2997 | 396..423 '{ ... }': &T |
3003 | 396..423 '{ ... }': &T | 2998 | 406..417 '&self.inner': &*mut T |
3004 | 406..417 '&self.inner': &*mut T | 2999 | 407..411 'self': &Box<T> |
3005 | 407..411 'self': &Box<T> | 3000 | 407..417 'self.inner': *mut T |
3006 | 407..417 'self.inner': *mut T | 3001 | 478..575 '{ ...(&s) }': FnOnce::Output<dyn FnOnce<(&Option<i32>,)>, (&Option<i32>,)> |
3007 | 478..575 '{ ...(&s) }': FnOnce::Output<dyn FnOnce<(&Option<i32>,)>, (&Option<i32>,)> | 3002 | 488..489 's': Option<i32> |
3008 | 488..489 's': Option<i32> | 3003 | 492..504 'Option::None': Option<i32> |
3009 | 492..504 'Option::None': Option<i32> | 3004 | 514..515 'f': Box<dyn FnOnce<(&Option<i32>,)>> |
3010 | 514..515 'f': Box<dyn FnOnce<(&Option<i32>,)>> | 3005 | 549..562 'box (|ps| {})': Box<|{unknown}| -> ()> |
3011 | 549..562 'box (|ps| {})': Box<|{unknown}| -> ()> | 3006 | 554..561 '|ps| {}': |{unknown}| -> () |
3012 | 554..561 '|ps| {}': |{unknown}| -> () | 3007 | 555..557 'ps': {unknown} |
3013 | 555..557 'ps': {unknown} | 3008 | 559..561 '{}': () |
3014 | 559..561 '{}': () | 3009 | 568..569 'f': Box<dyn FnOnce<(&Option<i32>,)>> |
3015 | 568..569 'f': Box<dyn FnOnce<(&Option<i32>,)>> | 3010 | 568..573 'f(&s)': FnOnce::Output<dyn FnOnce<(&Option<i32>,)>, (&Option<i32>,)> |
3016 | 568..573 'f(&s)': FnOnce::Output<dyn FnOnce<(&Option<i32>,)>, (&Option<i32>,)> | 3011 | 570..572 '&s': &Option<i32> |
3017 | 570..572 '&s': &Option<i32> | 3012 | 571..572 's': Option<i32> |
3018 | 571..572 's': Option<i32> | 3013 | "#]], |
3019 | "### | ||
3020 | ); | 3014 | ); |
3021 | } | 3015 | } |
3022 | 3016 | ||