From de591f08d6a38f1b70365622f62352583c9c06ef Mon Sep 17 00:00:00 2001 From: Ryo Yoshida Date: Sat, 3 Dec 2022 22:57:08 +0900 Subject: [PATCH] Handle raw identifiers in proc macro server --- crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs | 8 ++++++-- crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs | 8 ++++++-- .../proc-macro-srv/src/abis/abi_sysroot/ra_server.rs | 7 +++---- crates/proc-macro-srv/src/tests/mod.rs | 6 ++---- crates/tt/src/lib.rs | 10 ++++++++++ 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs b/crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs index b1e982f4779..c19684850fc 100644 --- a/crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs +++ b/crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs @@ -471,8 +471,12 @@ fn with_span(&mut self, punct: Self::Punct, span: Self::Span) -> Self::Punct { } impl server::Ident for RustAnalyzer { - fn new(&mut self, string: &str, span: Self::Span, _is_raw: bool) -> Self::Ident { - IdentId(self.ident_interner.intern(&IdentData(tt::Ident { text: string.into(), id: span }))) + fn new(&mut self, string: &str, span: Self::Span, is_raw: bool) -> Self::Ident { + IdentId(self.ident_interner.intern(&IdentData(tt::Ident::new_with_is_raw( + string.into(), + span, + is_raw, + )))) } fn span(&mut self, ident: Self::Ident) -> Self::Span { diff --git a/crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs b/crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs index ed49cc75966..eb9d7a94b5d 100644 --- a/crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs +++ b/crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs @@ -486,8 +486,12 @@ fn with_span(&mut self, punct: Self::Punct, span: Self::Span) -> Self::Punct { } impl server::Ident for RustAnalyzer { - fn new(&mut self, string: &str, span: Self::Span, _is_raw: bool) -> Self::Ident { - IdentId(self.ident_interner.intern(&IdentData(tt::Ident { text: string.into(), id: span }))) + fn new(&mut self, string: &str, span: Self::Span, is_raw: bool) -> Self::Ident { + IdentId(self.ident_interner.intern(&IdentData(tt::Ident::new_with_is_raw( + string.into(), + span, + is_raw, + )))) } fn span(&mut self, ident: Self::Ident) -> Self::Span { diff --git a/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs b/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs index e4e43e97dde..d38bd9400b5 100644 --- a/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs +++ b/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs @@ -107,8 +107,8 @@ fn from_token_tree( } bridge::TokenTree::Ident(ident) => { - // FIXME: handle raw idents let text = ident.sym.text(); + let text = if ident.is_raw { tt::SmolStr::from_iter(["r#", &text]) } else { text }; let ident: tt::Ident = tt::Ident { text, id: ident.span }; let leaf = tt::Leaf::from(ident); let tree = TokenTree::from(leaf); @@ -182,9 +182,8 @@ fn into_trees( .map(|tree| match tree { tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => { bridge::TokenTree::Ident(bridge::Ident { - sym: Symbol::intern(&ident.text), - // FIXME: handle raw idents - is_raw: false, + sym: Symbol::intern(&ident.text.trim_start_matches("r#")), + is_raw: ident.text.starts_with("r#"), span: ident.id, }) } diff --git a/crates/proc-macro-srv/src/tests/mod.rs b/crates/proc-macro-srv/src/tests/mod.rs index cc0fc91fe98..1ccc170f422 100644 --- a/crates/proc-macro-srv/src/tests/mod.rs +++ b/crates/proc-macro-srv/src/tests/mod.rs @@ -63,7 +63,7 @@ fn test_fn_like_macro_clone_raw_ident() { "r#async", expect![[r#" SUBTREE $ - IDENT async 4294967295"#]], + IDENT r#async 4294967295"#]], ); } @@ -86,15 +86,13 @@ fn test_fn_like_mk_literals() { #[test] fn test_fn_like_mk_idents() { - // FIXME: this test is wrong: raw should be 'r#raw' but ABIs 1.64 and below - // simply ignore `is_raw` when implementing the `Ident` interface. assert_expand( "fn_like_mk_idents", r#""#, expect![[r#" SUBTREE $ IDENT standard 4294967295 - IDENT raw 4294967295"#]], + IDENT r#raw 4294967295"#]], ); } diff --git a/crates/tt/src/lib.rs b/crates/tt/src/lib.rs index a54861de958..85daec262c4 100644 --- a/crates/tt/src/lib.rs +++ b/crates/tt/src/lib.rs @@ -86,10 +86,20 @@ pub enum Spacing { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Ident { + /// Identifier or keyword. Unlike rustc, we keep "r#" prefix when it represents a raw identifier. pub text: SmolStr, pub id: TokenId, } +impl Ident { + /// Constructor intended to be used only by proc macro server. `text` should not contain raw + /// identifier prefix. + pub fn new_with_is_raw(text: SmolStr, id: TokenId, is_raw: bool) -> Self { + let text = if is_raw { SmolStr::from_iter(["r#", &text]) } else { text }; + Ident { text, id } + } +} + impl Leaf { pub fn id(&self) -> TokenId { match self {