Skip to content

Commit 09a4ac5

Browse files
fix: do not offer completions within macro strings
1 parent 9344334 commit 09a4ac5

File tree

3 files changed

+72
-1
lines changed

3 files changed

+72
-1
lines changed

src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs

+9
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,15 @@ fn analyze(
417417
derive_ctx,
418418
} = expansion_result;
419419

420+
if original_token.kind() != self_token.kind()
421+
// FIXME: This check can be removed once we use speculative database forking for completions
422+
&& !(original_token.kind().is_punct() || original_token.kind().is_trivia())
423+
&& !(SyntaxKind::is_any_identifier(original_token.kind())
424+
&& SyntaxKind::is_any_identifier(self_token.kind()))
425+
{
426+
return None;
427+
}
428+
420429
// Overwrite the path kind for derives
421430
if let Some((original_file, file_with_fake_ident, offset, origin_attr)) = derive_ctx {
422431
if let Some(ast::NameLike::NameRef(name_ref)) =

src/tools/rust-analyzer/crates/ide-completion/src/tests/attribute.rs

+22
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,28 @@ struct Foo;
713713
);
714714
}
715715

716+
#[test]
717+
fn issue_17479() {
718+
check(
719+
r#"
720+
//- proc_macros: issue_17479
721+
fn main() {
722+
proc_macros::issue_17479!("te$0");
723+
}
724+
"#,
725+
expect![""],
726+
);
727+
check(
728+
r#"
729+
//- proc_macros: issue_17479
730+
fn main() {
731+
proc_macros::issue_17479!("$0");
732+
}
733+
"#,
734+
expect![""],
735+
)
736+
}
737+
716738
mod cfg {
717739
use super::*;
718740

src/tools/rust-analyzer/crates/test-fixture/src/lib.rs

+41-1
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ impl ChangeFixture {
376376
}
377377
}
378378

379-
fn default_test_proc_macros() -> [(String, ProcMacro); 7] {
379+
fn default_test_proc_macros() -> [(String, ProcMacro); 8] {
380380
[
381381
(
382382
r#"
@@ -483,6 +483,21 @@ pub fn issue_18840(_attr: TokenStream, _item: TokenStream) -> TokenStream {
483483
disabled: false,
484484
},
485485
),
486+
(
487+
r#"
488+
#[proc_macro]
489+
pub fn issue_17479(input: TokenStream) -> TokenStream {
490+
input
491+
}
492+
"#
493+
.into(),
494+
ProcMacro {
495+
name: Symbol::intern("issue_17479"),
496+
kind: ProcMacroKind::Bang,
497+
expander: sync::Arc::new(Issue17479ProcMacroExpander),
498+
disabled: false,
499+
},
500+
),
486501
]
487502
}
488503

@@ -761,3 +776,28 @@ impl ProcMacroExpander for ShortenProcMacroExpander {
761776
}
762777
}
763778
}
779+
780+
// Reads ident type within string quotes, for issue #17479.
781+
#[derive(Debug)]
782+
struct Issue17479ProcMacroExpander;
783+
impl ProcMacroExpander for Issue17479ProcMacroExpander {
784+
fn expand(
785+
&self,
786+
subtree: &TopSubtree,
787+
_: Option<&TopSubtree>,
788+
_: &Env,
789+
_: Span,
790+
_: Span,
791+
_: Span,
792+
_: Option<String>,
793+
) -> Result<TopSubtree, ProcMacroExpansionError> {
794+
let TokenTree::Leaf(Leaf::Literal(lit)) = &subtree.0[1] else {
795+
return Err(ProcMacroExpansionError::Panic("incorrect Input".into()));
796+
};
797+
let symbol = &lit.symbol;
798+
let span = lit.span;
799+
Ok(quote! { span =>
800+
#symbol()
801+
})
802+
}
803+
}

0 commit comments

Comments
 (0)