Unnamed repository; edit this file 'description' to name the repository.
fix: Fix proc-macro API creating malformed negative literals
Lukas Wirth 12 months ago
parent cb18ead · commit 361a927
-rw-r--r--crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs42
-rw-r--r--crates/proc-macro-srv/src/server_impl/token_id.rs42
-rw-r--r--crates/proc-macro-srv/src/server_impl/token_stream.rs5
-rw-r--r--crates/proc-macro-srv/src/tests/mod.rs25
4 files changed, 85 insertions, 29 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 47555a5db2..64b40e7b94 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
@@ -168,16 +168,38 @@ impl server::TokenStream for RaSpanServer {
}
bridge::TokenTree::Literal(literal) => {
- let literal = tt::Literal {
- symbol: literal.symbol,
- suffix: literal.suffix,
- span: literal.span,
- kind: literal_kind_to_internal(literal.kind),
- };
-
- let leaf: tt::Leaf = tt::Leaf::from(literal);
- let tree = tt::TokenTree::from(leaf);
- TokenStream { token_trees: vec![tree] }
+ let token_trees =
+ if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') {
+ let punct = tt::Punct {
+ spacing: tt::Spacing::Alone,
+ span: literal.span,
+ char: '-' as char,
+ };
+ let leaf: tt::Leaf = tt::Leaf::from(punct);
+ let minus_tree = tt::TokenTree::from(leaf);
+
+ let literal = tt::Literal {
+ symbol: Symbol::intern(symbol),
+ suffix: literal.suffix,
+ span: literal.span,
+ kind: literal_kind_to_internal(literal.kind),
+ };
+ let leaf: tt::Leaf = tt::Leaf::from(literal);
+ let tree = tt::TokenTree::from(leaf);
+ vec![minus_tree, tree]
+ } else {
+ let literal = tt::Literal {
+ symbol: literal.symbol,
+ suffix: literal.suffix,
+ span: literal.span,
+ kind: literal_kind_to_internal(literal.kind),
+ };
+
+ let leaf: tt::Leaf = tt::Leaf::from(literal);
+ let tree = tt::TokenTree::from(leaf);
+ vec![tree]
+ };
+ TokenStream { token_trees }
}
bridge::TokenTree::Punct(p) => {
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 c002be4be6..24a67bf45c 100644
--- a/crates/proc-macro-srv/src/server_impl/token_id.rs
+++ b/crates/proc-macro-srv/src/server_impl/token_id.rs
@@ -153,16 +153,38 @@ impl server::TokenStream for TokenIdServer {
}
bridge::TokenTree::Literal(literal) => {
- let literal = Literal {
- symbol: literal.symbol,
- suffix: literal.suffix,
- span: literal.span,
- kind: literal_kind_to_internal(literal.kind),
- };
-
- let leaf = tt::Leaf::from(literal);
- let tree = TokenTree::from(leaf);
- TokenStream { token_trees: vec![tree] }
+ let token_trees =
+ if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') {
+ let punct = tt::Punct {
+ spacing: tt::Spacing::Alone,
+ span: literal.span,
+ char: '-' as char,
+ };
+ let leaf: tt::Leaf = tt::Leaf::from(punct);
+ let minus_tree = tt::TokenTree::from(leaf);
+
+ let literal = Literal {
+ symbol: Symbol::intern(symbol),
+ suffix: literal.suffix,
+ span: literal.span,
+ kind: literal_kind_to_internal(literal.kind),
+ };
+ let leaf: tt::Leaf = tt::Leaf::from(literal);
+ let tree = tt::TokenTree::from(leaf);
+ vec![minus_tree, tree]
+ } else {
+ let literal = Literal {
+ symbol: literal.symbol,
+ suffix: literal.suffix,
+ span: literal.span,
+ kind: literal_kind_to_internal(literal.kind),
+ };
+
+ let leaf: tt::Leaf = tt::Leaf::from(literal);
+ let tree = tt::TokenTree::from(leaf);
+ vec![tree]
+ };
+ TokenStream { token_trees }
}
bridge::TokenTree::Punct(p) => {
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 4946a4f2a6..072557913c 100644
--- a/crates/proc-macro-srv/src/server_impl/token_stream.rs
+++ b/crates/proc-macro-srv/src/server_impl/token_stream.rs
@@ -68,6 +68,11 @@ impl<S: Copy> TokenStream<S> {
span: ident.span,
}))
}
+ // Note, we do not have to assemble our `-` punct and literal split into a single
+ // negative bridge literal here. As the proc-macro docs state
+ // > Literals created from negative numbers might not survive round-trips through
+ // > TokenStream or strings and may be broken into two tokens (- and positive
+ // > literal).
tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
result.push(bridge::TokenTree::Literal(bridge::Literal {
span: lit.span,
diff --git a/crates/proc-macro-srv/src/tests/mod.rs b/crates/proc-macro-srv/src/tests/mod.rs
index 7a0ac01c50..36cd675b9a 100644
--- a/crates/proc-macro-srv/src/tests/mod.rs
+++ b/crates/proc-macro-srv/src/tests/mod.rs
@@ -248,13 +248,17 @@ fn test_fn_like_mk_literals() {
LITERAL Str string 1
LITERAL CStr cstring 1
LITERAL Float 3.14f64 1
- LITERAL Float -3.14f64 1
+ PUNCH - [alone] 1
+ LITERAL Float 3.14f64 1
+ LITERAL Float 3.14 1
+ PUNCH - [alone] 1
LITERAL Float 3.14 1
- LITERAL Float -3.14 1
LITERAL Integer 123i64 1
- LITERAL Integer -123i64 1
+ PUNCH - [alone] 1
+ LITERAL Integer 123i64 1
LITERAL Integer 123 1
- LITERAL Integer -123 1"#]],
+ PUNCH - [alone] 1
+ LITERAL Integer 123 1"#]],
expect![[r#"
SUBTREE $$ 42:[email protected]#ROOT2024 42:[email protected]#ROOT2024
@@ -266,13 +270,17 @@ fn test_fn_like_mk_literals() {
LITERAL Str string 42:[email protected]#ROOT2024
LITERAL CStr cstring 42:[email protected]#ROOT2024
LITERAL Float 3.14f64 42:[email protected]#ROOT2024
- LITERAL Float -3.14f64 42:[email protected]#ROOT2024
+ PUNCH - [alone] 42:[email protected]#ROOT2024
+ LITERAL Float 3.14f64 42:[email protected]#ROOT2024
+ LITERAL Float 3.14 42:[email protected]#ROOT2024
+ PUNCH - [alone] 42:[email protected]#ROOT2024
LITERAL Float 3.14 42:[email protected]#ROOT2024
- LITERAL Float -3.14 42:[email protected]#ROOT2024
LITERAL Integer 123i64 42:[email protected]#ROOT2024
- LITERAL Integer -123i64 42:[email protected]#ROOT2024
+ PUNCH - [alone] 42:[email protected]#ROOT2024
+ LITERAL Integer 123i64 42:[email protected]#ROOT2024
LITERAL Integer 123 42:[email protected]#ROOT2024
- LITERAL Integer -123 42:[email protected]#ROOT2024"#]],
+ PUNCH - [alone] 42:[email protected]#ROOT2024
+ LITERAL Integer 123 42:[email protected]#ROOT2024"#]],
);
}
@@ -400,7 +408,6 @@ fn test_fn_like_macro_clone_literals() {
);
}
-
#[test]
fn test_fn_like_macro_negative_literals() {
assert_expand(