aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/tests/traits.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/tests/traits.rs')
-rw-r--r--crates/hir_ty/src/tests/traits.rs157
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]
164fn infer_try_trait_v2() {
165 check_types(
166 r#"
167//- /main.rs crate:main deps:core
168fn test() {
169 let r: Result<i32, u64> = Result::Ok(1);
170 let v = r?;
171 v;
172} //^ i32
173
174//- /core.rs crate:core
175mod 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
188mov convert {
189 pub trait From<T> {}
190 impl<T> From<T> for T {}
191}
192
193#[prelude_import] use result::*;
194mod 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]
164fn infer_for_loop() { 216fn 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]
3043fn infer_box_fn_arg() { 3095fn 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]
3628fn fn_returning_unit() {
3629 check_infer_with_mismatches(
3630 r#"
3631#[lang = "fn_once"]
3632trait FnOnce<Args> {
3633 type Output;
3634}
3635
3636fn 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]
3650fn trait_in_scope_of_trait_impl() {
3651 check_infer(
3652 r#"
3653mod foo {
3654 pub trait Foo {
3655 fn foo(self);
3656 fn bar(self) -> usize { 0 }
3657 }
3658}
3659impl 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]
3680fn infer_async_ret_type() {
3681 check_types(
3682 r#"
3683//- /main.rs crate:main deps:core
3684
3685enum Result<T, E> {
3686 Ok(T),
3687 Err(E),
3688}
3689
3690use Result::*;
3691
3692
3693struct Fooey;
3694
3695impl Fooey {
3696 fn collect<B: Convert>(self) -> B {
3697 B::new()
3698 }
3699}
3700
3701trait Convert {
3702 fn new() -> Self;
3703}
3704impl Convert for u32 {
3705 fn new() -> Self {
3706 0
3707 }
3708}
3709
3710async 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::*;
3718mod future {
3719 #[lang = "future_trait"]
3720 trait Future {
3721 type Output;
3722 }
3723}
3724"#,
3725 );
3726}