diff options
Diffstat (limited to 'crates/hir_ty/src')
-rw-r--r-- | crates/hir_ty/src/display.rs | 6 | ||||
-rw-r--r-- | crates/hir_ty/src/infer.rs | 7 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/traits.rs | 93 |
3 files changed, 101 insertions, 5 deletions
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 637bbc634..44f843bf3 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -778,8 +778,10 @@ fn write_bounds_like_dyn_trait( | |||
778 | } | 778 | } |
779 | WhereClause::AliasEq(alias_eq) if is_fn_trait => { | 779 | WhereClause::AliasEq(alias_eq) if is_fn_trait => { |
780 | is_fn_trait = false; | 780 | is_fn_trait = false; |
781 | write!(f, " -> ")?; | 781 | if !alias_eq.ty.is_unit() { |
782 | alias_eq.ty.hir_fmt(f)?; | 782 | write!(f, " -> ")?; |
783 | alias_eq.ty.hir_fmt(f)?; | ||
784 | } | ||
783 | } | 785 | } |
784 | WhereClause::AliasEq(AliasEq { ty, alias }) => { | 786 | WhereClause::AliasEq(AliasEq { ty, alias }) => { |
785 | // in types in actual Rust, these will always come | 787 | // in types in actual Rust, these will always come |
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index 174b7471e..8cefd80f3 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs | |||
@@ -579,9 +579,14 @@ impl<'a> InferenceContext<'a> { | |||
579 | } | 579 | } |
580 | 580 | ||
581 | fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> { | 581 | fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> { |
582 | // FIXME resolve via lang_item once try v2 is stable | ||
582 | let path = path![core::ops::Try]; | 583 | let path = path![core::ops::Try]; |
583 | let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?; | 584 | let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?; |
584 | self.db.trait_data(trait_).associated_type_by_name(&name![Ok]) | 585 | let trait_data = self.db.trait_data(trait_); |
586 | trait_data | ||
587 | // FIXME remove once try v2 is stable | ||
588 | .associated_type_by_name(&name![Ok]) | ||
589 | .or_else(|| trait_data.associated_type_by_name(&name![Output])) | ||
585 | } | 590 | } |
586 | 591 | ||
587 | fn resolve_ops_neg_output(&self) -> Option<TypeAliasId> { | 592 | fn resolve_ops_neg_output(&self) -> Option<TypeAliasId> { |
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs index a5a2df54c..6ad96bfe3 100644 --- a/crates/hir_ty/src/tests/traits.rs +++ b/crates/hir_ty/src/tests/traits.rs | |||
@@ -161,6 +161,43 @@ mod result { | |||
161 | } | 161 | } |
162 | 162 | ||
163 | #[test] | 163 | #[test] |
164 | fn infer_tryv2() { | ||
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 | #[prelude_import] use ops::*; | ||
176 | mod ops { | ||
177 | trait Try { | ||
178 | type Output; | ||
179 | type Residual; | ||
180 | } | ||
181 | } | ||
182 | |||
183 | #[prelude_import] use result::*; | ||
184 | mod result { | ||
185 | enum Infallible {} | ||
186 | enum Result<O, E> { | ||
187 | Ok(O), | ||
188 | Err(E) | ||
189 | } | ||
190 | |||
191 | impl<O, E> crate::ops::Try for Result<O, E> { | ||
192 | type Output = O; | ||
193 | type Error = Result<Infallible, E>; | ||
194 | } | ||
195 | } | ||
196 | "#, | ||
197 | ); | ||
198 | } | ||
199 | |||
200 | #[test] | ||
164 | fn infer_for_loop() { | 201 | fn infer_for_loop() { |
165 | check_types( | 202 | check_types( |
166 | r#" | 203 | r#" |
@@ -3041,7 +3078,7 @@ fn infer_fn_trait_arg() { | |||
3041 | 3078 | ||
3042 | #[test] | 3079 | #[test] |
3043 | fn infer_box_fn_arg() { | 3080 | fn infer_box_fn_arg() { |
3044 | // The type mismatch is a bug | 3081 | // The type mismatch is because we don't define Unsize and CoerceUnsized |
3045 | check_infer_with_mismatches( | 3082 | check_infer_with_mismatches( |
3046 | r#" | 3083 | r#" |
3047 | //- /lib.rs deps:std | 3084 | //- /lib.rs deps:std |
@@ -3101,7 +3138,7 @@ fn foo() { | |||
3101 | 555..557 'ps': {unknown} | 3138 | 555..557 'ps': {unknown} |
3102 | 559..561 '{}': () | 3139 | 559..561 '{}': () |
3103 | 568..569 'f': Box<dyn FnOnce(&Option<i32>)> | 3140 | 568..569 'f': Box<dyn FnOnce(&Option<i32>)> |
3104 | 568..573 'f(&s)': FnOnce::Output<dyn FnOnce(&Option<i32>), (&Option<i32>,)> | 3141 | 568..573 'f(&s)': () |
3105 | 570..572 '&s': &Option<i32> | 3142 | 570..572 '&s': &Option<i32> |
3106 | 571..572 's': Option<i32> | 3143 | 571..572 's': Option<i32> |
3107 | 549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|{unknown}| -> ()> | 3144 | 549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|{unknown}| -> ()> |
@@ -3571,3 +3608,55 @@ fn main() { | |||
3571 | "#]], | 3608 | "#]], |
3572 | ) | 3609 | ) |
3573 | } | 3610 | } |
3611 | |||
3612 | #[test] | ||
3613 | fn fn_returning_unit() { | ||
3614 | check_infer_with_mismatches( | ||
3615 | r#" | ||
3616 | #[lang = "fn_once"] | ||
3617 | trait FnOnce<Args> { | ||
3618 | type Output; | ||
3619 | } | ||
3620 | |||
3621 | fn test<F: FnOnce()>(f: F) { | ||
3622 | let _: () = f(); | ||
3623 | }"#, | ||
3624 | expect![[r#" | ||
3625 | 82..83 'f': F | ||
3626 | 88..112 '{ ...f(); }': () | ||
3627 | 98..99 '_': () | ||
3628 | 106..107 'f': F | ||
3629 | 106..109 'f()': () | ||
3630 | "#]], | ||
3631 | ); | ||
3632 | } | ||
3633 | |||
3634 | #[test] | ||
3635 | fn trait_in_scope_of_trait_impl() { | ||
3636 | check_infer( | ||
3637 | r#" | ||
3638 | mod foo { | ||
3639 | pub trait Foo { | ||
3640 | fn foo(self); | ||
3641 | fn bar(self) -> usize { 0 } | ||
3642 | } | ||
3643 | } | ||
3644 | impl foo::Foo for u32 { | ||
3645 | fn foo(self) { | ||
3646 | let _x = self.bar(); | ||
3647 | } | ||
3648 | } | ||
3649 | "#, | ||
3650 | expect![[r#" | ||
3651 | 45..49 'self': Self | ||
3652 | 67..71 'self': Self | ||
3653 | 82..87 '{ 0 }': usize | ||
3654 | 84..85 '0': usize | ||
3655 | 131..135 'self': u32 | ||
3656 | 137..173 '{ ... }': () | ||
3657 | 151..153 '_x': usize | ||
3658 | 156..160 'self': u32 | ||
3659 | 156..166 'self.bar()': usize | ||
3660 | "#]], | ||
3661 | ); | ||
3662 | } | ||