]> git.lizzy.rs Git - rust.git/commitdiff
fix: correctly complete macro call if cursor at `!`
authorunexge <unexge@gmail.com>
Thu, 26 Aug 2021 16:44:46 +0000 (19:44 +0300)
committerunexge <unexge@gmail.com>
Thu, 26 Aug 2021 16:44:46 +0000 (19:44 +0300)
crates/ide_completion/src/completions/unqualified_path.rs
crates/ide_completion/src/context.rs

index d81cb5391cb09e7002bdb556c64b098076b8fd9b..8d421fc78d783791dcf032f6556bcf47fcfa5600 100644 (file)
@@ -304,4 +304,31 @@ pub mod rust_2018 {}
             "#]],
         );
     }
+
+    #[test]
+    fn completes_macro_call_if_cursor_at_bang_token() {
+        // Regression test for https://github.com/rust-analyzer/rust-analyzer/issues/9904
+        cov_mark::check!(completes_macro_call_if_cursor_at_bang_token);
+        check_edit(
+            "foo!",
+            r#"
+macro_rules! foo {
+    () => {}
+}
+
+fn main() {
+    foo!$0
+}
+"#,
+            r#"
+macro_rules! foo {
+    () => {}
+}
+
+fn main() {
+    foo!($0)
+}
+"#,
+        );
+    }
 }
index 6c6f8f8512bfa29655007570801ac8ee0c3c5b31..d9024157ce458e826a1e41c7f557859a04b1419d 100644 (file)
@@ -236,14 +236,21 @@ pub(crate) fn source_range(&self) -> TextRange {
         let kind = self.token.kind();
         if kind == IDENT || kind == LIFETIME_IDENT || kind == UNDERSCORE || kind.is_keyword() {
             cov_mark::hit!(completes_if_prefix_is_keyword);
-            self.original_token.text_range()
+            return self.original_token.text_range();
         } else if kind == CHAR {
             // assume we are completing a lifetime but the user has only typed the '
             cov_mark::hit!(completes_if_lifetime_without_idents);
-            TextRange::at(self.original_token.text_range().start(), TextSize::from(1))
-        } else {
-            TextRange::empty(self.position.offset)
+            return TextRange::at(self.original_token.text_range().start(), TextSize::from(1));
+        } else if kind == BANG {
+            if let Some(n) = self.token.parent() {
+                if n.kind() == SyntaxKind::MACRO_CALL {
+                    cov_mark::hit!(completes_macro_call_if_cursor_at_bang_token);
+                    return n.text_range();
+                }
+            }
         }
+
+        TextRange::empty(self.position.offset)
     }
 
     pub(crate) fn previous_token_is(&self, kind: SyntaxKind) -> bool {