about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChayim Refael Friedman <chayimfr@gmail.com>2025-01-07 12:11:59 +0000
committerGitHub <noreply@github.com>2025-01-07 12:11:59 +0000
commit3f2f3e51804c74d6a92d4f5fbb2b09bbe83331e4 (patch)
treec3aaf68a0ef0f9f1353e053aa836c1d422b18012
parent1287e29e917b16139fdf4097f83b800b9e3f7ffe (diff)
parent09a4ac5e8bb3aa25a84043ab972996e999b0ed6c (diff)
downloadrust-3f2f3e51804c74d6a92d4f5fbb2b09bbe83331e4.tar.gz
rust-3f2f3e51804c74d6a92d4f5fbb2b09bbe83331e4.zip
Merge pull request #18832 from vishruth-thimmaiah/fix_string_comp
fix: do not offer completions within macro strings
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs9
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs22
-rw-r--r--src/tools/rust-analyzer/crates/test-fixture/src/lib.rs42
3 files changed, 72 insertions, 1 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
index 1979755ee50..acce62a041c 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs
@@ -417,6 +417,15 @@ fn analyze(
         derive_ctx,
     } = expansion_result;
 
+    if original_token.kind() != self_token.kind()
+        // FIXME: This check can be removed once we use speculative database forking for completions
+        && !(original_token.kind().is_punct() || original_token.kind().is_trivia())
+        && !(SyntaxKind::is_any_identifier(original_token.kind())
+            && SyntaxKind::is_any_identifier(self_token.kind()))
+    {
+        return None;
+    }
+
     // Overwrite the path kind for derives
     if let Some((original_file, file_with_fake_ident, offset, origin_attr)) = derive_ctx {
         if let Some(ast::NameLike::NameRef(name_ref)) =
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs b/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs
index acafa6518f6..ebf35820570 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs
@@ -713,6 +713,28 @@ struct Foo;
     );
 }
 
+#[test]
+fn issue_17479() {
+    check(
+        r#"
+//- proc_macros: issue_17479
+fn main() {
+    proc_macros::issue_17479!("te$0");
+}
+"#,
+        expect![""],
+    );
+    check(
+        r#"
+//- proc_macros: issue_17479
+fn main() {
+    proc_macros::issue_17479!("$0");
+}
+"#,
+        expect![""],
+    )
+}
+
 mod cfg {
     use super::*;
 
diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs
index b40b7757c6e..0e72d796875 100644
--- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs
@@ -376,7 +376,7 @@ impl ChangeFixture {
     }
 }
 
-fn default_test_proc_macros() -> [(String, ProcMacro); 7] {
+fn default_test_proc_macros() -> [(String, ProcMacro); 8] {
     [
         (
             r#"
@@ -483,6 +483,21 @@ pub fn issue_18840(_attr: TokenStream, _item: TokenStream) -> TokenStream {
                 disabled: false,
             },
         ),
+        (
+            r#"
+#[proc_macro]
+pub fn issue_17479(input: TokenStream) -> TokenStream {
+    input
+}
+"#
+            .into(),
+            ProcMacro {
+                name: Symbol::intern("issue_17479"),
+                kind: ProcMacroKind::Bang,
+                expander: sync::Arc::new(Issue17479ProcMacroExpander),
+                disabled: false,
+            },
+        ),
     ]
 }
 
@@ -761,3 +776,28 @@ impl ProcMacroExpander for ShortenProcMacroExpander {
         }
     }
 }
+
+// Reads ident type within string quotes, for issue #17479.
+#[derive(Debug)]
+struct Issue17479ProcMacroExpander;
+impl ProcMacroExpander for Issue17479ProcMacroExpander {
+    fn expand(
+        &self,
+        subtree: &TopSubtree,
+        _: Option<&TopSubtree>,
+        _: &Env,
+        _: Span,
+        _: Span,
+        _: Span,
+        _: Option<String>,
+    ) -> Result<TopSubtree, ProcMacroExpansionError> {
+        let TokenTree::Leaf(Leaf::Literal(lit)) = &subtree.0[1] else {
+            return Err(ProcMacroExpansionError::Panic("incorrect Input".into()));
+        };
+        let symbol = &lit.symbol;
+        let span = lit.span;
+        Ok(quote! { span =>
+            #symbol()
+        })
+    }
+}