Skip to content

Commit ca2b2ed

Browse files
mystordtolnay
authored andcommitted
Use Ident::new_raw to quote raw identifiers
This requires the changes in dtolnay/proc-macro2#331 which expose Ident::new_raw from proc-macro2, along with providing a fallback for earlier versions of Rust. Fixes #223
1 parent eeabf0d commit ca2b2ed

2 files changed

Lines changed: 7 additions & 45 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ autobenches = false
1414
rust-version = "1.31"
1515

1616
[dependencies]
17-
proc-macro2 = { version = "1.0.36", default-features = false }
17+
proc-macro2 = { version = "1.0.40", default-features = false }
1818

1919
[dev-dependencies]
2020
rustversion = "1.0"

src/runtime.rs

Lines changed: 6 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -205,27 +205,11 @@ fn respan_token_tree(mut token: TokenTree, span: Span) -> TokenTree {
205205
}
206206

207207
pub fn push_ident(tokens: &mut TokenStream, s: &str) {
208-
// Optimization over `mk_ident`, as `s` is guaranteed to be a valid ident.
209-
//
210-
// FIXME: When `Ident::new_raw` becomes stable, this method should be
211-
// updated to call it when available.
212-
if s.starts_with("r#") {
213-
parse(tokens, s);
214-
} else {
215-
tokens.append(Ident::new(s, Span::call_site()));
216-
}
208+
tokens.append(mk_ident(s, None));
217209
}
218210

219211
pub fn push_ident_spanned(tokens: &mut TokenStream, span: Span, s: &str) {
220-
// Optimization over `mk_ident`, as `s` is guaranteed to be a valid ident.
221-
//
222-
// FIXME: When `Ident::new_raw` becomes stable, this method should be
223-
// updated to call it when available.
224-
if s.starts_with("r#") {
225-
parse_spanned(tokens, span, s);
226-
} else {
227-
tokens.append(Ident::new(s, span));
228-
}
212+
tokens.append(mk_ident(s, Some(span)));
229213
}
230214

231215
pub fn push_lifetime(tokens: &mut TokenStream, lifetime: &str) {
@@ -392,36 +376,14 @@ pub fn push_underscore_spanned(tokens: &mut TokenStream, span: Span) {
392376

393377
// Helper method for constructing identifiers from the `format_ident!` macro,
394378
// handling `r#` prefixes.
395-
//
396-
// Directly parsing the input string may produce a valid identifier,
397-
// although the input string was invalid, due to ignored characters such as
398-
// whitespace and comments. Instead, we always create a non-raw identifier
399-
// to validate that the string is OK, and only parse again if needed.
400379
pub fn mk_ident(id: &str, span: Option<Span>) -> Ident {
401380
let span = span.unwrap_or_else(Span::call_site);
402381

403-
let is_raw = id.starts_with("r#");
404-
let unraw = Ident::new(if is_raw { &id[2..] } else { id }, span);
405-
if !is_raw {
406-
return unraw;
407-
}
408-
409-
// At this point, the identifier is raw, and the unraw-ed version of it was
410-
// successfully converted into an identifier. Try to produce a valid raw
411-
// identifier by running the `TokenStream` parser, and unwrapping the first
412-
// token as an `Ident`.
413-
//
414-
// FIXME: When `Ident::new_raw` becomes stable, this method should be
415-
// updated to call it when available.
416-
if let Ok(ts) = id.parse::<TokenStream>() {
417-
let mut iter = ts.into_iter();
418-
if let (Some(TokenTree::Ident(mut id)), None) = (iter.next(), iter.next()) {
419-
id.set_span(span);
420-
return id;
421-
}
382+
if id.starts_with("r#") {
383+
Ident::new_raw(&id[2..], span)
384+
} else {
385+
Ident::new(id, span)
422386
}
423-
424-
panic!("not allowed as a raw identifier: `{}`", id);
425387
}
426388

427389
// Adapts from `IdentFragment` to `fmt::Display` for use by the `format_ident!`

0 commit comments

Comments
 (0)