Skip to content

Commit aaefc26

Browse files
authored
Merge pull request #19746 from Veykril/push-swvuyqwwplrt
fix: Fix proc-macro API creating malformed negative literals
2 parents 75af9dd + 361a927 commit aaefc26

File tree

7 files changed

+415
-44
lines changed

7 files changed

+415
-44
lines changed

crates/proc-macro-srv/proc-macro-test/imp/src/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,17 @@ pub fn fn_like_mk_literals(_args: TokenStream) -> TokenStream {
3131
TokenTree::from(Literal::byte_string(b"byte_string")),
3232
TokenTree::from(Literal::character('c')),
3333
TokenTree::from(Literal::string("string")),
34+
TokenTree::from(Literal::c_string(c"cstring")),
3435
// as of 2022-07-21, there's no method on `Literal` to build a raw
3536
// string or a raw byte string
3637
TokenTree::from(Literal::f64_suffixed(3.14)),
38+
TokenTree::from(Literal::f64_suffixed(-3.14)),
3739
TokenTree::from(Literal::f64_unsuffixed(3.14)),
40+
TokenTree::from(Literal::f64_unsuffixed(-3.14)),
3841
TokenTree::from(Literal::i64_suffixed(123)),
42+
TokenTree::from(Literal::i64_suffixed(-123)),
3943
TokenTree::from(Literal::i64_unsuffixed(123)),
44+
TokenTree::from(Literal::i64_unsuffixed(-123)),
4045
];
4146
TokenStream::from_iter(trees)
4247
}

crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs

+32-10
Original file line numberDiff line numberDiff line change
@@ -168,16 +168,38 @@ impl server::TokenStream for RaSpanServer {
168168
}
169169

170170
bridge::TokenTree::Literal(literal) => {
171-
let literal = tt::Literal {
172-
symbol: literal.symbol,
173-
suffix: literal.suffix,
174-
span: literal.span,
175-
kind: literal_kind_to_internal(literal.kind),
176-
};
177-
178-
let leaf: tt::Leaf = tt::Leaf::from(literal);
179-
let tree = tt::TokenTree::from(leaf);
180-
TokenStream { token_trees: vec![tree] }
171+
let token_trees =
172+
if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') {
173+
let punct = tt::Punct {
174+
spacing: tt::Spacing::Alone,
175+
span: literal.span,
176+
char: '-' as char,
177+
};
178+
let leaf: tt::Leaf = tt::Leaf::from(punct);
179+
let minus_tree = tt::TokenTree::from(leaf);
180+
181+
let literal = tt::Literal {
182+
symbol: Symbol::intern(symbol),
183+
suffix: literal.suffix,
184+
span: literal.span,
185+
kind: literal_kind_to_internal(literal.kind),
186+
};
187+
let leaf: tt::Leaf = tt::Leaf::from(literal);
188+
let tree = tt::TokenTree::from(leaf);
189+
vec![minus_tree, tree]
190+
} else {
191+
let literal = tt::Literal {
192+
symbol: literal.symbol,
193+
suffix: literal.suffix,
194+
span: literal.span,
195+
kind: literal_kind_to_internal(literal.kind),
196+
};
197+
198+
let leaf: tt::Leaf = tt::Leaf::from(literal);
199+
let tree = tt::TokenTree::from(leaf);
200+
vec![tree]
201+
};
202+
TokenStream { token_trees }
181203
}
182204

183205
bridge::TokenTree::Punct(p) => {

crates/proc-macro-srv/src/server_impl/token_id.rs

+32-10
Original file line numberDiff line numberDiff line change
@@ -153,16 +153,38 @@ impl server::TokenStream for TokenIdServer {
153153
}
154154

155155
bridge::TokenTree::Literal(literal) => {
156-
let literal = Literal {
157-
symbol: literal.symbol,
158-
suffix: literal.suffix,
159-
span: literal.span,
160-
kind: literal_kind_to_internal(literal.kind),
161-
};
162-
163-
let leaf = tt::Leaf::from(literal);
164-
let tree = TokenTree::from(leaf);
165-
TokenStream { token_trees: vec![tree] }
156+
let token_trees =
157+
if let Some((_minus, symbol)) = literal.symbol.as_str().split_once('-') {
158+
let punct = tt::Punct {
159+
spacing: tt::Spacing::Alone,
160+
span: literal.span,
161+
char: '-' as char,
162+
};
163+
let leaf: tt::Leaf = tt::Leaf::from(punct);
164+
let minus_tree = tt::TokenTree::from(leaf);
165+
166+
let literal = Literal {
167+
symbol: Symbol::intern(symbol),
168+
suffix: literal.suffix,
169+
span: literal.span,
170+
kind: literal_kind_to_internal(literal.kind),
171+
};
172+
let leaf: tt::Leaf = tt::Leaf::from(literal);
173+
let tree = tt::TokenTree::from(leaf);
174+
vec![minus_tree, tree]
175+
} else {
176+
let literal = Literal {
177+
symbol: literal.symbol,
178+
suffix: literal.suffix,
179+
span: literal.span,
180+
kind: literal_kind_to_internal(literal.kind),
181+
};
182+
183+
let leaf: tt::Leaf = tt::Leaf::from(literal);
184+
let tree = tt::TokenTree::from(leaf);
185+
vec![tree]
186+
};
187+
TokenStream { token_trees }
166188
}
167189

168190
bridge::TokenTree::Punct(p) => {

crates/proc-macro-srv/src/server_impl/token_stream.rs

+5
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ impl<S: Copy> TokenStream<S> {
6868
span: ident.span,
6969
}))
7070
}
71+
// Note, we do not have to assemble our `-` punct and literal split into a single
72+
// negative bridge literal here. As the proc-macro docs state
73+
// > Literals created from negative numbers might not survive round-trips through
74+
// > TokenStream or strings and may be broken into two tokens (- and positive
75+
// > literal).
7176
tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
7277
result.push(bridge::TokenTree::Literal(bridge::Literal {
7378
span: lit.span,

0 commit comments

Comments
 (0)