From ef2f7bb2438e66fd046791bb67849b6c61d946ab Mon Sep 17 00:00:00 2001 From: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com> Date: Wed, 28 Oct 2020 12:29:42 +0100 Subject: do not use associated types placeholder for inlay hint Signed-off-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com> --- crates/hir_ty/src/display.rs | 104 +++++++++++++-------------- crates/hir_ty/src/tests.rs | 8 ++- crates/hir_ty/src/tests/method_resolution.rs | 40 +++++------ crates/hir_ty/src/tests/regression.rs | 8 +-- crates/hir_ty/src/tests/traits.rs | 82 +++------------------ crates/ide/src/inlay_hints.rs | 21 ++++++ 6 files changed, 108 insertions(+), 155 deletions(-) diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index f1232a72f..ddfd8c8af 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs @@ -74,9 +74,29 @@ pub trait HirDisplay { curr_size: 0, max_size: None, omit_verbose_types: false, - #[cfg(not(test))] display_target: DisplayTarget::SourceCode { module_id }, - #[cfg(test)] + }) { + Ok(()) => {} + Err(HirDisplayError::FmtError) => panic!("Writing to String can't fail!"), + Err(HirDisplayError::DisplaySourceCodeError(e)) => return Err(e), + }; + Ok(result) + } + + /// Returns a String representation of `self` for test purposes + fn display_test<'a>( + &'a self, + db: &'a dyn HirDatabase, + module_id: ModuleId, + ) -> Result { + let mut result = String::new(); + match self.hir_fmt(&mut HirFormatter { + db, + fmt: &mut result, + buf: String::with_capacity(20), + curr_size: 0, + max_size: None, + omit_verbose_types: false, display_target: DisplayTarget::Test { module_id }, }) { Ok(()) => {} @@ -138,7 +158,6 @@ enum DisplayTarget { /// The generated code should compile, so paths need to be qualified. SourceCode { module_id: ModuleId }, /// Only for test purpose to keep real types - #[cfg(test)] Test { module_id: ModuleId }, } @@ -147,14 +166,7 @@ impl DisplayTarget { matches!(self, Self::SourceCode {..}) } fn is_test(&self) -> bool { - #[cfg(test)] - { - matches!(self, Self::Test {..}) - } - #[cfg(not(test))] - { - false - } + matches!(self, Self::Test {..}) } } @@ -344,21 +356,7 @@ impl HirDisplay for ApplicationTy { }; write!(f, "{}", name)?; } - DisplayTarget::SourceCode { module_id } => { - if let Some(path) = find_path::find_path( - f.db.upcast(), - ItemInNs::Types(def_id.into()), - module_id, - ) { - write!(f, "{}", path)?; - } else { - return Err(HirDisplayError::DisplaySourceCodeError( - DisplaySourceCodeError::PathNotFound, - )); - } - } - #[cfg(test)] - DisplayTarget::Test { module_id } => { + DisplayTarget::SourceCode { module_id } | DisplayTarget::Test { module_id } => { if let Some(path) = find_path::find_path( f.db.upcast(), ItemInNs::Types(def_id.into()), @@ -374,40 +372,38 @@ impl HirDisplay for ApplicationTy { } if self.parameters.len() > 0 { - let parameters_to_write = if f.display_target.is_source_code() - || f.display_target.is_test() - || f.omit_verbose_types() - { - match self - .ctor - .as_generic_def() - .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) - .filter(|defaults| !defaults.is_empty()) - { - None => self.parameters.0.as_ref(), - Some(default_parameters) => { - let mut default_from = 0; - for (i, parameter) in self.parameters.iter().enumerate() { - match (parameter, default_parameters.get(i)) { - (&Ty::Unknown, _) | (_, None) => { - default_from = i + 1; - } - (_, Some(default_parameter)) => { - let actual_default = default_parameter - .clone() - .subst(&self.parameters.prefix(i)); - if parameter != &actual_default { + let parameters_to_write = + if f.display_target.is_source_code() || f.omit_verbose_types() { + match self + .ctor + .as_generic_def() + .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) + .filter(|defaults| !defaults.is_empty()) + { + None => self.parameters.0.as_ref(), + Some(default_parameters) => { + let mut default_from = 0; + for (i, parameter) in self.parameters.iter().enumerate() { + match (parameter, default_parameters.get(i)) { + (&Ty::Unknown, _) | (_, None) => { default_from = i + 1; } + (_, Some(default_parameter)) => { + let actual_default = default_parameter + .clone() + .subst(&self.parameters.prefix(i)); + if parameter != &actual_default { + default_from = i + 1; + } + } } } + &self.parameters.0[0..default_from] } - &self.parameters.0[0..default_from] } - } - } else { - self.parameters.0.as_ref() - }; + } else { + self.parameters.0.as_ref() + }; if !parameters_to_write.is_empty() { write!(f, "<")?; f.write_joined(parameters_to_write, ", ")?; diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs index 0445efc9e..510baadf2 100644 --- a/crates/hir_ty/src/tests.rs +++ b/crates/hir_ty/src/tests.rs @@ -157,13 +157,14 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { (node.value.text_range(), node.value.text().to_string().replace("\n", " ")) }; let macro_prefix = if node.file_id != file_id.into() { "!" } else { "" }; + let module = db.module_for_file(node.file_id.original_file(&db)); format_to!( buf, "{}{:?} '{}': {}\n", macro_prefix, range, ellipsize(text, 15), - ty.display(&db) + ty.display_test(&db, module).unwrap() ); } if include_mismatches { @@ -174,13 +175,14 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String { for (src_ptr, mismatch) in &mismatches { let range = src_ptr.value.text_range(); let macro_prefix = if src_ptr.file_id != file_id.into() { "!" } else { "" }; + let module = db.module_for_file(src_ptr.file_id.original_file(&db)); format_to!( buf, "{}{:?}: expected {}, got {}\n", macro_prefix, range, - mismatch.expected.display(&db), - mismatch.actual.display(&db), + mismatch.expected.display_test(&db, module).unwrap(), + mismatch.actual.display_test(&db, module).unwrap(), ); } } diff --git a/crates/hir_ty/src/tests/method_resolution.rs b/crates/hir_ty/src/tests/method_resolution.rs index 0f17ff151..596d4f182 100644 --- a/crates/hir_ty/src/tests/method_resolution.rs +++ b/crates/hir_ty/src/tests/method_resolution.rs @@ -108,16 +108,16 @@ fn infer_associated_method_with_modules() { check_infer( r#" mod a { - struct A; + pub struct A; impl A { pub fn thing() -> A { A {} }} } mod b { - struct B; + pub struct B; impl B { pub fn thing() -> u32 { 99 }} - mod c { - struct C; + pub mod c { + pub struct C; impl C { pub fn thing() -> C { C {} }} } } @@ -130,22 +130,22 @@ fn infer_associated_method_with_modules() { } "#, expect![[r#" - 55..63 '{ A {} }': A - 57..61 'A {}': A - 125..131 '{ 99 }': u32 - 127..129 '99': u32 - 201..209 '{ C {} }': C - 203..207 'C {}': C - 240..324 '{ ...g(); }': () - 250..251 'x': A - 254..265 'a::A::thing': fn thing() -> A - 254..267 'a::A::thing()': A - 277..278 'y': u32 - 281..292 'b::B::thing': fn thing() -> u32 - 281..294 'b::B::thing()': u32 - 304..305 'z': C - 308..319 'c::C::thing': fn thing() -> C - 308..321 'c::C::thing()': C + 59..67 '{ A {} }': a::A + 61..65 'A {}': a::A + 133..139 '{ 99 }': u32 + 135..137 '99': u32 + 217..225 '{ C {} }': c::C + 219..223 'C {}': c::C + 256..340 '{ ...g(); }': () + 266..267 'x': a::A + 270..281 'a::A::thing': fn thing() -> A + 270..283 'a::A::thing()': a::A + 293..294 'y': u32 + 297..308 'b::B::thing': fn thing() -> u32 + 297..310 'b::B::thing()': u32 + 320..321 'z': c::C + 324..335 'c::C::thing': fn thing() -> C + 324..337 'c::C::thing()': c::C "#]], ); } diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs index 66e171f24..42d08f12c 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>> 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> + 401..404 'vec': Vec f64>>>> + 407..416 'from_iter': fn from_iter f64>>>, Repeat f64>>>(Repeat f64>>) -> Vec< f64>> as IntoIterator>::Item> + 407..424 'from_i...epeat)': Vec f64>>>> 417..423 'repeat': Repeat f64>> - 431..434 'vec': Vec< f64>> as IntoIterator>::Item> + 431..434 'vec': Vec f64>>>> 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 e98d7c064..4d193dea9 100644 --- a/crates/hir_ty/src/tests/traits.rs +++ b/crates/hir_ty/src/tests/traits.rs @@ -1,7 +1,7 @@ use expect_test::expect; use test_utils::mark; -use super::{check_infer, check_infer_with_mismatches, check_types, check_types_source_code}; +use super::{check_infer, check_infer_with_mismatches, check_types}; #[test] fn infer_await() { @@ -384,12 +384,12 @@ fn infer_project_associated_type() { 108..261 '{ ...ter; }': () 118..119 'x': u32 145..146 '1': u32 - 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 + 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 "#]], ); } @@ -945,45 +945,6 @@ fn test(t: T) { ); } -#[test] -fn associated_type_placeholder() { - check_types_source_code( - r#" -pub trait ApplyL { - type Out; -} - -pub struct RefMutL; - -impl ApplyL for RefMutL { - type Out = ::Out; -} - -fn test() { - let y: as ApplyL>::Out = no_matter; - y; -} //^ ApplyL::Out -"#, - ); -} - -#[test] -fn associated_type_placeholder_2() { - check_types_source_code( - r#" -pub trait ApplyL { - type Out; -} -fn foo(t: T) -> ::Out; - -fn test(t: T) { - let y = foo(t); - y; -} //^ ApplyL::Out -"#, - ); -} - #[test] fn argument_impl_trait() { check_infer_with_mismatches( @@ -2158,7 +2119,7 @@ fn unselected_projection_on_impl_self() { "#, expect![[r#" 40..44 'self': &Self - 46..47 'x': ::Item + 46..47 'x': Trait::Item 126..130 'self': &S 132..133 'x': u32 147..161 '{ let y = x; }': () @@ -3189,30 +3150,3 @@ 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 - "#]], - ); -} diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 49d8e4ae1..adb93efd7 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -1235,4 +1235,25 @@ fn main() { "#, ); } + + #[test] + fn infer_call_method_return_associated_types_with_generic() { + check( + r#" + pub trait Default { + fn default() -> Self; + } + pub trait Foo { + type Bar: Default; + } + + pub fn quux() -> T::Bar { + let y = Default::default(); + //^ ::Bar + + y + } + "#, + ); + } } -- cgit v1.2.3