Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir/src/lib.rs41
-rw-r--r--crates/ide/src/inlay_hints.rs2
-rw-r--r--crates/ide/src/inlay_hints/generic_param.rs30
-rw-r--r--crates/ide/src/inlay_hints/param_name.rs47
4 files changed, 67 insertions, 53 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 4938478bb1..0cbc75726b 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -45,7 +45,7 @@ use hir_def::{
body::BodyDiagnostic,
data::{adt::VariantData, TraitFlags},
generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
- hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, Pat},
+ hir::{BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, LabelId, Pat},
item_tree::{AttrOwner, FieldParent, ItemTreeFieldId, ItemTreeNode},
lang_item::LangItemTarget,
layout::{self, ReprOptions, TargetDataLayout},
@@ -2470,20 +2470,31 @@ impl Param {
}
pub fn as_local(&self, db: &dyn HirDatabase) -> Option<Local> {
- let parent = match self.func {
- Callee::Def(CallableDefId::FunctionId(it)) => DefWithBodyId::FunctionId(it),
- Callee::Closure(closure, _) => db.lookup_intern_closure(closure.into()).0,
- _ => return None,
- };
- let body = db.body(parent);
- if let Some(self_param) = body.self_param.filter(|_| self.idx == 0) {
- Some(Local { parent, binding_id: self_param })
- } else if let Pat::Bind { id, .. } =
- &body[body.params[self.idx - body.self_param.is_some() as usize]]
- {
- Some(Local { parent, binding_id: *id })
- } else {
- None
+ match self.func {
+ Callee::Def(CallableDefId::FunctionId(it)) => {
+ let parent = DefWithBodyId::FunctionId(it);
+ let body = db.body(parent);
+ if let Some(self_param) = body.self_param.filter(|_| self.idx == 0) {
+ Some(Local { parent, binding_id: self_param })
+ } else if let Pat::Bind { id, .. } =
+ &body[body.params[self.idx - body.self_param.is_some() as usize]]
+ {
+ Some(Local { parent, binding_id: *id })
+ } else {
+ None
+ }
+ }
+ Callee::Closure(closure, _) => {
+ let c = db.lookup_intern_closure(closure.into());
+ let body = db.body(c.0);
+ if let Expr::Closure { args, .. } = &body[c.1] {
+ if let Pat::Bind { id, .. } = &body[args[self.idx]] {
+ return Some(Local { parent: c.0, binding_id: *id });
+ }
+ }
+ None
+ }
+ _ => None,
}
}
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 6d83a747d7..94dd90c4aa 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -209,7 +209,7 @@ fn hints(
) {
closing_brace::hints(hints, sema, config, file_id, node.clone());
if let Some(any_has_generic_args) = ast::AnyHasGenericArgs::cast(node.clone()) {
- generic_param::hints(hints, sema, config, any_has_generic_args);
+ generic_param::hints(hints, famous_defs, config, any_has_generic_args);
}
match_ast! {
diff --git a/crates/ide/src/inlay_hints/generic_param.rs b/crates/ide/src/inlay_hints/generic_param.rs
index 037b328d97..13055757ba 100644
--- a/crates/ide/src/inlay_hints/generic_param.rs
+++ b/crates/ide/src/inlay_hints/generic_param.rs
@@ -1,17 +1,19 @@
//! Implementation of inlay hints for generic parameters.
-use ide_db::{active_parameter::generic_def_for_node, RootDatabase};
+use ide_db::{active_parameter::generic_def_for_node, famous_defs::FamousDefs};
use syntax::{
ast::{self, AnyHasGenericArgs, HasGenericArgs, HasName},
AstNode,
};
-use crate::{inlay_hints::GenericParameterHints, InlayHint, InlayHintsConfig, InlayKind};
+use crate::{
+ inlay_hints::GenericParameterHints, InlayHint, InlayHintLabel, InlayHintsConfig, InlayKind,
+};
-use super::param_name::{is_argument_similar_to_param_name, render_label};
+use super::param_name::is_argument_similar_to_param_name;
pub(crate) fn hints(
acc: &mut Vec<InlayHint>,
- sema: &hir::Semantics<'_, RootDatabase>,
+ FamousDefs(sema, krate): &FamousDefs<'_, '_>,
config: &InlayHintsConfig,
node: AnyHasGenericArgs,
) -> Option<()> {
@@ -45,12 +47,11 @@ pub(crate) fn hints(
return None;
}
- let name = param.name(sema.db);
- let param_name = name.as_str();
+ let param_name = param.name(sema.db);
let should_hide = {
let argument = get_string_representation(&arg)?;
- is_argument_similar_to_param_name(&argument, param_name)
+ is_argument_similar_to_param_name(&argument, param_name.as_str())
};
if should_hide {
@@ -64,7 +65,7 @@ pub(crate) fn hints(
if !type_hints || !matches!(arg, ast::GenericArg::TypeArg(_)) {
return None;
}
- sema.source(it.merge())?.value.syntax().clone()
+ sema.source(it.merge()).map(|it| it.value.syntax().clone())
}
hir::GenericParam::ConstParam(it) => {
if !const_hints || !matches!(arg, ast::GenericArg::ConstArg(_)) {
@@ -72,17 +73,22 @@ pub(crate) fn hints(
}
let syntax = sema.source(it.merge())?.value.syntax().clone();
let const_param = ast::ConstParam::cast(syntax)?;
- const_param.name()?.syntax().clone()
+ const_param.name().map(|it| it.syntax().clone())
}
hir::GenericParam::LifetimeParam(it) => {
if !lifetime_hints || !matches!(arg, ast::GenericArg::LifetimeArg(_)) {
return None;
}
- sema.source(it)?.value.syntax().clone()
+ sema.source(it).map(|it| it.value.syntax().clone())
}
};
- let linked_location = sema.original_range_opt(&source_syntax);
- let label = render_label(param_name, config, linked_location);
+ let linked_location = source_syntax.and_then(|it| sema.original_range_opt(&it));
+ let colon = if config.render_colons { ":" } else { "" };
+ let label = InlayHintLabel::simple(
+ format!("{}{colon}", param_name.display(sema.db, krate.edition(sema.db))),
+ None,
+ linked_location.map(Into::into),
+ );
Some(InlayHint {
range,
diff --git a/crates/ide/src/inlay_hints/param_name.rs b/crates/ide/src/inlay_hints/param_name.rs
index a6f7e0c184..ac137d97d8 100644
--- a/crates/ide/src/inlay_hints/param_name.rs
+++ b/crates/ide/src/inlay_hints/param_name.rs
@@ -3,7 +3,6 @@
//! fn max(x: i32, y: i32) -> i32 { x + y }
//! _ = max(/*x*/4, /*y*/4);
//! ```
-use std::fmt::Display;
use either::Either;
use hir::{Callable, Semantics};
@@ -20,7 +19,7 @@ use crate::{InlayHint, InlayHintLabel, InlayHintPosition, InlayHintsConfig, Inla
pub(super) fn hints(
acc: &mut Vec<InlayHint>,
- FamousDefs(sema, _): &FamousDefs<'_, '_>,
+ FamousDefs(sema, krate): &FamousDefs<'_, '_>,
config: &InlayHintsConfig,
_file_id: EditionedFileId,
expr: ast::Expr,
@@ -37,23 +36,31 @@ pub(super) fn hints(
.filter_map(|(p, arg)| {
// Only annotate hints for expressions that exist in the original file
let range = sema.original_range_opt(arg.syntax())?;
- let source = sema.source(p)?;
- let (param_name, name_syntax) = match source.value.as_ref() {
- Either::Left(pat) => (pat.name()?, pat.name()),
- Either::Right(param) => match param.pat()? {
- ast::Pat::IdentPat(it) => (it.name()?, it.name()),
- _ => return None,
- },
- };
- Some((name_syntax, param_name, arg, range))
+ let param_name = p.name(sema.db)?;
+ Some((p, param_name, arg, range))
})
.filter(|(_, param_name, arg, _)| {
- !should_hide_param_name_hint(sema, &callable, &param_name.text(), arg)
+ !should_hide_param_name_hint(sema, &callable, param_name.as_str(), arg)
})
.map(|(param, param_name, _, hir::FileRange { range, .. })| {
- let linked_location = param.and_then(|name| sema.original_range_opt(name.syntax()));
-
- let label = render_label(&param_name, config, linked_location);
+ let linked_location = (|| {
+ let source = sema.source(param)?;
+ let name_syntax = match source.value.as_ref() {
+ Either::Left(pat) => pat.name(),
+ Either::Right(param) => match param.pat()? {
+ ast::Pat::IdentPat(it) => it.name(),
+ _ => None,
+ },
+ }?;
+ sema.original_range_opt(name_syntax.syntax())
+ })();
+
+ let colon = if config.render_colons { ":" } else { "" };
+ let label = InlayHintLabel::simple(
+ format!("{}{colon}", param_name.display(sema.db, krate.edition(sema.db))),
+ None,
+ linked_location.map(Into::into),
+ );
InlayHint {
range,
kind: InlayKind::Parameter,
@@ -70,16 +77,6 @@ pub(super) fn hints(
Some(())
}
-pub(super) fn render_label(
- param_name: impl Display,
- config: &InlayHintsConfig,
- linked_location: Option<hir::FileRange>,
-) -> InlayHintLabel {
- let colon = if config.render_colons { ":" } else { "" };
-
- InlayHintLabel::simple(format!("{param_name}{colon}"), None, linked_location.map(Into::into))
-}
-
fn get_callable(
sema: &Semantics<'_, RootDatabase>,
expr: &ast::Expr,