Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/inlay_hints.rs')
-rw-r--r--crates/ide/src/inlay_hints.rs127
1 files changed, 73 insertions, 54 deletions
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 21550d5e66..06ae0b1d73 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -40,6 +40,7 @@ mod implicit_static;
mod implied_dyn_trait;
mod lifetime;
mod param_name;
+mod placeholders;
mod ra_fixture;
mod range_exclusive;
@@ -88,9 +89,7 @@ pub(crate) fn inlay_hints(
) -> Vec<InlayHint> {
let _p = tracing::info_span!("inlay_hints").entered();
let sema = Semantics::new(db);
- let file_id = sema
- .attach_first_edition(file_id)
- .unwrap_or_else(|| EditionedFileId::current_edition(db, file_id));
+ let file_id = sema.attach_first_edition(file_id);
let file = sema.parse(file_id);
let file = file.syntax();
@@ -109,16 +108,14 @@ pub(crate) fn inlay_hints(
}
};
let mut preorder = file.preorder();
- hir::attach_db(sema.db, || {
- while let Some(event) = preorder.next() {
- if matches!((&event, range_limit), (WalkEvent::Enter(node), Some(range)) if range.intersect(node.text_range()).is_none())
- {
- preorder.skip_subtree();
- continue;
- }
- hints(event);
+ while let Some(event) = preorder.next() {
+ if matches!((&event, range_limit), (WalkEvent::Enter(node), Some(range)) if range.intersect(node.text_range()).is_none())
+ {
+ preorder.skip_subtree();
+ continue;
}
- });
+ hints(event);
+ }
if let Some(range_limit) = range_limit {
acc.retain(|hint| range_limit.contains_range(hint.range));
}
@@ -141,9 +138,7 @@ pub(crate) fn inlay_hints_resolve(
) -> Option<InlayHint> {
let _p = tracing::info_span!("inlay_hints_resolve").entered();
let sema = Semantics::new(db);
- let file_id = sema
- .attach_first_edition(file_id)
- .unwrap_or_else(|| EditionedFileId::current_edition(db, file_id));
+ let file_id = sema.attach_first_edition(file_id);
let file = sema.parse(file_id);
let file = file.syntax();
@@ -291,6 +286,10 @@ fn hints(
implied_dyn_trait::hints(hints, famous_defs, config, Either::Right(dyn_));
Some(())
},
+ ast::Type::InferType(placeholder) => {
+ placeholders::type_hints(hints, famous_defs, config, display_target, placeholder);
+ Some(())
+ },
_ => Some(()),
},
ast::GenericParamList(it) => bounds::hints(hints, famous_defs, config, it),
@@ -306,6 +305,7 @@ pub struct InlayHintsConfig<'a> {
pub sized_bound: bool,
pub discriminant_hints: DiscriminantHints,
pub parameter_hints: bool,
+ pub parameter_hints_for_missing_arguments: bool,
pub generic_parameter_hints: GenericParameterHints,
pub chaining_hints: bool,
pub adjustment_hints: AdjustmentHints,
@@ -316,8 +316,10 @@ pub struct InlayHintsConfig<'a> {
pub closure_capture_hints: bool,
pub binding_mode_hints: bool,
pub implicit_drop_hints: bool,
+ pub implied_dyn_trait_hints: bool,
pub lifetime_elision_hints: LifetimeElisionHints,
pub param_names_for_lifetime_elision_hints: bool,
+ pub hide_inferred_type_hints: bool,
pub hide_named_constructor_hints: bool,
pub hide_closure_initialization_hints: bool,
pub hide_closure_parameter_hints: bool,
@@ -745,46 +747,60 @@ fn label_of_ty(
config: &InlayHintsConfig<'_>,
display_target: DisplayTarget,
) -> Result<(), HirDisplayError> {
- hir::attach_db(sema.db, || {
- let iter_item_type = hint_iterator(sema, famous_defs, ty);
- match iter_item_type {
- Some((iter_trait, item, ty)) => {
- const LABEL_START: &str = "impl ";
- const LABEL_ITERATOR: &str = "Iterator";
- const LABEL_MIDDLE: &str = "<";
- const LABEL_ITEM: &str = "Item";
- const LABEL_MIDDLE2: &str = " = ";
- const LABEL_END: &str = ">";
-
- max_length = max_length.map(|len| {
- len.saturating_sub(
- LABEL_START.len()
- + LABEL_ITERATOR.len()
- + LABEL_MIDDLE.len()
- + LABEL_MIDDLE2.len()
- + LABEL_END.len(),
- )
- });
-
- label_builder.write_str(LABEL_START)?;
- label_builder.start_location_link(ModuleDef::from(iter_trait).into());
- 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, config, display_target)?;
- label_builder.write_str(LABEL_END)?;
+ let iter_item_type = hint_iterator(sema, famous_defs, ty);
+ match iter_item_type {
+ Some((iter_trait, item, ty)) => {
+ const LABEL_START: &str = "impl ";
+ const LABEL_ITERATOR: &str = "Iterator";
+ const LABEL_MIDDLE: &str = "<";
+ const LABEL_ITEM: &str = "Item";
+ const LABEL_MIDDLE2: &str = " = ";
+ const LABEL_END: &str = ">";
+
+ max_length = max_length.map(|len| {
+ len.saturating_sub(
+ LABEL_START.len()
+ + LABEL_ITERATOR.len()
+ + LABEL_MIDDLE.len()
+ + LABEL_MIDDLE2.len()
+ + LABEL_END.len(),
+ )
+ });
+
+ let module_def_location = |label_builder: &mut InlayHintLabelBuilder<'_>,
+ def: ModuleDef,
+ name| {
+ let def = def.try_into();
+ if let Ok(def) = def {
+ label_builder.start_location_link(def);
+ }
+ #[expect(
+ clippy::question_mark,
+ reason = "false positive; replacing with `?` leads to 'type annotations needed' error"
+ )]
+ if let Err(err) = label_builder.write_str(name) {
+ return Err(err);
+ }
+ if def.is_ok() {
+ label_builder.end_location_link();
+ }
Ok(())
- }
- None => ty
- .display_truncated(sema.db, max_length, display_target)
- .with_closure_style(config.closure_style)
- .write_to(label_builder),
+ };
+
+ label_builder.write_str(LABEL_START)?;
+ module_def_location(label_builder, ModuleDef::from(iter_trait), LABEL_ITERATOR)?;
+ label_builder.write_str(LABEL_MIDDLE)?;
+ module_def_location(label_builder, ModuleDef::from(item), LABEL_ITEM)?;
+ label_builder.write_str(LABEL_MIDDLE2)?;
+ rec(sema, famous_defs, max_length, &ty, label_builder, config, display_target)?;
+ label_builder.write_str(LABEL_END)?;
+ Ok(())
}
- })
+ None => ty
+ .display_truncated(sema.db, max_length, display_target)
+ .with_closure_style(config.closure_style)
+ .write_to(label_builder),
+ }
}
let mut label_builder = InlayHintLabelBuilder {
@@ -808,7 +824,7 @@ fn hint_iterator<'db>(
) -> Option<(hir::Trait, hir::TypeAlias, hir::Type<'db>)> {
let db = sema.db;
let strukt = ty.strip_references().as_adt()?;
- let krate = strukt.module(db).krate();
+ let krate = strukt.module(db).krate(db);
if krate != famous_defs.core()? {
return None;
}
@@ -883,6 +899,7 @@ mod tests {
render_colons: false,
type_hints: false,
parameter_hints: false,
+ parameter_hints_for_missing_arguments: false,
sized_bound: false,
generic_parameter_hints: GenericParameterHints {
type_hints: false,
@@ -898,6 +915,7 @@ mod tests {
adjustment_hints_mode: AdjustmentHintsMode::Prefix,
adjustment_hints_hide_outside_unsafe: false,
binding_mode_hints: false,
+ hide_inferred_type_hints: false,
hide_named_constructor_hints: false,
hide_closure_initialization_hints: false,
hide_closure_parameter_hints: false,
@@ -907,6 +925,7 @@ mod tests {
closing_brace_hints_min_lines: None,
fields_to_resolve: InlayFieldsToResolve::empty(),
implicit_drop_hints: false,
+ implied_dyn_trait_hints: false,
range_exclusive_hints: false,
minicore: MiniCore::default(),
};