do not use associated types placeholder for inlay hint

Signed-off-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com>
This commit is contained in:
Benjamin Coenen 2020-10-28 15:09:47 +01:00
parent ef2f7bb243
commit 0aca7b78de
3 changed files with 44 additions and 60 deletions

View file

@ -84,26 +84,17 @@ pub trait HirDisplay {
} }
/// Returns a String representation of `self` for test purposes /// Returns a String representation of `self` for test purposes
fn display_test<'a>( fn display_test<'a>(&'a self, db: &'a dyn HirDatabase) -> HirDisplayWrapper<'a, Self>
&'a self, where
db: &'a dyn HirDatabase, Self: Sized,
module_id: ModuleId, {
) -> Result<String, DisplaySourceCodeError> { HirDisplayWrapper {
let mut result = String::new();
match self.hir_fmt(&mut HirFormatter {
db, db,
fmt: &mut result, t: self,
buf: String::with_capacity(20),
curr_size: 0,
max_size: None, max_size: None,
omit_verbose_types: false, omit_verbose_types: false,
display_target: DisplayTarget::Test { module_id }, display_target: DisplayTarget::Test,
}) { }
Ok(()) => {}
Err(HirDisplayError::FmtError) => panic!("Writing to String can't fail!"),
Err(HirDisplayError::DisplaySourceCodeError(e)) => return Err(e),
};
Ok(result)
} }
} }
@ -158,7 +149,7 @@ enum DisplayTarget {
/// The generated code should compile, so paths need to be qualified. /// The generated code should compile, so paths need to be qualified.
SourceCode { module_id: ModuleId }, SourceCode { module_id: ModuleId },
/// Only for test purpose to keep real types /// Only for test purpose to keep real types
Test { module_id: ModuleId }, Test,
} }
impl DisplayTarget { impl DisplayTarget {
@ -166,7 +157,7 @@ impl DisplayTarget {
matches!(self, Self::SourceCode {..}) matches!(self, Self::SourceCode {..})
} }
fn is_test(&self) -> bool { fn is_test(&self) -> bool {
matches!(self, Self::Test {..}) matches!(self, Self::Test)
} }
} }
@ -348,7 +339,7 @@ impl HirDisplay for ApplicationTy {
} }
TypeCtor::Adt(def_id) => { TypeCtor::Adt(def_id) => {
match f.display_target { match f.display_target {
DisplayTarget::Diagnostics => { DisplayTarget::Diagnostics | DisplayTarget::Test => {
let name = match def_id { let name = match def_id {
AdtId::StructId(it) => f.db.struct_data(it).name.clone(), AdtId::StructId(it) => f.db.struct_data(it).name.clone(),
AdtId::UnionId(it) => f.db.union_data(it).name.clone(), AdtId::UnionId(it) => f.db.union_data(it).name.clone(),
@ -356,7 +347,7 @@ impl HirDisplay for ApplicationTy {
}; };
write!(f, "{}", name)?; write!(f, "{}", name)?;
} }
DisplayTarget::SourceCode { module_id } | DisplayTarget::Test { module_id } => { DisplayTarget::SourceCode { module_id } => {
if let Some(path) = find_path::find_path( if let Some(path) = find_path::find_path(
f.db.upcast(), f.db.upcast(),
ItemInNs::Types(def_id.into()), ItemInNs::Types(def_id.into()),
@ -417,28 +408,23 @@ impl HirDisplay for ApplicationTy {
_ => panic!("not an associated type"), _ => panic!("not an associated type"),
}; };
let trait_ = f.db.trait_data(trait_); let trait_ = f.db.trait_data(trait_);
let type_alias = f.db.type_alias_data(type_alias); let type_alias_data = f.db.type_alias_data(type_alias);
// Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) // 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 { if f.display_target.is_test() {
write!(f, "{}::{}", trait_.name, type_alias.name)?; write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
if self.parameters.len() > 0 { if self.parameters.len() > 0 {
write!(f, "<")?; write!(f, "<")?;
f.write_joined(&*self.parameters.0, ", ")?; f.write_joined(&*self.parameters.0, ", ")?;
write!(f, ">")?; write!(f, ">")?;
} }
} else { } else {
if self.parameters.len() == 1 { let projection_ty = ProjectionTy {
write!( associated_ty: type_alias,
f, parameters: self.parameters.clone(),
"<{} as {}>::{}", };
self.parameters.as_single().display(f.db),
trait_.name, projection_ty.hir_fmt(f)?;
type_alias.name
)?;
} else {
write!(f, "{}::{}", trait_.name, type_alias.name)?;
}
} }
} }
TypeCtor::ForeignType(type_alias) => { TypeCtor::ForeignType(type_alias) => {

View file

@ -157,14 +157,13 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
(node.value.text_range(), node.value.text().to_string().replace("\n", " ")) (node.value.text_range(), node.value.text().to_string().replace("\n", " "))
}; };
let macro_prefix = if node.file_id != file_id.into() { "!" } else { "" }; 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!( format_to!(
buf, buf,
"{}{:?} '{}': {}\n", "{}{:?} '{}': {}\n",
macro_prefix, macro_prefix,
range, range,
ellipsize(text, 15), ellipsize(text, 15),
ty.display_test(&db, module).unwrap() ty.display_test(&db)
); );
} }
if include_mismatches { if include_mismatches {
@ -175,14 +174,13 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
for (src_ptr, mismatch) in &mismatches { for (src_ptr, mismatch) in &mismatches {
let range = src_ptr.value.text_range(); let range = src_ptr.value.text_range();
let macro_prefix = if src_ptr.file_id != file_id.into() { "!" } else { "" }; 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!( format_to!(
buf, buf,
"{}{:?}: expected {}, got {}\n", "{}{:?}: expected {}, got {}\n",
macro_prefix, macro_prefix,
range, range,
mismatch.expected.display_test(&db, module).unwrap(), mismatch.expected.display_test(&db),
mismatch.actual.display_test(&db, module).unwrap(), mismatch.actual.display_test(&db),
); );
} }
} }

View file

@ -108,16 +108,16 @@ fn infer_associated_method_with_modules() {
check_infer( check_infer(
r#" r#"
mod a { mod a {
pub struct A; struct A;
impl A { pub fn thing() -> A { A {} }} impl A { pub fn thing() -> A { A {} }}
} }
mod b { mod b {
pub struct B; struct B;
impl B { pub fn thing() -> u32 { 99 }} impl B { pub fn thing() -> u32 { 99 }}
pub mod c { mod c {
pub struct C; struct C;
impl C { pub fn thing() -> C { C {} }} impl C { pub fn thing() -> C { C {} }}
} }
} }
@ -130,22 +130,22 @@ fn infer_associated_method_with_modules() {
} }
"#, "#,
expect![[r#" expect![[r#"
59..67 '{ A {} }': a::A 55..63 '{ A {} }': A
61..65 'A {}': a::A 57..61 'A {}': A
133..139 '{ 99 }': u32 125..131 '{ 99 }': u32
135..137 '99': u32 127..129 '99': u32
217..225 '{ C {} }': c::C 201..209 '{ C {} }': C
219..223 'C {}': c::C 203..207 'C {}': C
256..340 '{ ...g(); }': () 240..324 '{ ...g(); }': ()
266..267 'x': a::A 250..251 'x': A
270..281 'a::A::thing': fn thing() -> A 254..265 'a::A::thing': fn thing() -> A
270..283 'a::A::thing()': a::A 254..267 'a::A::thing()': A
293..294 'y': u32 277..278 'y': u32
297..308 'b::B::thing': fn thing() -> u32 281..292 'b::B::thing': fn thing() -> u32
297..310 'b::B::thing()': u32 281..294 'b::B::thing()': u32
320..321 'z': c::C 304..305 'z': C
324..335 'c::C::thing': fn thing() -> C 308..319 'c::C::thing': fn thing() -> C
324..337 'c::C::thing()': c::C 308..321 'c::C::thing()': C
"#]], "#]],
); );
} }