about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonas Schievink <jonas.schievink@ferrous-systems.com>2022-11-29 18:50:21 +0100
committerJonas Schievink <jonas.schievink@ferrous-systems.com>2022-11-29 18:50:21 +0100
commitb65b02fd976d0174312e71ac8735ed8fecdfc74e (patch)
treea8362c3ff3bb72d541be8eae2b9ca66d6d6ee58d
parent3827e3ddf1f04adba960ffd747316861b0a68930 (diff)
downloadrust-b65b02fd976d0174312e71ac8735ed8fecdfc74e.tar.gz
rust-b65b02fd976d0174312e71ac8735ed8fecdfc74e.zip
Fix signature help not showing up when cursor is between `))` or `>>`
-rw-r--r--crates/ide/src/signature_help.rs58
1 files changed, 43 insertions, 15 deletions
diff --git a/crates/ide/src/signature_help.rs b/crates/ide/src/signature_help.rs
index e7412d27faf..6045a787ecc 100644
--- a/crates/ide/src/signature_help.rs
+++ b/crates/ide/src/signature_help.rs
@@ -74,20 +74,28 @@ pub(crate) fn signature_help(db: &RootDatabase, position: FilePosition) -> Optio
                 ast::ArgList(arg_list) => {
                     let cursor_outside = arg_list.r_paren_token().as_ref() == Some(&token);
                     if cursor_outside {
-                        return None;
+                        continue;
                     }
-                    return signature_help_for_call(&sema, token);
+                    return signature_help_for_call(&sema, arg_list, token);
                 },
                 ast::GenericArgList(garg_list) => {
                     let cursor_outside = garg_list.r_angle_token().as_ref() == Some(&token);
                     if cursor_outside {
-                        return None;
+                        continue;
                     }
-                    return signature_help_for_generics(&sema, token);
+                    return signature_help_for_generics(&sema, garg_list, token);
                 },
                 _ => (),
             }
         }
+
+        // Stop at multi-line expressions, since the signature of the outer call is not very
+        // helpful inside them.
+        if let Some(expr) = ast::Expr::cast(node.clone()) {
+            if expr.syntax().text().contains_char('\n') {
+                return None;
+            }
+        }
     }
 
     None
@@ -95,10 +103,11 @@ pub(crate) fn signature_help(db: &RootDatabase, position: FilePosition) -> Optio
 
 fn signature_help_for_call(
     sema: &Semantics<'_, RootDatabase>,
+    arg_list: ast::ArgList,
     token: SyntaxToken,
 ) -> Option<SignatureHelp> {
     // Find the calling expression and its NameRef
-    let mut node = token.parent()?;
+    let mut node = arg_list.syntax().parent()?;
     let calling_node = loop {
         if let Some(callable) = ast::CallableExpr::cast(node.clone()) {
             if callable
@@ -109,14 +118,6 @@ fn signature_help_for_call(
             }
         }
 
-        // Stop at multi-line expressions, since the signature of the outer call is not very
-        // helpful inside them.
-        if let Some(expr) = ast::Expr::cast(node.clone()) {
-            if expr.syntax().text().contains_char('\n') {
-                return None;
-            }
-        }
-
         node = node.parent()?;
     };
 
@@ -200,10 +201,11 @@ fn signature_help_for_call(
 
 fn signature_help_for_generics(
     sema: &Semantics<'_, RootDatabase>,
+    garg_list: ast::GenericArgList,
     token: SyntaxToken,
 ) -> Option<SignatureHelp> {
-    let parent = token.parent()?;
-    let arg_list = parent
+    let arg_list = garg_list
+        .syntax()
         .ancestors()
         .filter_map(ast::GenericArgList::cast)
         .find(|list| list.syntax().text_range().contains(token.text_range().start()))?;
@@ -770,6 +772,32 @@ fn f() {
 "#,
             expect![[]],
         );
+        check(
+            r#"
+fn foo(a: u8) -> u8 {a}
+fn bar(a: u8) -> u8 {a}
+fn f() {
+    foo(bar(123)$0)
+}
+"#,
+            expect![[r#"
+                fn foo(a: u8) -> u8
+                       ^^^^^
+            "#]],
+        );
+        check(
+            r#"
+struct Vec<T>(T);
+struct Vec2<T>(T);
+fn f() {
+    let _: Vec2<Vec<u8>$0>
+}
+"#,
+            expect![[r#"
+                struct Vec2<T>
+                            ^
+            "#]],
+        );
     }
 
     #[test]