aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/tests
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/tests')
-rw-r--r--crates/ra_hir_ty/src/tests/coercion.rs55
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs132
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]
665fn coerce_unsize_trait_object() { 665fn coerce_unsize_trait_object_simple() {
666 assert_snapshot!(
667 infer_with_mismatches(r#"
668#[lang = "sized"]
669pub trait Sized {}
670#[lang = "unsize"]
671pub trait Unsize<T> {}
672#[lang = "coerce_unsized"]
673pub trait CoerceUnsized<T> {}
674
675impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
676
677trait Foo<T, U> {}
678trait Bar<U, T, X>: Foo<T, U> {}
679trait Baz<T, X>: Bar<usize, T, X> {}
680
681struct S<T, X>;
682impl<T, X> Foo<T, usize> for S<T, X> {}
683impl<T, X> Bar<usize, T, X> for S<T, X> {}
684impl<T, X> Baz<T, X> for S<T, X> {}
685
686fn 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]
711fn 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
736fn test() { 782fn 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]
1995fn fn_item_fn_trait() {
1996 check_types(
1997 r#"
1998#[lang = "fn_once"]
1999trait FnOnce<Args> {
2000 type Output;
2001}
2002
2003struct S;
2004
2005fn foo() -> S {}
2006
2007fn takes_closure<U, F: FnOnce() -> U>(f: F) -> U { f() }
2008
2009fn test() {
2010 takes_closure(foo);
2011} //^^^^^^^^^^^^^^^^^^ S
2012"#,
2013 );
2014}
2015
2016#[test]
1995fn unselected_projection_in_trait_env_1() { 2017fn 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]
3002fn infer_dyn_fn_output() { 3024fn 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 3028pub 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> { 3034pub 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> { 3038fn 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 3047fn infer_dyn_fn_once_output() {
3037 } 3048 check_types(
3038 } 3049 r#"
3050#[lang = "fn_once"]
3051pub trait FnOnce<Args> {
3052 type Output;
3053 extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
3054}
3039 3055
3040 fn foo() { 3056fn 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]
3070fn variable_kinds() { 3065fn variable_kinds_1() {
3071 check_types( 3066 check_types(
3072 r#" 3067 r#"
3073trait Trait<T> { fn get(self, t: T) -> T; } 3068trait Trait<T> { fn get(self, t: T) -> T; }
@@ -3083,3 +3078,20 @@ fn test() {
3083 "#, 3078 "#,
3084 ); 3079 );
3085} 3080}
3081
3082#[test]
3083fn variable_kinds_2() {
3084 check_types(
3085 r#"
3086trait Trait { fn get(self) -> Self; }
3087impl Trait for u128 {}
3088impl Trait for f32 {}
3089fn test() {
3090 1.get();
3091 //^^^^^^^ u128
3092 (1.).get();
3093 //^^^^^^^^^^ f32
3094}
3095 "#,
3096 );
3097}