6387: do not use associated types placeholder for inlay hint  r=flodiebold a=bnjjj


close #6191

Co-authored-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com>
This commit is contained in:
bors[bot] 2020-10-28 14:54:00 +00:00 committed by GitHub
commit e34183218c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 72 additions and 13 deletions

View File

@ -82,6 +82,20 @@ pub trait HirDisplay {
};
Ok(result)
}
/// Returns a String representation of `self` for test purposes
fn display_test<'a>(&'a self, db: &'a dyn HirDatabase) -> HirDisplayWrapper<'a, Self>
where
Self: Sized,
{
HirDisplayWrapper {
db,
t: self,
max_size: None,
omit_verbose_types: false,
display_target: DisplayTarget::Test,
}
}
}
impl<'a> HirFormatter<'a> {
@ -134,12 +148,17 @@ 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
Test,
}
impl DisplayTarget {
fn is_source_code(&self) -> bool {
matches!(self, Self::SourceCode {..})
}
fn is_test(&self) -> bool {
matches!(self, Self::Test)
}
}
#[derive(Debug)]
@ -313,14 +332,18 @@ impl HirDisplay for ApplicationTy {
let ret_display = if f.omit_verbose_types() {
ret.display_truncated(f.db, f.max_size)
} else {
ret.display(f.db)
if f.display_target.is_test() {
ret.display_test(f.db)
} else {
ret.display(f.db)
}
};
write!(f, " -> {}", ret_display)?;
}
}
TypeCtor::Adt(def_id) => {
match f.display_target {
DisplayTarget::Diagnostics => {
DisplayTarget::Diagnostics | DisplayTarget::Test => {
let name = match def_id {
AdtId::StructId(it) => f.db.struct_data(it).name.clone(),
AdtId::UnionId(it) => f.db.union_data(it).name.clone(),
@ -389,12 +412,23 @@ impl HirDisplay for ApplicationTy {
_ => panic!("not an associated type"),
};
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, ">")?;
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)
if f.display_target.is_test() {
write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
if self.parameters.len() > 0 {
write!(f, "<")?;
f.write_joined(&*self.parameters.0, ", ")?;
write!(f, ">")?;
}
} else {
let projection_ty = ProjectionTy {
associated_ty: type_alias,
parameters: self.parameters.clone(),
};
projection_ty.hir_fmt(f)?;
}
}
TypeCtor::ForeignType(type_alias) => {
@ -442,7 +476,11 @@ impl HirDisplay for ApplicationTy {
let ret_display = if f.omit_verbose_types() {
sig.ret().display_truncated(f.db, f.max_size)
} else {
sig.ret().display(f.db)
if f.display_target.is_test() {
sig.ret().display_test(f.db)
} else {
sig.ret().display(f.db)
}
};
write!(f, " -> {}", ret_display)?;
} else {

View File

@ -74,7 +74,7 @@ fn check_types_impl(ra_fixture: &str, display_source: bool) {
let module = db.module_for_file(file_id);
ty.display_source_code(&db, module).unwrap()
} else {
ty.display(&db).to_string()
ty.display_test(&db).to_string()
};
assert_eq!(expected, actual);
checked_one = true;
@ -163,7 +163,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
macro_prefix,
range,
ellipsize(text, 15),
ty.display(&db)
ty.display_test(&db)
);
}
if include_mismatches {
@ -179,8 +179,8 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
"{}{:?}: expected {}, got {}\n",
macro_prefix,
range,
mismatch.expected.display(&db),
mismatch.actual.display(&db),
mismatch.expected.display_test(&db),
mismatch.actual.display_test(&db),
);
}
}

View File

@ -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: Foo>() -> T::Bar {
let y = Default::default();
//^ <T as Foo>::Bar
y
}
"#,
);
}
}