aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-04-12 11:29:03 +0100
committerFlorian Diebold <[email protected]>2020-04-13 15:32:23 +0100
commitd88d67819b3f052422ad3f024e44ad73dde1630b (patch)
tree990564fefe3e9b907ea7dea59563703e2165c08e
parentc388130f5ffbcbe7d3131213a24d12d02f769b87 (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.rs14
-rw-r--r--crates/ra_hir_ty/src/tests/regression.rs3
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs26
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]
1806fn unselected_projection_on_trait_self() { 1806fn 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]
1847fn unselected_projection_on_trait_self() {
1848 let t = type_at(
1849 r#"
1850//- /main.rs
1851trait Trait {
1852 type Item;
1853
1854 fn f(&self) -> Self::Item { loop {} }
1855}
1856
1857struct S;
1858impl Trait for S {
1859 type Item = u32;
1860}
1861
1862fn test() {
1863 S.f()<|>;
1864}
1865"#,
1866 );
1867 assert_eq!(t, "u32");
1868}
1869
1870#[test]
1847fn trait_impl_self_ty() { 1871fn trait_impl_self_ty() {
1848 let t = type_at( 1872 let t = type_at(
1849 r#" 1873 r#"