diff options
Diffstat (limited to 'crates/hir_ty/src/tests/traits.rs')
-rw-r--r-- | crates/hir_ty/src/tests/traits.rs | 157 |
1 files changed, 155 insertions, 2 deletions
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs index a5a2df54c..49add4ab9 100644 --- a/crates/hir_ty/src/tests/traits.rs +++ b/crates/hir_ty/src/tests/traits.rs | |||
@@ -161,6 +161,58 @@ mod result { | |||
161 | } | 161 | } |
162 | 162 | ||
163 | #[test] | 163 | #[test] |
164 | fn infer_try_trait_v2() { | ||
165 | check_types( | ||
166 | r#" | ||
167 | //- /main.rs crate:main deps:core | ||
168 | fn test() { | ||
169 | let r: Result<i32, u64> = Result::Ok(1); | ||
170 | let v = r?; | ||
171 | v; | ||
172 | } //^ i32 | ||
173 | |||
174 | //- /core.rs crate:core | ||
175 | mod ops { | ||
176 | mod try_trait { | ||
177 | pub trait Try: FromResidual { | ||
178 | type Output; | ||
179 | type Residual; | ||
180 | } | ||
181 | pub trait FromResidual<R = <Self as Try>::Residual> {} | ||
182 | } | ||
183 | |||
184 | pub use self::try_trait::FromResidual; | ||
185 | pub use self::try_trait::Try; | ||
186 | } | ||
187 | |||
188 | mov convert { | ||
189 | pub trait From<T> {} | ||
190 | impl<T> From<T> for T {} | ||
191 | } | ||
192 | |||
193 | #[prelude_import] use result::*; | ||
194 | mod result { | ||
195 | use crate::convert::From; | ||
196 | use crate::ops::{Try, FromResidual}; | ||
197 | |||
198 | pub enum Infallible {} | ||
199 | pub enum Result<O, E> { | ||
200 | Ok(O), | ||
201 | Err(E) | ||
202 | } | ||
203 | |||
204 | impl<O, E> Try for Result<O, E> { | ||
205 | type Output = O; | ||
206 | type Error = Result<Infallible, E>; | ||
207 | } | ||
208 | |||
209 | impl<T, E, F: From<E>> FromResidual<Result<Infallible, E>> for Result<T, F> {} | ||
210 | } | ||
211 | "#, | ||
212 | ); | ||
213 | } | ||
214 | |||
215 | #[test] | ||
164 | fn infer_for_loop() { | 216 | fn infer_for_loop() { |
165 | check_types( | 217 | check_types( |
166 | r#" | 218 | r#" |
@@ -3041,7 +3093,7 @@ fn infer_fn_trait_arg() { | |||
3041 | 3093 | ||
3042 | #[test] | 3094 | #[test] |
3043 | fn infer_box_fn_arg() { | 3095 | fn infer_box_fn_arg() { |
3044 | // The type mismatch is a bug | 3096 | // The type mismatch is because we don't define Unsize and CoerceUnsized |
3045 | check_infer_with_mismatches( | 3097 | check_infer_with_mismatches( |
3046 | r#" | 3098 | r#" |
3047 | //- /lib.rs deps:std | 3099 | //- /lib.rs deps:std |
@@ -3101,7 +3153,7 @@ fn foo() { | |||
3101 | 555..557 'ps': {unknown} | 3153 | 555..557 'ps': {unknown} |
3102 | 559..561 '{}': () | 3154 | 559..561 '{}': () |
3103 | 568..569 'f': Box<dyn FnOnce(&Option<i32>)> | 3155 | 568..569 'f': Box<dyn FnOnce(&Option<i32>)> |
3104 | 568..573 'f(&s)': FnOnce::Output<dyn FnOnce(&Option<i32>), (&Option<i32>,)> | 3156 | 568..573 'f(&s)': () |
3105 | 570..572 '&s': &Option<i32> | 3157 | 570..572 '&s': &Option<i32> |
3106 | 571..572 's': Option<i32> | 3158 | 571..572 's': Option<i32> |
3107 | 549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|{unknown}| -> ()> | 3159 | 549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|{unknown}| -> ()> |
@@ -3571,3 +3623,104 @@ fn main() { | |||
3571 | "#]], | 3623 | "#]], |
3572 | ) | 3624 | ) |
3573 | } | 3625 | } |
3626 | |||
3627 | #[test] | ||
3628 | fn fn_returning_unit() { | ||
3629 | check_infer_with_mismatches( | ||
3630 | r#" | ||
3631 | #[lang = "fn_once"] | ||
3632 | trait FnOnce<Args> { | ||
3633 | type Output; | ||
3634 | } | ||
3635 | |||
3636 | fn test<F: FnOnce()>(f: F) { | ||
3637 | let _: () = f(); | ||
3638 | }"#, | ||
3639 | expect![[r#" | ||
3640 | 82..83 'f': F | ||
3641 | 88..112 '{ ...f(); }': () | ||
3642 | 98..99 '_': () | ||
3643 | 106..107 'f': F | ||
3644 | 106..109 'f()': () | ||
3645 | "#]], | ||
3646 | ); | ||
3647 | } | ||
3648 | |||
3649 | #[test] | ||
3650 | fn trait_in_scope_of_trait_impl() { | ||
3651 | check_infer( | ||
3652 | r#" | ||
3653 | mod foo { | ||
3654 | pub trait Foo { | ||
3655 | fn foo(self); | ||
3656 | fn bar(self) -> usize { 0 } | ||
3657 | } | ||
3658 | } | ||
3659 | impl foo::Foo for u32 { | ||
3660 | fn foo(self) { | ||
3661 | let _x = self.bar(); | ||
3662 | } | ||
3663 | } | ||
3664 | "#, | ||
3665 | expect![[r#" | ||
3666 | 45..49 'self': Self | ||
3667 | 67..71 'self': Self | ||
3668 | 82..87 '{ 0 }': usize | ||
3669 | 84..85 '0': usize | ||
3670 | 131..135 'self': u32 | ||
3671 | 137..173 '{ ... }': () | ||
3672 | 151..153 '_x': usize | ||
3673 | 156..160 'self': u32 | ||
3674 | 156..166 'self.bar()': usize | ||
3675 | "#]], | ||
3676 | ); | ||
3677 | } | ||
3678 | |||
3679 | #[test] | ||
3680 | fn infer_async_ret_type() { | ||
3681 | check_types( | ||
3682 | r#" | ||
3683 | //- /main.rs crate:main deps:core | ||
3684 | |||
3685 | enum Result<T, E> { | ||
3686 | Ok(T), | ||
3687 | Err(E), | ||
3688 | } | ||
3689 | |||
3690 | use Result::*; | ||
3691 | |||
3692 | |||
3693 | struct Fooey; | ||
3694 | |||
3695 | impl Fooey { | ||
3696 | fn collect<B: Convert>(self) -> B { | ||
3697 | B::new() | ||
3698 | } | ||
3699 | } | ||
3700 | |||
3701 | trait Convert { | ||
3702 | fn new() -> Self; | ||
3703 | } | ||
3704 | impl Convert for u32 { | ||
3705 | fn new() -> Self { | ||
3706 | 0 | ||
3707 | } | ||
3708 | } | ||
3709 | |||
3710 | async fn get_accounts() -> Result<u32, ()> { | ||
3711 | let ret = Fooey.collect(); | ||
3712 | // ^ u32 | ||
3713 | Ok(ret) | ||
3714 | } | ||
3715 | |||
3716 | //- /core.rs crate:core | ||
3717 | #[prelude_import] use future::*; | ||
3718 | mod future { | ||
3719 | #[lang = "future_trait"] | ||
3720 | trait Future { | ||
3721 | type Output; | ||
3722 | } | ||
3723 | } | ||
3724 | "#, | ||
3725 | ); | ||
3726 | } | ||