about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs41
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs30
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs47
4 files changed, 67 insertions, 53 deletions
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index 4938478bb12..0cbc75726bf 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
index 6d83a747d76..94dd90c4aac 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints.rs
+++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs
index 037b328d971..13055757ba6 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/generic_param.rs
+++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs
index a6f7e0c184a..ac137d97d8a 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/param_name.rs
+++ b/src/tools/rust-analyzer/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,