aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir_ty/src/display.rs26
-rw-r--r--crates/hir_ty/src/tests/regression.rs8
-rw-r--r--crates/hir_ty/src/tests/traits.rs46
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]
910fn associated_type_placeholder() { 910fn 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#"
914pub trait ApplyL { 913pub trait ApplyL {
@@ -924,7 +923,7 @@ impl<T> ApplyL for RefMutL<T> {
924fn test<T: ApplyL>() { 923fn 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;
941fn test<T: ApplyL>(t: T) { 940fn 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]
3155fn 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}