diff options
-rw-r--r-- | crates/hir_ty/src/display.rs | 26 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/regression.rs | 8 | ||||
-rw-r--r-- | crates/hir_ty/src/tests/traits.rs | 46 |
3 files changed, 61 insertions, 19 deletions
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index d2e151f25..43db24882 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -390,11 +390,27 @@ impl HirDisplay for ApplicationTy { | |||
390 | }; | 390 | }; |
391 | let trait_ = f.db.trait_data(trait_); | 391 | let trait_ = f.db.trait_data(trait_); |
392 | let type_alias = f.db.type_alias_data(type_alias); | 392 | let type_alias = f.db.type_alias_data(type_alias); |
393 | write!(f, "{}::{}", trait_.name, type_alias.name)?; | 393 | |
394 | if self.parameters.len() > 0 { | 394 | // Use placeholder associated types when the target is source code (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) |
395 | write!(f, "<")?; | 395 | if f.display_target.is_source_code() || self.parameters.len() > 1 { |
396 | f.write_joined(&*self.parameters.0, ", ")?; | 396 | write!(f, "{}::{}", trait_.name, type_alias.name)?; |
397 | write!(f, ">")?; | 397 | if self.parameters.len() > 0 { |
398 | write!(f, "<")?; | ||
399 | f.write_joined(&*self.parameters.0, ", ")?; | ||
400 | write!(f, ">")?; | ||
401 | } | ||
402 | } else { | ||
403 | if self.parameters.len() == 1 { | ||
404 | write!( | ||
405 | f, | ||
406 | "<{} as {}>::{}", | ||
407 | self.parameters.as_single().display(f.db), | ||
408 | trait_.name, | ||
409 | type_alias.name | ||
410 | )?; | ||
411 | } else { | ||
412 | write!(f, "{}::{}", trait_.name, type_alias.name)?; | ||
413 | } | ||
398 | } | 414 | } |
399 | } | 415 | } |
400 | TypeCtor::ForeignType(type_alias) => { | 416 | TypeCtor::ForeignType(type_alias) => { |
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs index 94d86b0d1..66e171f24 100644 --- a/crates/hir_ty/src/tests/regression.rs +++ b/crates/hir_ty/src/tests/regression.rs | |||
@@ -831,11 +831,11 @@ fn issue_4966() { | |||
831 | 356..362 'repeat': Repeat<Map<|&f64| -> f64>> | 831 | 356..362 'repeat': Repeat<Map<|&f64| -> f64>> |
832 | 365..390 'Repeat...nner }': Repeat<Map<|&f64| -> f64>> | 832 | 365..390 'Repeat...nner }': Repeat<Map<|&f64| -> f64>> |
833 | 383..388 'inner': Map<|&f64| -> f64> | 833 | 383..388 'inner': Map<|&f64| -> f64> |
834 | 401..404 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> | 834 | 401..404 'vec': Vec<<Repeat<Map<|&f64| -> f64>> as IntoIterator>::Item> |
835 | 407..416 'from_iter': fn from_iter<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>, Repeat<Map<|&f64| -> f64>>>(Repeat<Map<|&f64| -> f64>>) -> Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> | 835 | 407..416 'from_iter': fn from_iter<<Repeat<Map<|&f64| -> f64>> as IntoIterator>::Item, Repeat<Map<|&f64| -> f64>>>(Repeat<Map<|&f64| -> f64>>) -> Vec<<Repeat<Map<|&f64| -> f64>> as IntoIterator>::Item> |
836 | 407..424 'from_i...epeat)': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> | 836 | 407..424 'from_i...epeat)': Vec<<Repeat<Map<|&f64| -> f64>> as IntoIterator>::Item> |
837 | 417..423 'repeat': Repeat<Map<|&f64| -> f64>> | 837 | 417..423 'repeat': Repeat<Map<|&f64| -> f64>> |
838 | 431..434 'vec': Vec<IntoIterator::Item<Repeat<Map<|&f64| -> f64>>>> | 838 | 431..434 'vec': Vec<<Repeat<Map<|&f64| -> f64>> as IntoIterator>::Item> |
839 | 431..444 'vec.foo_bar()': {unknown} | 839 | 431..444 'vec.foo_bar()': {unknown} |
840 | "#]], | 840 | "#]], |
841 | ); | 841 | ); |
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs index 41d097519..7ad8b5830 100644 --- a/crates/hir_ty/src/tests/traits.rs +++ b/crates/hir_ty/src/tests/traits.rs | |||
@@ -384,12 +384,12 @@ fn infer_project_associated_type() { | |||
384 | 108..261 '{ ...ter; }': () | 384 | 108..261 '{ ...ter; }': () |
385 | 118..119 'x': u32 | 385 | 118..119 'x': u32 |
386 | 145..146 '1': u32 | 386 | 145..146 '1': u32 |
387 | 156..157 'y': Iterable::Item<T> | 387 | 156..157 'y': <T as Iterable>::Item |
388 | 183..192 'no_matter': Iterable::Item<T> | 388 | 183..192 'no_matter': <T as Iterable>::Item |
389 | 202..203 'z': Iterable::Item<T> | 389 | 202..203 'z': <T as Iterable>::Item |
390 | 215..224 'no_matter': Iterable::Item<T> | 390 | 215..224 'no_matter': <T as Iterable>::Item |
391 | 234..235 'a': Iterable::Item<T> | 391 | 234..235 'a': <T as Iterable>::Item |
392 | 249..258 'no_matter': Iterable::Item<T> | 392 | 249..258 'no_matter': <T as Iterable>::Item |
393 | "#]], | 393 | "#]], |
394 | ); | 394 | ); |
395 | } | 395 | } |
@@ -908,7 +908,6 @@ fn test<T: Trait>(t: T) { (*t); } | |||
908 | 908 | ||
909 | #[test] | 909 | #[test] |
910 | fn associated_type_placeholder() { | 910 | fn associated_type_placeholder() { |
911 | // inside the generic function, the associated type gets normalized to a placeholder `ApplL::Out<T>` [https://rust-lang.github.io/rustc-guide/traits/associated-types.html#placeholder-associated-types]. | ||
912 | check_types( | 911 | check_types( |
913 | r#" | 912 | r#" |
914 | pub trait ApplyL { | 913 | pub trait ApplyL { |
@@ -924,7 +923,7 @@ impl<T> ApplyL for RefMutL<T> { | |||
924 | fn test<T: ApplyL>() { | 923 | fn test<T: ApplyL>() { |
925 | let y: <RefMutL<T> as ApplyL>::Out = no_matter; | 924 | let y: <RefMutL<T> as ApplyL>::Out = no_matter; |
926 | y; | 925 | y; |
927 | } //^ ApplyL::Out<T> | 926 | } //^ <T as ApplyL>::Out |
928 | "#, | 927 | "#, |
929 | ); | 928 | ); |
930 | } | 929 | } |
@@ -941,7 +940,7 @@ fn foo<T: ApplyL>(t: T) -> <T as ApplyL>::Out; | |||
941 | fn test<T: ApplyL>(t: T) { | 940 | fn test<T: ApplyL>(t: T) { |
942 | let y = foo(t); | 941 | let y = foo(t); |
943 | y; | 942 | y; |
944 | } //^ ApplyL::Out<T> | 943 | } //^ <T as ApplyL>::Out |
945 | "#, | 944 | "#, |
946 | ); | 945 | ); |
947 | } | 946 | } |
@@ -2120,7 +2119,7 @@ fn unselected_projection_on_impl_self() { | |||
2120 | "#, | 2119 | "#, |
2121 | expect![[r#" | 2120 | expect![[r#" |
2122 | 40..44 'self': &Self | 2121 | 40..44 'self': &Self |
2123 | 46..47 'x': Trait::Item<Self> | 2122 | 46..47 'x': <Self as Trait>::Item |
2124 | 126..130 'self': &S | 2123 | 126..130 'self': &S |
2125 | 132..133 'x': u32 | 2124 | 132..133 'x': u32 |
2126 | 147..161 '{ let y = x; }': () | 2125 | 147..161 '{ let y = x; }': () |
@@ -3151,3 +3150,30 @@ fn test() { | |||
3151 | "#, | 3150 | "#, |
3152 | ); | 3151 | ); |
3153 | } | 3152 | } |
3153 | |||
3154 | #[test] | ||
3155 | fn infer_call_method_return_associated_types_with_generic() { | ||
3156 | check_infer( | ||
3157 | r#" | ||
3158 | pub trait Default { | ||
3159 | fn default() -> Self; | ||
3160 | } | ||
3161 | pub trait Foo { | ||
3162 | type Bar: Default; | ||
3163 | } | ||
3164 | |||
3165 | pub fn quux<T: Foo>() -> T::Bar { | ||
3166 | let y = Default::default(); | ||
3167 | |||
3168 | y | ||
3169 | } | ||
3170 | "#, | ||
3171 | expect![[r#" | ||
3172 | 122..164 '{ ... y }': <T as Foo>::Bar | ||
3173 | 132..133 'y': <T as Foo>::Bar | ||
3174 | 136..152 'Defaul...efault': fn default<<T as Foo>::Bar>() -> <T as Foo>::Bar | ||
3175 | 136..154 'Defaul...ault()': <T as Foo>::Bar | ||
3176 | 161..162 'y': <T as Foo>::Bar | ||
3177 | "#]], | ||
3178 | ); | ||
3179 | } | ||