diff options
author | Florian Diebold <[email protected]> | 2020-04-12 11:29:03 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2020-04-13 15:32:23 +0100 |
commit | d88d67819b3f052422ad3f024e44ad73dde1630b (patch) | |
tree | 990564fefe3e9b907ea7dea59563703e2165c08e | |
parent | c388130f5ffbcbe7d3131213a24d12d02f769b87 (diff) |
Handle `Self::Type` in trait definitions when referring to own associated type
It was implemented for other generic parameters for the trait, but not for `Self`.
-rw-r--r-- | crates/ra_hir_ty/src/lower.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/regression.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/traits.rs | 26 |
3 files changed, 38 insertions, 5 deletions
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 6c7bbc448..7b5990a47 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs | |||
@@ -360,13 +360,23 @@ impl Ty { | |||
360 | }, | 360 | }, |
361 | Some(TypeNs::GenericParam(param_id)) => { | 361 | Some(TypeNs::GenericParam(param_id)) => { |
362 | let predicates = ctx.db.generic_predicates_for_param(param_id); | 362 | let predicates = ctx.db.generic_predicates_for_param(param_id); |
363 | predicates | 363 | let mut traits_: Vec<_> = predicates |
364 | .iter() | 364 | .iter() |
365 | .filter_map(|pred| match &pred.value { | 365 | .filter_map(|pred| match &pred.value { |
366 | GenericPredicate::Implemented(tr) => Some(tr.trait_), | 366 | GenericPredicate::Implemented(tr) => Some(tr.trait_), |
367 | _ => None, | 367 | _ => None, |
368 | }) | 368 | }) |
369 | .collect() | 369 | .collect(); |
370 | // Handle `Self::Type` referring to own associated type in trait definitions | ||
371 | if let GenericDefId::TraitId(trait_id) = param_id.parent { | ||
372 | let generics = generics(ctx.db.upcast(), trait_id.into()); | ||
373 | if generics.params.types[param_id.local_id].provenance | ||
374 | == TypeParamProvenance::TraitSelf | ||
375 | { | ||
376 | traits_.push(trait_id); | ||
377 | } | ||
378 | } | ||
379 | traits_ | ||
370 | } | 380 | } |
371 | _ => return Ty::Unknown, | 381 | _ => return Ty::Unknown, |
372 | }; | 382 | }; |
diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs index 3402e0cb5..d69115a2f 100644 --- a/crates/ra_hir_ty/src/tests/regression.rs +++ b/crates/ra_hir_ty/src/tests/regression.rs | |||
@@ -451,8 +451,7 @@ pub mod str { | |||
451 | "#, | 451 | "#, |
452 | ); | 452 | ); |
453 | 453 | ||
454 | // should be Option<char>, but currently not because of Chalk ambiguity problem | 454 | assert_eq!("(Option<char>, Option<char>)", super::type_at_pos(&db, pos)); |
455 | assert_eq!("(Option<{unknown}>, Option<{unknown}>)", super::type_at_pos(&db, pos)); | ||
456 | } | 455 | } |
457 | 456 | ||
458 | #[test] | 457 | #[test] |
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 22ae6ca90..d088bf309 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs | |||
@@ -1803,7 +1803,7 @@ fn test<T, U>() where T::Item: Trait2, T: Trait<U::Item>, U: Trait<()> { | |||
1803 | } | 1803 | } |
1804 | 1804 | ||
1805 | #[test] | 1805 | #[test] |
1806 | fn unselected_projection_on_trait_self() { | 1806 | fn unselected_projection_on_impl_self() { |
1807 | assert_snapshot!(infer( | 1807 | assert_snapshot!(infer( |
1808 | r#" | 1808 | r#" |
1809 | //- /main.rs | 1809 | //- /main.rs |
@@ -1844,6 +1844,30 @@ impl Trait for S2 { | |||
1844 | } | 1844 | } |
1845 | 1845 | ||
1846 | #[test] | 1846 | #[test] |
1847 | fn unselected_projection_on_trait_self() { | ||
1848 | let t = type_at( | ||
1849 | r#" | ||
1850 | //- /main.rs | ||
1851 | trait Trait { | ||
1852 | type Item; | ||
1853 | |||
1854 | fn f(&self) -> Self::Item { loop {} } | ||
1855 | } | ||
1856 | |||
1857 | struct S; | ||
1858 | impl Trait for S { | ||
1859 | type Item = u32; | ||
1860 | } | ||
1861 | |||
1862 | fn test() { | ||
1863 | S.f()<|>; | ||
1864 | } | ||
1865 | "#, | ||
1866 | ); | ||
1867 | assert_eq!(t, "u32"); | ||
1868 | } | ||
1869 | |||
1870 | #[test] | ||
1847 | fn trait_impl_self_ty() { | 1871 | fn trait_impl_self_ty() { |
1848 | let t = type_at( | 1872 | let t = type_at( |
1849 | r#" | 1873 | r#" |