From 73161cc9cdcdf7b9f797d7984f2cad497a3f4553 Mon Sep 17 00:00:00 2001 From: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com> Date: Tue, 27 Oct 2020 20:23:09 +0100 Subject: do not use associated types placeholder for inlay hint #6191 Signed-off-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com> --- crates/hir_ty/src/display.rs | 26 ++++++++++++++++---- crates/hir_ty/src/tests/regression.rs | 8 +++--- crates/hir_ty/src/tests/traits.rs | 46 +++++++++++++++++++++++++++-------- 3 files changed, 61 insertions(+), 19 deletions(-) (limited to 'crates/hir_ty') 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 { }; let trait_ = f.db.trait_data(trait_); let type_alias = f.db.type_alias_data(type_alias); - write!(f, "{}::{}", trait_.name, type_alias.name)?; - if self.parameters.len() > 0 { - write!(f, "<")?; - f.write_joined(&*self.parameters.0, ", ")?; - write!(f, ">")?; + + // Use placeholder associated types when the target is source code (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) + if f.display_target.is_source_code() || self.parameters.len() > 1 { + write!(f, "{}::{}", trait_.name, type_alias.name)?; + if self.parameters.len() > 0 { + write!(f, "<")?; + f.write_joined(&*self.parameters.0, ", ")?; + write!(f, ">")?; + } + } else { + if self.parameters.len() == 1 { + write!( + f, + "<{} as {}>::{}", + self.parameters.as_single().display(f.db), + trait_.name, + type_alias.name + )?; + } else { + write!(f, "{}::{}", trait_.name, type_alias.name)?; + } } } 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() { 356..362 'repeat': Repeat f64>> 365..390 'Repeat...nner }': Repeat f64>> 383..388 'inner': Map<|&f64| -> f64> - 401..404 'vec': Vec f64>>>> - 407..416 'from_iter': fn from_iter f64>>>, Repeat f64>>>(Repeat f64>>) -> Vec f64>>>> - 407..424 'from_i...epeat)': Vec f64>>>> + 401..404 'vec': Vec< f64>> as IntoIterator>::Item> + 407..416 'from_iter': fn from_iter< f64>> as IntoIterator>::Item, Repeat f64>>>(Repeat f64>>) -> Vec< f64>> as IntoIterator>::Item> + 407..424 'from_i...epeat)': Vec< f64>> as IntoIterator>::Item> 417..423 'repeat': Repeat f64>> - 431..434 'vec': Vec f64>>>> + 431..434 'vec': Vec< f64>> as IntoIterator>::Item> 431..444 'vec.foo_bar()': {unknown} "#]], ); 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() { 108..261 '{ ...ter; }': () 118..119 'x': u32 145..146 '1': u32 - 156..157 'y': Iterable::Item - 183..192 'no_matter': Iterable::Item - 202..203 'z': Iterable::Item - 215..224 'no_matter': Iterable::Item - 234..235 'a': Iterable::Item - 249..258 'no_matter': Iterable::Item + 156..157 'y': ::Item + 183..192 'no_matter': ::Item + 202..203 'z': ::Item + 215..224 'no_matter': ::Item + 234..235 'a': ::Item + 249..258 'no_matter': ::Item "#]], ); } @@ -908,7 +908,6 @@ fn test(t: T) { (*t); } #[test] fn associated_type_placeholder() { - // inside the generic function, the associated type gets normalized to a placeholder `ApplL::Out` [https://rust-lang.github.io/rustc-guide/traits/associated-types.html#placeholder-associated-types]. check_types( r#" pub trait ApplyL { @@ -924,7 +923,7 @@ impl ApplyL for RefMutL { fn test() { let y: as ApplyL>::Out = no_matter; y; -} //^ ApplyL::Out +} //^ ::Out "#, ); } @@ -941,7 +940,7 @@ fn foo(t: T) -> ::Out; fn test(t: T) { let y = foo(t); y; -} //^ ApplyL::Out +} //^ ::Out "#, ); } @@ -2120,7 +2119,7 @@ fn unselected_projection_on_impl_self() { "#, expect![[r#" 40..44 'self': &Self - 46..47 'x': Trait::Item + 46..47 'x': ::Item 126..130 'self': &S 132..133 'x': u32 147..161 '{ let y = x; }': () @@ -3151,3 +3150,30 @@ fn test() { "#, ); } + +#[test] +fn infer_call_method_return_associated_types_with_generic() { + check_infer( + r#" + pub trait Default { + fn default() -> Self; + } + pub trait Foo { + type Bar: Default; + } + + pub fn quux() -> T::Bar { + let y = Default::default(); + + y + } + "#, + expect![[r#" + 122..164 '{ ... y }': ::Bar + 132..133 'y': ::Bar + 136..152 'Defaul...efault': fn default<::Bar>() -> ::Bar + 136..154 'Defaul...ault()': ::Bar + 161..162 'y': ::Bar + "#]], + ); +} -- cgit v1.2.3