Skip to content

feat: show full type in tooltips for hints #19640

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 58 additions & 15 deletions crates/hir-ty/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ use crate::{
pub trait HirWrite: fmt::Write {
fn start_location_link(&mut self, _location: ModuleDefId) {}
fn end_location_link(&mut self) {}
fn start_truncated(&mut self) {}
fn end_truncated(&mut self) {}
}

// String will ignore link metadata
Expand Down Expand Up @@ -356,19 +358,26 @@ impl HirFormatter<'_> {
sep: &str,
) -> Result<(), HirDisplayError> {
let mut first = true;
let mut truncated = false;
for e in iter {
if !first {
write!(self, "{sep}")?;
}
first = false;

// Abbreviate multiple omitted types with a single ellipsis.
if self.should_truncate() {
return write!(self, "{TYPE_HINT_TRUNCATION}");
if !truncated && self.should_truncate() {
truncated = true;
self.fmt.start_truncated();
}

e.hir_fmt(self)?;
}

if truncated {
self.fmt.end_truncated();
}

Ok(())
}

Expand Down Expand Up @@ -556,9 +565,11 @@ impl<T: HirDisplay + Internable> HirDisplay for Interned<T> {

impl HirDisplay for ProjectionTy {
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
if f.should_truncate() {
return write!(f, "{TYPE_HINT_TRUNCATION}");
let truncated = f.should_truncate();
if truncated {
f.fmt.start_truncated();
}

let trait_ref = self.trait_ref(f.db);
let self_ty = trait_ref.self_type_parameter(Interner);

Expand Down Expand Up @@ -624,17 +635,30 @@ impl HirDisplay for ProjectionTy {
let proj_params_count =
self.substitution.len(Interner) - trait_ref.substitution.len(Interner);
let proj_params = &self.substitution.as_slice(Interner)[..proj_params_count];
hir_fmt_generics(f, proj_params, None, None)
hir_fmt_generics(f, proj_params, None, None)?;

if truncated {
f.fmt.end_truncated();
}

Ok(())
}
}

impl HirDisplay for OpaqueTy {
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
if f.should_truncate() {
return write!(f, "{TYPE_HINT_TRUNCATION}");
let truncated = f.should_truncate();
if truncated {
f.fmt.start_truncated();
}

self.substitution.at(Interner, 0).hir_fmt(f)?;

if truncated {
f.fmt.end_truncated();
}

self.substitution.at(Interner, 0).hir_fmt(f)
Ok(())
}
}

Expand Down Expand Up @@ -997,8 +1021,9 @@ impl HirDisplay for Ty {
&self,
f @ &mut HirFormatter { db, .. }: &mut HirFormatter<'_>,
) -> Result<(), HirDisplayError> {
if f.should_truncate() {
return write!(f, "{TYPE_HINT_TRUNCATION}");
let truncated = f.should_truncate();
if truncated {
f.fmt.start_truncated();
}

match self.kind(Interner) {
Expand Down Expand Up @@ -1408,11 +1433,18 @@ impl HirDisplay for Ty {
_ => unreachable!(),
}
if sig.params().is_empty() {
} else if f.should_truncate() {
write!(f, "{TYPE_HINT_TRUNCATION}")?;
} else {
let truncated = f.should_truncate();
if truncated {
f.fmt.start_truncated();
}

f.write_joined(sig.params(), ", ")?;
};

if truncated {
f.fmt.end_truncated();
}
}
match f.closure_style {
ClosureStyle::ImplFn => write!(f, ")")?,
ClosureStyle::RANotation => write!(f, "|")?,
Expand Down Expand Up @@ -1576,6 +1608,11 @@ impl HirDisplay for Ty {
}
TyKind::CoroutineWitness(..) => write!(f, "{{coroutine witness}}")?,
}

if truncated {
f.fmt.end_truncated();
}

Ok(())
}
}
Expand Down Expand Up @@ -1929,8 +1966,9 @@ impl HirDisplay for TraitRef {

impl HirDisplay for WhereClause {
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
if f.should_truncate() {
return write!(f, "{TYPE_HINT_TRUNCATION}");
let truncated = f.should_truncate();
if truncated {
f.fmt.start_truncated();
}

match self {
Expand Down Expand Up @@ -1963,6 +2001,11 @@ impl HirDisplay for WhereClause {
WhereClause::TypeOutlives(..) => {}
WhereClause::LifetimeOutlives(..) => {}
}

if truncated {
f.fmt.end_truncated();
}

Ok(())
}
}
Expand Down
24 changes: 23 additions & 1 deletion crates/ide/src/inlay_hints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,7 @@ struct InlayHintLabelBuilder<'a> {
last_part: String,
resolve: bool,
location: Option<LazyProperty<FileRange>>,
tooltip: Option<LazyProperty<InlayTooltip>>,
}

impl fmt::Write for InlayHintLabelBuilder<'_> {
Expand All @@ -673,6 +674,7 @@ impl fmt::Write for InlayHintLabelBuilder<'_> {
impl HirWrite for InlayHintLabelBuilder<'_> {
fn start_location_link(&mut self, def: ModuleDefId) {
never!(self.location.is_some(), "location link is already started");
never!(self.tooltip.is_some(), "tooltip is already started");
self.make_new_part();

self.location = Some(if self.resolve {
Expand All @@ -689,6 +691,25 @@ impl HirWrite for InlayHintLabelBuilder<'_> {
fn end_location_link(&mut self) {
self.make_new_part();
}

fn start_truncated(&mut self) {
never!(self.location.is_some(), "location link is already started");
never!(self.tooltip.is_some(), "tooltip is already started");
self.make_new_part();
}

fn end_truncated(&mut self) {
self.tooltip = Some(if self.resolve {
self.last_part = "…".to_owned();
LazyProperty::Lazy
} else {
// TODO: tricky
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is tricky here, swapping the buffer out seems correct to me?

let tooltip = mem::replace(&mut self.last_part, "…".to_owned());
LazyProperty::Computed(InlayTooltip::String(tooltip))
});

self.make_new_part();
}
}

impl InlayHintLabelBuilder<'_> {
Expand All @@ -698,7 +719,7 @@ impl InlayHintLabelBuilder<'_> {
self.result.parts.push(InlayHintLabelPart {
text,
linked_location: self.location.take(),
tooltip: None,
tooltip: self.tooltip.take(),
});
}
}
Expand Down Expand Up @@ -768,6 +789,7 @@ fn label_of_ty(
db: sema.db,
last_part: String::new(),
location: None,
tooltip: None,
result: InlayHintLabel::default(),
resolve: config.fields_to_resolve.resolve_label_location,
};
Expand Down