about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-10-23 09:30:36 +0200
committerLukas Wirth <lukastw97@gmail.com>2024-10-23 09:30:36 +0200
commitcb816ad4f0c2ec8ac8cb74fdcc8b078d7357e012 (patch)
tree4afa9fc221a3d31f67fb97ff56731fd65681d209
parent770df7ffbb75b0ab53a50c2612000e2374789a92 (diff)
downloadrust-cb816ad4f0c2ec8ac8cb74fdcc8b078d7357e012.tar.gz
rust-cb816ad4f0c2ec8ac8cb74fdcc8b078d7357e012.zip
Add text edit to adjustment hints
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs52
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs11
2 files changed, 42 insertions, 21 deletions
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs
index ab44d8c3b50..8f239f6029b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs
@@ -3,6 +3,8 @@
 //! let _: u32  = /* <never-to-any> */ loop {};
 //! let _: &u32 = /* &* */ &mut 0;
 //! ```
+use std::ops::Not;
+
 use either::Either;
 use hir::{
     Adjust, Adjustment, AutoBorrow, HirDisplay, Mutability, OverloadedDeref, PointerCast, Safety,
@@ -15,6 +17,7 @@ use syntax::{
     ast::{self, make, AstNode},
     ted,
 };
+use text_edit::TextEditBuilder;
 
 use crate::{
     AdjustmentHints, AdjustmentHintsMode, InlayHint, InlayHintLabel, InlayHintLabelPart,
@@ -51,13 +54,13 @@ pub(super) fn hints(
     let adjustments = sema.expr_adjustments(desc_expr).filter(|it| !it.is_empty())?;
 
     if let ast::Expr::BlockExpr(_) | ast::Expr::IfExpr(_) | ast::Expr::MatchExpr(_) = desc_expr {
-        if let [Adjustment { kind: Adjust::Deref(_), source, .. }, Adjustment { kind: Adjust::Borrow(_), source: _, target }] =
-            &*adjustments
-        {
-            // Don't show unnecessary reborrows for these, they will just repeat the inner ones again
-            if source == target {
-                return None;
-            }
+        // Don't show unnecessary reborrows for these, they will just repeat the inner ones again
+        if matches!(
+            &*adjustments,
+            [Adjustment { kind: Adjust::Deref(_), source, .. }, Adjustment { kind: Adjust::Borrow(_), target, .. }]
+            if source == target
+        ) {
+            return None;
         }
     }
 
@@ -170,12 +173,39 @@ pub(super) fn hints(
     if needs_outer_parens || (!postfix && needs_inner_parens) {
         post.label.append_str(")");
     }
-    if !pre.label.parts.is_empty() {
-        acc.push(pre);
+
+    let mut pre = pre.label.parts.is_empty().not().then_some(pre);
+    let mut post = post.label.parts.is_empty().not().then_some(post);
+    if pre.is_none() && post.is_none() {
+        return None;
     }
-    if !post.label.parts.is_empty() {
-        acc.push(post);
+    let edit = {
+        let mut b = TextEditBuilder::default();
+        if let Some(pre) = &pre {
+            b.insert(
+                pre.range.start(),
+                pre.label.parts.iter().map(|part| &*part.text).collect::<String>(),
+            );
+        }
+        if let Some(post) = &post {
+            b.insert(
+                post.range.end(),
+                post.label.parts.iter().map(|part| &*part.text).collect::<String>(),
+            );
+        }
+        b.finish()
+    };
+    match (&mut pre, &mut post) {
+        (Some(pre), Some(post)) => {
+            pre.text_edit = Some(edit.clone());
+            post.text_edit = Some(edit);
+        }
+        (Some(pre), None) => pre.text_edit = Some(edit),
+        (None, Some(post)) => post.text_edit = Some(edit),
+        (None, None) => (),
     }
+    acc.extend(pre);
+    acc.extend(post);
     Some(())
 }
 
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs
index beba2ad748c..db36a06cbe8 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/binding_mode.rs
@@ -23,16 +23,7 @@ pub(super) fn hints(
         return None;
     }
 
-    let outer_paren_pat = pat
-        .syntax()
-        .ancestors()
-        .skip(1)
-        .map_while(ast::Pat::cast)
-        .map_while(|pat| match pat {
-            ast::Pat::ParenPat(pat) => Some(pat),
-            _ => None,
-        })
-        .last();
+    let outer_paren_pat = pat.syntax().ancestors().skip(1).map_while(ast::ParenPat::cast).last();
     let range = outer_paren_pat.as_ref().map_or_else(
         || match pat {
             // for ident patterns that @ bind a name, render the un-ref patterns in front of the inner pattern