Skip to content

Commit 6673e51

Browse files
committed
Auto merge of rust-lang#13948 - Veykril:inlay-hints, r=Veykril
Make inlay hint location links work for more types
2 parents ce6955c + 27ba598 commit 6673e51

File tree

7 files changed

+221
-100
lines changed

7 files changed

+221
-100
lines changed

crates/hir-ty/src/display.rs

+108-74
Large diffs are not rendered by default.

crates/hir-ty/src/lower.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ use hir_def::{
3030
ConstScalarOrPath, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef,
3131
},
3232
AdtId, AssocItemId, ConstId, ConstParamId, EnumId, EnumVariantId, FunctionId, GenericDefId,
33-
HasModule, ImplId, ItemContainerId, LocalFieldId, Lookup, StaticId, StructId, TraitId,
34-
TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, VariantId,
33+
HasModule, ImplId, ItemContainerId, LocalFieldId, Lookup, ModuleDefId, StaticId, StructId,
34+
TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, VariantId,
3535
};
3636
use hir_expand::{name::Name, ExpandResult};
3737
use intern::Interned;
@@ -1704,6 +1704,15 @@ pub enum CallableDefId {
17041704
EnumVariantId(EnumVariantId),
17051705
}
17061706
impl_from!(FunctionId, StructId, EnumVariantId for CallableDefId);
1707+
impl From<CallableDefId> for ModuleDefId {
1708+
fn from(def: CallableDefId) -> ModuleDefId {
1709+
match def {
1710+
CallableDefId::FunctionId(f) => ModuleDefId::FunctionId(f),
1711+
CallableDefId::StructId(s) => ModuleDefId::AdtId(AdtId::StructId(s)),
1712+
CallableDefId::EnumVariantId(e) => ModuleDefId::EnumVariantId(e),
1713+
}
1714+
}
1715+
}
17071716

17081717
impl CallableDefId {
17091718
pub fn krate(self, db: &dyn HirDatabase) -> CrateId {

crates/hir/src/display.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ impl HirDisplay for TypeParam {
270270
let has_only_not_sized_bound = predicates.is_empty();
271271
if !has_only_sized_bound || has_only_not_sized_bound {
272272
let default_sized = SizedByDefault::Sized { anchor: krate };
273-
write_bounds_like_dyn_trait_with_prefix(":", &predicates, default_sized, f)?;
273+
write_bounds_like_dyn_trait_with_prefix(f, ":", &predicates, default_sized)?;
274274
}
275275
Ok(())
276276
}

crates/hir/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ pub use {
127127
ExpandResult, HirFileId, InFile, MacroFile, Origin,
128128
},
129129
hir_ty::{
130-
display::{HirDisplay, HirWrite},
130+
display::{HirDisplay, HirDisplayError, HirWrite},
131131
PointerCast, Safety,
132132
},
133133
};

crates/ide/src/inlay_hints.rs

+31-18
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use std::{
44
};
55

66
use either::Either;
7-
use hir::{known, HasVisibility, HirDisplay, HirWrite, ModuleDef, ModuleDefId, Semantics};
7+
use hir::{
8+
known, HasVisibility, HirDisplay, HirDisplayError, HirWrite, ModuleDef, ModuleDefId, Semantics,
9+
};
810
use ide_db::{base_db::FileRange, famous_defs::FamousDefs, RootDatabase};
911
use itertools::Itertools;
1012
use smallvec::{smallvec, SmallVec};
@@ -297,24 +299,35 @@ fn label_of_ty(
297299
mut max_length: Option<usize>,
298300
ty: hir::Type,
299301
label_builder: &mut InlayHintLabelBuilder<'_>,
300-
) {
302+
) -> Result<(), HirDisplayError> {
301303
let iter_item_type = hint_iterator(sema, famous_defs, &ty);
302304
match iter_item_type {
303-
Some(ty) => {
304-
const LABEL_START: &str = "impl Iterator<Item = ";
305+
Some((iter_trait, ty)) => {
306+
const LABEL_START: &str = "impl ";
307+
const LABEL_ITERATOR: &str = "Iterator";
308+
const LABEL_MIDDLE: &str = "<Item = ";
305309
const LABEL_END: &str = ">";
306310

307-
max_length =
308-
max_length.map(|len| len.saturating_sub(LABEL_START.len() + LABEL_END.len()));
309-
310-
label_builder.write_str(LABEL_START).unwrap();
311-
rec(sema, famous_defs, max_length, ty, label_builder);
312-
label_builder.write_str(LABEL_END).unwrap();
313-
}
314-
None => {
315-
let _ = ty.display_truncated(sema.db, max_length).write_to(label_builder);
311+
max_length = max_length.map(|len| {
312+
len.saturating_sub(
313+
LABEL_START.len()
314+
+ LABEL_ITERATOR.len()
315+
+ LABEL_MIDDLE.len()
316+
+ LABEL_END.len(),
317+
)
318+
});
319+
320+
label_builder.write_str(LABEL_START)?;
321+
label_builder.start_location_link(ModuleDef::from(iter_trait).into());
322+
label_builder.write_str(LABEL_ITERATOR)?;
323+
label_builder.end_location_link();
324+
label_builder.write_str(LABEL_MIDDLE)?;
325+
rec(sema, famous_defs, max_length, ty, label_builder)?;
326+
label_builder.write_str(LABEL_END)?;
327+
Ok(())
316328
}
317-
};
329+
None => ty.display_truncated(sema.db, max_length).write_to(label_builder),
330+
}
318331
}
319332

320333
let mut label_builder = InlayHintLabelBuilder {
@@ -324,7 +337,7 @@ fn label_of_ty(
324337
location_link_enabled: config.location_links,
325338
result: InlayHintLabel::default(),
326339
};
327-
rec(sema, famous_defs, config.max_length, ty, &mut label_builder);
340+
let _ = rec(sema, famous_defs, config.max_length, ty, &mut label_builder);
328341
let r = label_builder.finish();
329342
Some(r)
330343
}
@@ -430,12 +443,12 @@ fn hints(
430443
};
431444
}
432445

433-
/// Checks if the type is an Iterator from std::iter and returns its item type.
446+
/// Checks if the type is an Iterator from std::iter and returns the iterator trait and the item type of the concrete iterator.
434447
fn hint_iterator(
435448
sema: &Semantics<'_, RootDatabase>,
436449
famous_defs: &FamousDefs<'_, '_>,
437450
ty: &hir::Type,
438-
) -> Option<hir::Type> {
451+
) -> Option<(hir::Trait, hir::Type)> {
439452
let db = sema.db;
440453
let strukt = ty.strip_references().as_adt()?;
441454
let krate = strukt.module(db).krate();
@@ -458,7 +471,7 @@ fn hint_iterator(
458471
_ => None,
459472
})?;
460473
if let Some(ty) = ty.normalize_trait_assoc_type(db, &[], assoc_type_item) {
461-
return Some(ty);
474+
return Some((iter_trait, ty));
462475
}
463476
}
464477

crates/ide/src/inlay_hints/bind_pat.rs

+27-1
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,33 @@ fn main(a: SliceIter<'_, Container>) {
318318
range: 484..554,
319319
kind: Chaining,
320320
label: [
321-
"impl Iterator<Item = impl Iterator<Item = &&str>>",
321+
"impl ",
322+
InlayHintLabelPart {
323+
text: "Iterator",
324+
linked_location: Some(
325+
FileRange {
326+
file_id: FileId(
327+
1,
328+
),
329+
range: 2248..2256,
330+
},
331+
),
332+
tooltip: "",
333+
},
334+
"<Item = impl ",
335+
InlayHintLabelPart {
336+
text: "Iterator",
337+
linked_location: Some(
338+
FileRange {
339+
file_id: FileId(
340+
1,
341+
),
342+
range: 2248..2256,
343+
},
344+
),
345+
tooltip: "",
346+
},
347+
"<Item = &&str>>",
322348
],
323349
},
324350
InlayHint {

crates/ide/src/inlay_hints/chaining.rs

+42-3
Original file line numberDiff line numberDiff line change
@@ -408,21 +408,60 @@ fn main() {
408408
range: 174..241,
409409
kind: Chaining,
410410
label: [
411-
"impl Iterator<Item = ()>",
411+
"impl ",
412+
InlayHintLabelPart {
413+
text: "Iterator",
414+
linked_location: Some(
415+
FileRange {
416+
file_id: FileId(
417+
1,
418+
),
419+
range: 2248..2256,
420+
},
421+
),
422+
tooltip: "",
423+
},
424+
"<Item = ()>",
412425
],
413426
},
414427
InlayHint {
415428
range: 174..224,
416429
kind: Chaining,
417430
label: [
418-
"impl Iterator<Item = ()>",
431+
"impl ",
432+
InlayHintLabelPart {
433+
text: "Iterator",
434+
linked_location: Some(
435+
FileRange {
436+
file_id: FileId(
437+
1,
438+
),
439+
range: 2248..2256,
440+
},
441+
),
442+
tooltip: "",
443+
},
444+
"<Item = ()>",
419445
],
420446
},
421447
InlayHint {
422448
range: 174..206,
423449
kind: Chaining,
424450
label: [
425-
"impl Iterator<Item = ()>",
451+
"impl ",
452+
InlayHintLabelPart {
453+
text: "Iterator",
454+
linked_location: Some(
455+
FileRange {
456+
file_id: FileId(
457+
1,
458+
),
459+
range: 2248..2256,
460+
},
461+
),
462+
tooltip: "",
463+
},
464+
"<Item = ()>",
426465
],
427466
},
428467
InlayHint {

0 commit comments

Comments
 (0)