From 3d5f430b6bcdc583bbb8676eca822366be86c31e Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 29 Aug 2024 08:08:00 +0200 Subject: [PATCH 1/2] fix: Fix proc-macro server crashing when parsing a non-lexable string into a TokenStream --- .../proc-macro-srv/src/server_impl/rust_analyzer_span.rs | 8 +++++++- crates/proc-macro-srv/src/server_impl/token_id.rs | 8 +++++++- crates/proc-macro-srv/src/server_impl/token_stream.rs | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 552d99f51ba1..bfc3ea5d03a5 100644 --- a/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -142,7 +142,13 @@ impl server::TokenStream for RaSpanServer { stream.is_empty() } fn from_str(&mut self, src: &str) -> Self::TokenStream { - Self::TokenStream::from_str(src, self.call_site).expect("cannot parse string") + Self::TokenStream::from_str(src, self.call_site).unwrap_or_else(|e| { + Self::TokenStream::from_str( + &format!("compile_error!(\"failed to parse str to token stream: {e}\")"), + self.call_site, + ) + .unwrap() + }) } fn to_string(&mut self, stream: &Self::TokenStream) -> String { stream.to_string() diff --git a/crates/proc-macro-srv/src/server_impl/token_id.rs b/crates/proc-macro-srv/src/server_impl/token_id.rs index 7720c6d83c38..e478b1c853be 100644 --- a/crates/proc-macro-srv/src/server_impl/token_id.rs +++ b/crates/proc-macro-srv/src/server_impl/token_id.rs @@ -131,7 +131,13 @@ impl server::TokenStream for TokenIdServer { stream.is_empty() } fn from_str(&mut self, src: &str) -> Self::TokenStream { - Self::TokenStream::from_str(src, self.call_site).expect("cannot parse string") + Self::TokenStream::from_str(src, self.call_site).unwrap_or_else(|e| { + Self::TokenStream::from_str( + &format!("compile_error!(\"failed to parse str to token stream: {e}\")"), + self.call_site, + ) + .unwrap() + }) } fn to_string(&mut self, stream: &Self::TokenStream) -> String { stream.to_string() diff --git a/crates/proc-macro-srv/src/server_impl/token_stream.rs b/crates/proc-macro-srv/src/server_impl/token_stream.rs index 4d8d496418bf..dbcb5a3143a6 100644 --- a/crates/proc-macro-srv/src/server_impl/token_stream.rs +++ b/crates/proc-macro-srv/src/server_impl/token_stream.rs @@ -131,7 +131,7 @@ pub(super) mod token_stream { call_site, src, ) - .ok_or("lexing error")?; + .ok_or_else(|| format!("lexing error: {src}"))?; Ok(TokenStream::with_subtree(subtree)) } From c103fee98762fbf29f3ff7d77f5b62ced8f48fcd Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 29 Aug 2024 08:41:43 +0200 Subject: [PATCH 2/2] fix: Fix TokenStream::to_string implementation dropping quotation marks --- .../proc-macro-srv/src/server_impl/rust_analyzer_span.rs | 9 +++++++-- crates/tt/src/lib.rs | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index bfc3ea5d03a5..d508c19dd719 100644 --- a/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -507,12 +507,17 @@ mod tests { close: span, kind: tt::DelimiterKind::Brace, }, - token_trees: Box::new([]), + token_trees: Box::new([tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { + kind: tt::LitKind::Str, + symbol: Symbol::intern("string"), + suffix: None, + span, + }))]), }), ], }; - assert_eq!(s.to_string(), "struct T {}"); + assert_eq!(s.to_string(), "struct T {\"string\"}"); } #[test] diff --git a/crates/tt/src/lib.rs b/crates/tt/src/lib.rs index 7b72f9ff108d..8d915d0a51e3 100644 --- a/crates/tt/src/lib.rs +++ b/crates/tt/src/lib.rs @@ -603,7 +603,7 @@ pub fn pretty(tkns: &[TokenTree]) -> String { TokenTree::Leaf(Leaf::Ident(ident)) => { format!("{}{}", ident.is_raw.as_str(), ident.sym) } - TokenTree::Leaf(Leaf::Literal(literal)) => literal.symbol.as_str().to_owned(), + TokenTree::Leaf(Leaf::Literal(literal)) => format!("{literal}"), TokenTree::Leaf(Leaf::Punct(punct)) => format!("{}", punct.char), TokenTree::Subtree(subtree) => { let content = pretty(&subtree.token_trees);