about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/ide/src/inlay_hints/binding_mode.rs29
1 files changed, 27 insertions, 2 deletions
diff --git a/crates/ide/src/inlay_hints/binding_mode.rs b/crates/ide/src/inlay_hints/binding_mode.rs
index 11b9cd269bf..5d9729263c2 100644
--- a/crates/ide/src/inlay_hints/binding_mode.rs
+++ b/crates/ide/src/inlay_hints/binding_mode.rs
@@ -29,8 +29,17 @@ pub(super) fn hints(
             _ => None,
         })
         .last();
-    let range =
-        outer_paren_pat.as_ref().map_or_else(|| pat.syntax(), |it| it.syntax()).text_range();
+    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
+            // instead of the name as that makes it more clear and doesn't really change the outcome
+            ast::Pat::IdentPat(it) => {
+                it.pat().map_or_else(|| it.syntax().text_range(), |it| it.syntax().text_range())
+            }
+            it => it.syntax().text_range(),
+        },
+        |it| it.syntax().text_range(),
+    );
     let pattern_adjustments = sema.pattern_adjustments(pat);
     pattern_adjustments.iter().for_each(|ty| {
         let reference = ty.is_reference();
@@ -123,4 +132,20 @@ fn __(
 }"#,
         );
     }
+
+    #[test]
+    fn hints_binding_modes_complex_ident_pat() {
+        check_with_config(
+            InlayHintsConfig { binding_mode_hints: true, ..DISABLED_CONFIG },
+            r#"
+struct Struct {
+    field: &'static str,
+}
+fn foo(s @ Struct { field, .. }: &Struct) {}
+     //^^^^^^^^^^^^^^^^^^^^^^^^ref
+         //^^^^^^^^^^^^^^^^^^^^&
+                  //^^^^^ref
+"#,
+        );
+    }
 }