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.rs | 127 |
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(), }; |