diff options
Diffstat (limited to 'crates/ra_hir_ty/src/tests/coercion.rs')
-rw-r--r-- | crates/ra_hir_ty/src/tests/coercion.rs | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs index 42330b269..60ad6e9be 100644 --- a/crates/ra_hir_ty/src/tests/coercion.rs +++ b/crates/ra_hir_ty/src/tests/coercion.rs | |||
@@ -548,3 +548,141 @@ impl<TT> S<TT> { | |||
548 | "### | 548 | "### |
549 | ); | 549 | ); |
550 | } | 550 | } |
551 | |||
552 | #[test] | ||
553 | fn coerce_unsize_array() { | ||
554 | assert_snapshot!( | ||
555 | infer_with_mismatches(r#" | ||
556 | #[lang = "unsize"] | ||
557 | pub trait Unsize<T> {} | ||
558 | #[lang = "coerce_unsized"] | ||
559 | pub trait CoerceUnsized<T> {} | ||
560 | |||
561 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | ||
562 | |||
563 | fn test() { | ||
564 | let f: &[usize] = &[1, 2, 3]; | ||
565 | } | ||
566 | "#, true), | ||
567 | @r###" | ||
568 | [162; 199) '{ ... 3]; }': () | ||
569 | [172; 173) 'f': &[usize] | ||
570 | [186; 196) '&[1, 2, 3]': &[usize; _] | ||
571 | [187; 196) '[1, 2, 3]': [usize; _] | ||
572 | [188; 189) '1': usize | ||
573 | [191; 192) '2': usize | ||
574 | [194; 195) '3': usize | ||
575 | "### | ||
576 | ); | ||
577 | } | ||
578 | |||
579 | #[test] | ||
580 | fn coerce_unsize_trait_object() { | ||
581 | assert_snapshot!( | ||
582 | infer_with_mismatches(r#" | ||
583 | #[lang = "unsize"] | ||
584 | pub trait Unsize<T> {} | ||
585 | #[lang = "coerce_unsized"] | ||
586 | pub trait CoerceUnsized<T> {} | ||
587 | |||
588 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | ||
589 | |||
590 | trait Foo<T, U> {} | ||
591 | trait Bar<U, T, X>: Foo<T, U> {} | ||
592 | trait Baz<T, X>: Bar<usize, T, X> {} | ||
593 | |||
594 | struct S<T, X>; | ||
595 | impl<T, X> Foo<T, usize> for S<T, X> {} | ||
596 | impl<T, X> Bar<usize, T, X> for S<T, X> {} | ||
597 | impl<T, X> Baz<T, X> for S<T, X> {} | ||
598 | |||
599 | fn test() { | ||
600 | let obj: &dyn Baz<i8, i16> = &S; | ||
601 | let obj: &dyn Bar<_, _, _> = obj; | ||
602 | let obj: &dyn Foo<_, _> = obj; | ||
603 | let obj2: &dyn Baz<i8, i16> = &S; | ||
604 | let _: &dyn Foo<_, _> = obj2; | ||
605 | } | ||
606 | "#, true), | ||
607 | @r###" | ||
608 | [388; 573) '{ ...bj2; }': () | ||
609 | [398; 401) 'obj': &dyn Baz<i8, i16> | ||
610 | [423; 425) '&S': &S<i8, i16> | ||
611 | [424; 425) 'S': S<i8, i16> | ||
612 | [435; 438) 'obj': &dyn Bar<usize, i8, i16> | ||
613 | [460; 463) 'obj': &dyn Baz<i8, i16> | ||
614 | [473; 476) 'obj': &dyn Foo<i8, usize> | ||
615 | [495; 498) 'obj': &dyn Bar<usize, i8, i16> | ||
616 | [508; 512) 'obj2': &dyn Baz<i8, i16> | ||
617 | [534; 536) '&S': &S<i8, i16> | ||
618 | [535; 536) 'S': S<i8, i16> | ||
619 | [546; 547) '_': &dyn Foo<i8, usize> | ||
620 | [566; 570) 'obj2': &dyn Baz<i8, i16> | ||
621 | "### | ||
622 | ); | ||
623 | } | ||
624 | |||
625 | #[test] | ||
626 | fn coerce_unsize_super_trait_cycle() { | ||
627 | assert_snapshot!( | ||
628 | infer_with_mismatches(r#" | ||
629 | #[lang = "unsize"] | ||
630 | pub trait Unsize<T> {} | ||
631 | #[lang = "coerce_unsized"] | ||
632 | pub trait CoerceUnsized<T> {} | ||
633 | |||
634 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | ||
635 | |||
636 | trait A {} | ||
637 | trait B: C + A {} | ||
638 | trait C: B {} | ||
639 | trait D: C | ||
640 | |||
641 | struct S; | ||
642 | impl A for S {} | ||
643 | impl B for S {} | ||
644 | impl C for S {} | ||
645 | impl D for S {} | ||
646 | |||
647 | fn test() { | ||
648 | let obj: &dyn D = &S; | ||
649 | let obj: &dyn A = obj; | ||
650 | } | ||
651 | "#, true), | ||
652 | @r###" | ||
653 | [292; 348) '{ ...obj; }': () | ||
654 | [302; 305) 'obj': &dyn D | ||
655 | [316; 318) '&S': &S | ||
656 | [317; 318) 'S': S | ||
657 | [328; 331) 'obj': &dyn A | ||
658 | [342; 345) 'obj': &dyn D | ||
659 | "### | ||
660 | ); | ||
661 | } | ||
662 | |||
663 | #[ignore] | ||
664 | #[test] | ||
665 | fn coerce_unsize_generic() { | ||
666 | // FIXME: Implement this | ||
667 | // https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions | ||
668 | assert_snapshot!( | ||
669 | infer_with_mismatches(r#" | ||
670 | #[lang = "unsize"] | ||
671 | pub trait Unsize<T> {} | ||
672 | #[lang = "coerce_unsized"] | ||
673 | pub trait CoerceUnsized<T> {} | ||
674 | |||
675 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | ||
676 | |||
677 | struct Foo<T> { t: T }; | ||
678 | struct Bar<T>(Foo<T>); | ||
679 | |||
680 | fn test() { | ||
681 | let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] }; | ||
682 | let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] }); | ||
683 | } | ||
684 | "#, true), | ||
685 | @r###" | ||
686 | "### | ||
687 | ); | ||
688 | } | ||