diff options
Diffstat (limited to 'crates/ra_hir_ty/src/tests')
-rw-r--r-- | crates/ra_hir_ty/src/tests/coercion.rs | 55 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/traits.rs | 132 |
2 files changed, 123 insertions, 64 deletions
diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs index 136d28a91..d7fb6a962 100644 --- a/crates/ra_hir_ty/src/tests/coercion.rs +++ b/crates/ra_hir_ty/src/tests/coercion.rs | |||
@@ -662,7 +662,53 @@ fn test() { | |||
662 | } | 662 | } |
663 | 663 | ||
664 | #[test] | 664 | #[test] |
665 | fn coerce_unsize_trait_object() { | 665 | fn coerce_unsize_trait_object_simple() { |
666 | assert_snapshot!( | ||
667 | infer_with_mismatches(r#" | ||
668 | #[lang = "sized"] | ||
669 | pub trait Sized {} | ||
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 | trait Foo<T, U> {} | ||
678 | trait Bar<U, T, X>: Foo<T, U> {} | ||
679 | trait Baz<T, X>: Bar<usize, T, X> {} | ||
680 | |||
681 | struct S<T, X>; | ||
682 | impl<T, X> Foo<T, usize> for S<T, X> {} | ||
683 | impl<T, X> Bar<usize, T, X> for S<T, X> {} | ||
684 | impl<T, X> Baz<T, X> for S<T, X> {} | ||
685 | |||
686 | fn test() { | ||
687 | let obj: &dyn Baz<i8, i16> = &S; | ||
688 | let obj: &dyn Bar<_, i8, i16> = &S; | ||
689 | let obj: &dyn Foo<i8, _> = &S; | ||
690 | } | ||
691 | "#, true), | ||
692 | @r###" | ||
693 | 424..539 '{ ... &S; }': () | ||
694 | 434..437 'obj': &dyn Baz<i8, i16> | ||
695 | 459..461 '&S': &S<i8, i16> | ||
696 | 460..461 'S': S<i8, i16> | ||
697 | 471..474 'obj': &dyn Bar<usize, i8, i16> | ||
698 | 499..501 '&S': &S<i8, i16> | ||
699 | 500..501 'S': S<i8, i16> | ||
700 | 511..514 'obj': &dyn Foo<i8, usize> | ||
701 | 534..536 '&S': &S<i8, {unknown}> | ||
702 | 535..536 'S': S<i8, {unknown}> | ||
703 | "### | ||
704 | ); | ||
705 | } | ||
706 | |||
707 | #[test] | ||
708 | // The rust reference says this should be possible, but rustc doesn't implement | ||
709 | // it. We used to support it, but Chalk doesn't. | ||
710 | #[ignore] | ||
711 | fn coerce_unsize_trait_object_to_trait_object() { | ||
666 | assert_snapshot!( | 712 | assert_snapshot!( |
667 | infer_with_mismatches(r#" | 713 | infer_with_mismatches(r#" |
668 | #[lang = "sized"] | 714 | #[lang = "sized"] |
@@ -735,16 +781,17 @@ impl D for S {} | |||
735 | 781 | ||
736 | fn test() { | 782 | fn test() { |
737 | let obj: &dyn D = &S; | 783 | let obj: &dyn D = &S; |
738 | let obj: &dyn A = obj; | 784 | let obj: &dyn A = &S; |
739 | } | 785 | } |
740 | "#, true), | 786 | "#, true), |
741 | @r###" | 787 | @r###" |
742 | 328..384 '{ ...obj; }': () | 788 | 328..383 '{ ... &S; }': () |
743 | 338..341 'obj': &dyn D | 789 | 338..341 'obj': &dyn D |
744 | 352..354 '&S': &S | 790 | 352..354 '&S': &S |
745 | 353..354 'S': S | 791 | 353..354 'S': S |
746 | 364..367 'obj': &dyn A | 792 | 364..367 'obj': &dyn A |
747 | 378..381 'obj': &dyn D | 793 | 378..380 '&S': &S |
794 | 379..380 'S': S | ||
748 | "### | 795 | "### |
749 | ); | 796 | ); |
750 | } | 797 | } |
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 529d9e253..27737fa94 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs | |||
@@ -1992,6 +1992,28 @@ fn test() { | |||
1992 | } | 1992 | } |
1993 | 1993 | ||
1994 | #[test] | 1994 | #[test] |
1995 | fn fn_item_fn_trait() { | ||
1996 | check_types( | ||
1997 | r#" | ||
1998 | #[lang = "fn_once"] | ||
1999 | trait FnOnce<Args> { | ||
2000 | type Output; | ||
2001 | } | ||
2002 | |||
2003 | struct S; | ||
2004 | |||
2005 | fn foo() -> S {} | ||
2006 | |||
2007 | fn takes_closure<U, F: FnOnce() -> U>(f: F) -> U { f() } | ||
2008 | |||
2009 | fn test() { | ||
2010 | takes_closure(foo); | ||
2011 | } //^^^^^^^^^^^^^^^^^^ S | ||
2012 | "#, | ||
2013 | ); | ||
2014 | } | ||
2015 | |||
2016 | #[test] | ||
1995 | fn unselected_projection_in_trait_env_1() { | 2017 | fn unselected_projection_in_trait_env_1() { |
1996 | check_types( | 2018 | check_types( |
1997 | r#" | 2019 | r#" |
@@ -3000,74 +3022,47 @@ fn infer_box_fn_arg() { | |||
3000 | 3022 | ||
3001 | #[test] | 3023 | #[test] |
3002 | fn infer_dyn_fn_output() { | 3024 | fn infer_dyn_fn_output() { |
3003 | assert_snapshot!( | 3025 | check_types( |
3004 | infer( | 3026 | r#" |
3005 | r#" | 3027 | #[lang = "fn_once"] |
3006 | //- /lib.rs deps:std | 3028 | pub trait FnOnce<Args> { |
3007 | 3029 | type Output; | |
3008 | #[lang = "fn_once"] | 3030 | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; |
3009 | pub trait FnOnce<Args> { | 3031 | } |
3010 | type Output; | ||
3011 | |||
3012 | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; | ||
3013 | } | ||
3014 | |||
3015 | #[lang = "fn"] | ||
3016 | pub trait Fn<Args>:FnOnce<Args> { | ||
3017 | extern "rust-call" fn call(&self, args: Args) -> Self::Output; | ||
3018 | } | ||
3019 | |||
3020 | #[lang = "deref"] | ||
3021 | pub trait Deref { | ||
3022 | type Target: ?Sized; | ||
3023 | |||
3024 | fn deref(&self) -> &Self::Target; | ||
3025 | } | ||
3026 | 3032 | ||
3027 | #[lang = "owned_box"] | 3033 | #[lang = "fn"] |
3028 | pub struct Box<T: ?Sized> { | 3034 | pub trait Fn<Args>: FnOnce<Args> { |
3029 | inner: *mut T, | 3035 | extern "rust-call" fn call(&self, args: Args) -> Self::Output; |
3030 | } | 3036 | } |
3031 | 3037 | ||
3032 | impl<T: ?Sized> Deref for Box<T> { | 3038 | fn foo() { |
3033 | type Target = T; | 3039 | let f: &dyn Fn() -> i32; |
3040 | f(); | ||
3041 | //^^^ i32 | ||
3042 | }"#, | ||
3043 | ); | ||
3044 | } | ||
3034 | 3045 | ||
3035 | fn deref(&self) -> &T { | 3046 | #[test] |
3036 | &self.inner | 3047 | fn infer_dyn_fn_once_output() { |
3037 | } | 3048 | check_types( |
3038 | } | 3049 | r#" |
3050 | #[lang = "fn_once"] | ||
3051 | pub trait FnOnce<Args> { | ||
3052 | type Output; | ||
3053 | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; | ||
3054 | } | ||
3039 | 3055 | ||
3040 | fn foo() { | 3056 | fn foo() { |
3041 | let f: Box<dyn Fn() -> i32> = box(|| 5); | 3057 | let f: dyn FnOnce() -> i32; |
3042 | let x = f(); | 3058 | f(); |
3043 | } | 3059 | //^^^ i32 |
3044 | "# | 3060 | }"#, |
3045 | ), | ||
3046 | @r###" | ||
3047 | 100..104 'self': Self | ||
3048 | 106..110 'args': Args | ||
3049 | 219..223 'self': &Self | ||
3050 | 225..229 'args': Args | ||
3051 | 333..337 'self': &Self | ||
3052 | 503..507 'self': &Box<T> | ||
3053 | 515..542 '{ ... }': &T | ||
3054 | 525..536 '&self.inner': &*mut T | ||
3055 | 526..530 'self': &Box<T> | ||
3056 | 526..536 'self.inner': *mut T | ||
3057 | 555..620 '{ ...f(); }': () | ||
3058 | 565..566 'f': Box<dyn Fn<(), Output = i32>> | ||
3059 | 591..600 'box(|| 5)': Box<|| -> i32> | ||
3060 | 595..599 '|| 5': || -> i32 | ||
3061 | 598..599 '5': i32 | ||
3062 | 610..611 'x': FnOnce::Output<dyn Fn<(), Output = i32>, ()> | ||
3063 | 614..615 'f': Box<dyn Fn<(), Output = i32>> | ||
3064 | 614..617 'f()': FnOnce::Output<dyn Fn<(), Output = i32>, ()> | ||
3065 | "### | ||
3066 | ); | 3061 | ); |
3067 | } | 3062 | } |
3068 | 3063 | ||
3069 | #[test] | 3064 | #[test] |
3070 | fn variable_kinds() { | 3065 | fn variable_kinds_1() { |
3071 | check_types( | 3066 | check_types( |
3072 | r#" | 3067 | r#" |
3073 | trait Trait<T> { fn get(self, t: T) -> T; } | 3068 | trait Trait<T> { fn get(self, t: T) -> T; } |
@@ -3083,3 +3078,20 @@ fn test() { | |||
3083 | "#, | 3078 | "#, |
3084 | ); | 3079 | ); |
3085 | } | 3080 | } |
3081 | |||
3082 | #[test] | ||
3083 | fn variable_kinds_2() { | ||
3084 | check_types( | ||
3085 | r#" | ||
3086 | trait Trait { fn get(self) -> Self; } | ||
3087 | impl Trait for u128 {} | ||
3088 | impl Trait for f32 {} | ||
3089 | fn test() { | ||
3090 | 1.get(); | ||
3091 | //^^^^^^^ u128 | ||
3092 | (1.).get(); | ||
3093 | //^^^^^^^^^^ f32 | ||
3094 | } | ||
3095 | "#, | ||
3096 | ); | ||
3097 | } | ||