Properly use location links for type hints of impl Future and its assoc type

This commit is contained in:
Lukas Wirth 2023-02-07 22:42:03 +01:00
parent 0b32b65ca6
commit 2b4a5374ee
4 changed files with 106 additions and 12 deletions

View File

@ -12,7 +12,7 @@
find_path,
generics::{TypeOrConstParamData, TypeParamProvenance},
item_scope::ItemInNs,
lang_item::LangItem,
lang_item::{LangItem, LangItemTarget},
path::{Path, PathKind},
type_ref::{ConstScalar, TraitBoundModifier, TypeBound, TypeRef},
visibility::Visibility,
@ -731,8 +731,30 @@ fn should_show(
)?;
// FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
}
ImplTraitId::AsyncBlockTypeImplTrait(..) => {
write!(f, "impl Future<Output = ")?;
ImplTraitId::AsyncBlockTypeImplTrait(body, ..) => {
let future_trait = db
.lang_item(body.module(db.upcast()).krate(), LangItem::Future)
.and_then(LangItemTarget::as_trait);
let output = future_trait.and_then(|t| {
db.trait_data(t).associated_type_by_name(&hir_expand::name!(Output))
});
write!(f, "impl ")?;
if let Some(t) = future_trait {
f.start_location_link(t.into());
}
write!(f, "Future")?;
if let Some(_) = future_trait {
f.end_location_link();
}
write!(f, "<")?;
if let Some(t) = output {
f.start_location_link(t.into());
}
write!(f, "Output")?;
if let Some(_) = output {
f.end_location_link();
}
write!(f, " = ")?;
parameters.at(Interner, 0).hir_fmt(f)?;
write!(f, ">")?;
}

View File

@ -294,10 +294,12 @@ fn rec(
) -> Result<(), HirDisplayError> {
let iter_item_type = hint_iterator(sema, famous_defs, &ty);
match iter_item_type {
Some((iter_trait, ty)) => {
Some((iter_trait, item, ty)) => {
const LABEL_START: &str = "impl ";
const LABEL_ITERATOR: &str = "Iterator";
const LABEL_MIDDLE: &str = "<Item = ";
const LABEL_MIDDLE: &str = "<";
const LABEL_ITEM: &str = "Item";
const LABEL_MIDDLE2: &str = " = ";
const LABEL_END: &str = ">";
max_length = max_length.map(|len| {
@ -305,6 +307,7 @@ fn rec(
LABEL_START.len()
+ LABEL_ITERATOR.len()
+ LABEL_MIDDLE.len()
+ LABEL_MIDDLE2.len()
+ LABEL_END.len(),
)
});
@ -314,6 +317,10 @@ fn rec(
label_builder.write_str(LABEL_ITERATOR)?;
label_builder.end_location_link();
label_builder.write_str(LABEL_MIDDLE)?;
label_builder.start_location_link(ModuleDef::from(item).into());
label_builder.write_str(LABEL_ITEM)?;
label_builder.end_location_link();
label_builder.write_str(LABEL_MIDDLE2)?;
rec(sema, famous_defs, max_length, ty, label_builder)?;
label_builder.write_str(LABEL_END)?;
Ok(())
@ -437,7 +444,7 @@ fn hint_iterator(
sema: &Semantics<'_, RootDatabase>,
famous_defs: &FamousDefs<'_, '_>,
ty: &hir::Type,
) -> Option<(hir::Trait, hir::Type)> {
) -> Option<(hir::Trait, hir::TypeAlias, hir::Type)> {
let db = sema.db;
let strukt = ty.strip_references().as_adt()?;
let krate = strukt.module(db).krate();
@ -460,7 +467,7 @@ fn hint_iterator(
_ => None,
})?;
if let Some(ty) = ty.normalize_trait_assoc_type(db, &[], assoc_type_item) {
return Some((iter_trait, ty));
return Some((iter_trait, assoc_type_item, ty));
}
}

View File

@ -330,7 +330,20 @@ fn main(a: SliceIter<'_, Container>) {
),
tooltip: "",
},
"<Item = impl ",
"<",
InlayHintLabelPart {
text: "Item",
linked_location: Some(
FileRange {
file_id: FileId(
1,
),
range: 2643..2647,
},
),
tooltip: "",
},
" = impl ",
InlayHintLabelPart {
text: "Iterator",
linked_location: Some(
@ -343,7 +356,20 @@ fn main(a: SliceIter<'_, Container>) {
),
tooltip: "",
},
"<Item = &&str>>",
"<",
InlayHintLabelPart {
text: "Item",
linked_location: Some(
FileRange {
file_id: FileId(
1,
),
range: 2643..2647,
},
),
tooltip: "",
},
" = &&str>>",
],
},
InlayHint {

View File

@ -440,7 +440,20 @@ fn main() {
),
tooltip: "",
},
"<Item = ()>",
"<",
InlayHintLabelPart {
text: "Item",
linked_location: Some(
FileRange {
file_id: FileId(
1,
),
range: 2643..2647,
},
),
tooltip: "",
},
" = ()>",
],
},
InlayHint {
@ -460,7 +473,20 @@ fn main() {
),
tooltip: "",
},
"<Item = ()>",
"<",
InlayHintLabelPart {
text: "Item",
linked_location: Some(
FileRange {
file_id: FileId(
1,
),
range: 2643..2647,
},
),
tooltip: "",
},
" = ()>",
],
},
InlayHint {
@ -480,7 +506,20 @@ fn main() {
),
tooltip: "",
},
"<Item = ()>",
"<",
InlayHintLabelPart {
text: "Item",
linked_location: Some(
FileRange {
file_id: FileId(
1,
),
range: 2643..2647,
},
),
tooltip: "",
},
" = ()>",
],
},
InlayHint {