From db32a2e4211f9444ef4f10b633e400d27ed2662e Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 10 Apr 2020 22:05:46 +0200 Subject: Implement inline associated type bounds Like `Iterator`. This is an unstable feature, but it's used in the standard library e.g. in the definition of Flatten, so we can't get away with not implementing it :) --- crates/ra_hir_ty/src/tests/traits.rs | 47 ++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'crates/ra_hir_ty/src/tests') diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index 22ae6ca90..53461bdbb 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs @@ -1923,6 +1923,53 @@ fn test() where T: Trait, U: Trait { assert_eq!(t, "{unknown}"); } +#[test] +fn inline_assoc_type_bounds_1() { + let t = type_at( + r#" +//- /main.rs +trait Iterator { + type Item; +} +trait OtherTrait { + fn foo(&self) -> T; +} + +// workaround for Chalk assoc type normalization problems +pub struct S; +impl Iterator for S { + type Item = ::Item; +} + +fn test>>() { + let x: as Iterator>::Item; + x.foo()<|>; +} +"#, + ); + assert_eq!(t, "u32"); +} + +#[test] +fn inline_assoc_type_bounds_2() { + let t = type_at( + r#" +//- /main.rs +trait Iterator { + type Item; +} + +fn test>>() { + let x: <::Item as Iterator>::Item; + x<|>; +} +"#, + ); + // assert_eq!(t, "u32"); + // doesn't currently work, Chalk #234 + assert_eq!(t, "{unknown}"); +} + #[test] fn unify_impl_trait() { assert_snapshot!( -- cgit v1.2.3 From d88d67819b3f052422ad3f024e44ad73dde1630b Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 12 Apr 2020 12:29:03 +0200 Subject: 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`. --- crates/ra_hir_ty/src/tests/regression.rs | 3 +-- crates/ra_hir_ty/src/tests/traits.rs | 26 +++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir_ty/src/tests') 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 { "#, ); - // should be Option, but currently not because of Chalk ambiguity problem - assert_eq!("(Option<{unknown}>, Option<{unknown}>)", super::type_at_pos(&db, pos)); + assert_eq!("(Option, Option)", super::type_at_pos(&db, pos)); } #[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() where T::Item: Trait2, T: Trait, U: Trait<()> { } #[test] -fn unselected_projection_on_trait_self() { +fn unselected_projection_on_impl_self() { assert_snapshot!(infer( r#" //- /main.rs @@ -1843,6 +1843,30 @@ impl Trait for S2 { "###); } +#[test] +fn unselected_projection_on_trait_self() { + let t = type_at( + r#" +//- /main.rs +trait Trait { + type Item; + + fn f(&self) -> Self::Item { loop {} } +} + +struct S; +impl Trait for S { + type Item = u32; +} + +fn test() { + S.f()<|>; +} +"#, + ); + assert_eq!(t, "u32"); +} + #[test] fn trait_impl_self_ty() { let t = type_at( -- cgit v1.2.3