From 8762b797fd37e9a9cab3e5fe534a9672f30e6022 Mon Sep 17 00:00:00 2001 From: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com> Date: Wed, 28 Oct 2020 11:20:05 +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 | 88 ++++++++++++++++++++++++++------------- crates/hir_ty/src/tests/traits.rs | 45 ++++++++++++++++++-- 2 files changed, 102 insertions(+), 31 deletions(-) diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 43db24882..f1232a72f 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs @@ -74,7 +74,10 @@ pub trait HirDisplay { curr_size: 0, max_size: None, omit_verbose_types: false, + #[cfg(not(test))] display_target: DisplayTarget::SourceCode { module_id }, + #[cfg(test)] + display_target: DisplayTarget::Test { module_id }, }) { Ok(()) => {} Err(HirDisplayError::FmtError) => panic!("Writing to String can't fail!"), @@ -134,12 +137,25 @@ enum DisplayTarget { /// Display types for inserting them in source files. /// 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 }, } impl DisplayTarget { fn is_source_code(&self) -> bool { matches!(self, Self::SourceCode {..}) } + fn is_test(&self) -> bool { + #[cfg(test)] + { + matches!(self, Self::Test {..}) + } + #[cfg(not(test))] + { + false + } + } } #[derive(Debug)] @@ -341,41 +357,57 @@ impl HirDisplay for ApplicationTy { )); } } + #[cfg(test)] + DisplayTarget::Test { 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, + )); + } + } } if self.parameters.len() > 0 { - 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) => { + 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 { 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, ", ")?; @@ -391,8 +423,8 @@ impl HirDisplay for ApplicationTy { let trait_ = f.db.trait_data(trait_); let type_alias = f.db.type_alias_data(type_alias); - // 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 { + // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) + if f.display_target.is_test() || self.parameters.len() > 1 { write!(f, "{}::{}", trait_.name, type_alias.name)?; if self.parameters.len() > 0 { write!(f, "<")?; diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs index 7ad8b5830..e98d7c064 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}; +use super::{check_infer, check_infer_with_mismatches, check_types, check_types_source_code}; #[test] fn infer_await() { @@ -907,7 +907,7 @@ fn test(t: T) { (*t); } } #[test] -fn associated_type_placeholder() { +fn associated_type_inlay_hints() { check_types( r#" pub trait ApplyL { @@ -929,7 +929,7 @@ fn test() { } #[test] -fn associated_type_placeholder_2() { +fn associated_type_inlay_hints_2() { check_types( r#" pub trait ApplyL { @@ -945,6 +945,45 @@ 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( -- cgit v1.2.3