Skip to content

Commit 37a6f41

Browse files
committed
proc_macro: don't use an opaque libsyntax Token in Literal.
1 parent 341edae commit 37a6f41

File tree

3 files changed

+157
-101
lines changed

3 files changed

+157
-101
lines changed

src/libproc_macro/lib.rs

Lines changed: 83 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ use std::{ascii, fmt, iter};
6767
use std::path::PathBuf;
6868
use std::str::FromStr;
6969

70-
use syntax::parse::token;
7170
use syntax::symbol::Symbol;
7271

7372
/// The main type provided by this crate, representing an abstract stream of
@@ -429,14 +428,39 @@ pub enum Spacing {
429428
}
430429

431430
/// A literal character (`'a'`), string (`"hello"`), or number (`2.3`).
432-
#[derive(Clone, Debug)]
431+
#[derive(Clone)]
432+
#[unstable(feature = "proc_macro", issue = "38356")]
433+
pub struct Literal {
434+
#[unstable(feature = "proc_macro_internals", issue = "27812")]
435+
#[doc(hidden)]
436+
pub kind: LiteralKind,
437+
438+
#[unstable(feature = "proc_macro_internals", issue = "27812")]
439+
#[doc(hidden)]
440+
pub contents: Term,
441+
442+
#[unstable(feature = "proc_macro_internals", issue = "27812")]
443+
#[doc(hidden)]
444+
pub suffix: Option<Term>,
445+
}
446+
433447
#[unstable(feature = "proc_macro", issue = "38356")]
434-
pub struct Literal(token::Token);
448+
impl fmt::Debug for Literal {
449+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
450+
fmt::Debug::fmt(&TokenTree {
451+
kind: TokenNode::Literal(self.clone()),
452+
span: Span::def_site()
453+
}, f)
454+
}
455+
}
435456

436457
#[unstable(feature = "proc_macro", issue = "38356")]
437458
impl fmt::Display for Literal {
438459
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
439-
TokenTree { kind: TokenNode::Literal(self.clone()), span: Span::def_site() }.fmt(f)
460+
fmt::Display::fmt(&TokenTree {
461+
kind: TokenNode::Literal(self.clone()),
462+
span: Span::def_site()
463+
}, f)
440464
}
441465
}
442466

@@ -454,13 +478,20 @@ impl Literal {
454478
/// Integer literal
455479
#[unstable(feature = "proc_macro", issue = "38356")]
456480
pub fn integer(n: i128) -> Literal {
457-
Literal(token::Literal(token::Lit::Integer(Symbol::intern(&n.to_string())), None))
481+
Literal {
482+
kind: LiteralKind::Integer,
483+
contents: Term::intern(&n.to_string()),
484+
suffix: None,
485+
}
458486
}
459487

460488
int_literals!(u8, i8, u16, i16, u32, i32, u64, i64, usize, isize);
461489
fn typed_integer(n: i128, kind: &'static str) -> Literal {
462-
Literal(token::Literal(token::Lit::Integer(Symbol::intern(&n.to_string())),
463-
Some(Symbol::intern(kind))))
490+
Literal {
491+
kind: LiteralKind::Integer,
492+
contents: Term::intern(&n.to_string()),
493+
suffix: Some(Term::intern(kind)),
494+
}
464495
}
465496

466497
/// Floating point literal.
@@ -469,7 +500,11 @@ impl Literal {
469500
if !n.is_finite() {
470501
panic!("Invalid float literal {}", n);
471502
}
472-
Literal(token::Literal(token::Lit::Float(Symbol::intern(&n.to_string())), None))
503+
Literal {
504+
kind: LiteralKind::Float,
505+
contents: Term::intern(&n.to_string()),
506+
suffix: None,
507+
}
473508
}
474509

475510
/// Floating point literal.
@@ -478,8 +513,11 @@ impl Literal {
478513
if !n.is_finite() {
479514
panic!("Invalid f32 literal {}", n);
480515
}
481-
Literal(token::Literal(token::Lit::Float(Symbol::intern(&n.to_string())),
482-
Some(Symbol::intern("f32"))))
516+
Literal {
517+
kind: LiteralKind::Float,
518+
contents: Term::intern(&n.to_string()),
519+
suffix: Some(Term::intern("f32")),
520+
}
483521
}
484522

485523
/// Floating point literal.
@@ -488,8 +526,11 @@ impl Literal {
488526
if !n.is_finite() {
489527
panic!("Invalid f64 literal {}", n);
490528
}
491-
Literal(token::Literal(token::Lit::Float(Symbol::intern(&n.to_string())),
492-
Some(Symbol::intern("f64"))))
529+
Literal {
530+
kind: LiteralKind::Float,
531+
contents: Term::intern(&n.to_string()),
532+
suffix: Some(Term::intern("f64")),
533+
}
493534
}
494535

495536
/// String literal.
@@ -499,89 +540,54 @@ impl Literal {
499540
for ch in string.chars() {
500541
escaped.extend(ch.escape_debug());
501542
}
502-
Literal(token::Literal(token::Lit::Str_(Symbol::intern(&escaped)), None))
543+
Literal {
544+
kind: LiteralKind::Str_,
545+
contents: Term::intern(&escaped),
546+
suffix: None,
547+
}
503548
}
504549

505550
/// Character literal.
506551
#[unstable(feature = "proc_macro", issue = "38356")]
507552
pub fn character(ch: char) -> Literal {
508553
let mut escaped = String::new();
509554
escaped.extend(ch.escape_unicode());
510-
Literal(token::Literal(token::Lit::Char(Symbol::intern(&escaped)), None))
555+
Literal {
556+
kind: LiteralKind::Char,
557+
contents: Term::intern(&escaped),
558+
suffix: None,
559+
}
511560
}
512561

513562
/// Byte string literal.
514563
#[unstable(feature = "proc_macro", issue = "38356")]
515564
pub fn byte_string(bytes: &[u8]) -> Literal {
516565
let string = bytes.iter().cloned().flat_map(ascii::escape_default)
517566
.map(Into::<char>::into).collect::<String>();
518-
Literal(token::Literal(token::Lit::ByteStr(Symbol::intern(&string)), None))
519-
}
520-
}
521-
522-
macro_rules! literals {
523-
($($i:ident),*; $($raw:ident),*) => {
524-
#[unstable(feature = "proc_macro_internals", issue = "27812")]
525-
#[doc(hidden)]
526-
pub enum LiteralKind {
527-
$($i,)*
528-
$($raw(usize),)*
529-
}
530-
531-
impl LiteralKind {
532-
#[unstable(feature = "proc_macro_internals", issue = "27812")]
533-
#[doc(hidden)]
534-
pub fn with_contents_and_suffix(self, contents: Term, suffix: Option<Term>)
535-
-> Literal {
536-
let contents = contents.0;
537-
let suffix = suffix.map(|t| t.0);
538-
match self {
539-
$(LiteralKind::$i => {
540-
Literal(token::Literal(token::Lit::$i(contents), suffix))
541-
})*
542-
$(LiteralKind::$raw(n) => {
543-
Literal(token::Literal(token::Lit::$raw(contents, n), suffix))
544-
})*
545-
}
546-
}
547-
}
548-
549-
impl Literal {
550-
fn kind(&self) -> LiteralKind {
551-
let lit = match self.0 {
552-
token::Literal(lit, _) => lit,
553-
_ => panic!("unsupported literal {:?}", self.0),
554-
};
555-
556-
match lit {
557-
$(token::Lit::$i(_) => LiteralKind::$i,)*
558-
$(token::Lit::$raw(_, n) => LiteralKind::$raw(n),)*
559-
}
560-
}
561-
562-
fn contents(&self) -> Term {
563-
let lit = match self.0 {
564-
token::Literal(lit, _) => lit,
565-
_ => panic!("unsupported literal {:?}", self.0),
566-
};
567-
568-
match lit {
569-
$(token::Lit::$i(contents))|* |
570-
$(token::Lit::$raw(contents, _))|* => Term(contents)
571-
}
572-
}
573-
574-
fn suffix(&self) -> Option<Term> {
575-
match self.0 {
576-
token::Literal(_, suffix) => suffix.map(Term),
577-
_ => panic!("unsupported literal {:?}", self.0),
578-
}
579-
}
567+
Literal {
568+
kind: LiteralKind::ByteStr,
569+
contents: Term::intern(&string),
570+
suffix: None,
580571
}
581572
}
582573
}
583574

584-
literals!(Byte, Char, Float, Str_, Integer, ByteStr; StrRaw, ByteStrRaw);
575+
#[derive(Copy, Clone)]
576+
#[unstable(feature = "proc_macro_internals", issue = "27812")]
577+
#[doc(hidden)]
578+
pub enum LiteralKind {
579+
DocComment,
580+
581+
Byte,
582+
Char,
583+
Float,
584+
Str_,
585+
Integer,
586+
ByteStr,
587+
588+
StrRaw(usize),
589+
ByteStrRaw(usize),
590+
}
585591

586592
/// An iterator over `TokenTree`s.
587593
#[derive(Clone)]

src/libproc_macro/quote.rs

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -151,35 +151,31 @@ impl Quote for Span {
151151
}
152152
}
153153

154-
macro_rules! literals {
155-
($($i:ident),*; $($raw:ident),*) => {
156-
impl Quote for LiteralKind {
157-
fn quote(self) -> TokenStream {
154+
impl Quote for LiteralKind {
155+
fn quote(self) -> TokenStream {
156+
macro_rules! gen_match {
157+
($($i:ident),*; $($raw:ident),*) => {
158158
match self {
159-
$(LiteralKind::$i => quote! {
160-
::LiteralKind::$i
161-
},)*
162-
$(LiteralKind::$raw(n) => quote! {
163-
::LiteralKind::$raw((quote n))
164-
},)*
159+
$(LiteralKind::$i => quote!(::LiteralKind::$i),)*
160+
$(LiteralKind::$raw(n) => quote!(::LiteralKind::$raw((quote n))),)*
165161
}
166162
}
167163
}
168164

169-
impl Quote for Literal {
170-
fn quote(self) -> TokenStream {
171-
let kind = self.kind();
172-
let contents = self.contents();
173-
let suffix = self.suffix();
174-
quote! {
175-
(quote kind).with_contents_and_suffix((quote contents), (quote suffix))
176-
}
177-
}
178-
}
165+
gen_match!(DocComment, Byte, Char, Float, Str_, Integer, ByteStr; StrRaw, ByteStrRaw)
179166
}
180167
}
181168

182-
literals!(Byte, Char, Float, Str_, Integer, ByteStr; StrRaw, ByteStrRaw);
169+
170+
impl Quote for Literal {
171+
fn quote(self) -> TokenStream {
172+
quote!(::Literal {
173+
kind: (quote self.kind),
174+
contents: (quote self.contents),
175+
suffix: (quote self.suffix),
176+
})
177+
}
178+
}
183179

184180
impl Quote for Delimiter {
185181
fn quote(self) -> TokenStream {

src/libproc_macro/rustc.rs

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use {Delimiter, Spacing, Term, TokenNode};
11+
use {Delimiter, Literal, LiteralKind, Spacing, Term, TokenNode};
1212

1313
use rustc_data_structures::sync::Lrc;
1414
use rustc_errors::{Diagnostic, DiagnosticBuilder, Level};
@@ -69,6 +69,56 @@ impl Delimiter {
6969
}
7070
}
7171

72+
macro_rules! literals {
73+
($($i:ident),*; $($raw:ident),*) => {
74+
impl Literal {
75+
fn from_internal(token: token::Token) -> Self {
76+
let (lit, suffix) = match token {
77+
token::Literal(lit, suffix) => (lit, suffix),
78+
token::DocComment(contents) => {
79+
return Literal {
80+
kind: LiteralKind::DocComment,
81+
contents: Term(contents),
82+
suffix: None
83+
};
84+
}
85+
_ => panic!("unsupported literal {:?}", token),
86+
};
87+
88+
let (kind, contents) = match lit {
89+
$(token::Lit::$i(contents) => (LiteralKind::$i, contents),)*
90+
$(token::Lit::$raw(contents, n) => (LiteralKind::$raw(n), contents),)*
91+
};
92+
93+
Literal {
94+
kind,
95+
contents: Term(contents),
96+
suffix: suffix.map(Term)
97+
}
98+
}
99+
100+
fn to_internal(self) -> token::Token {
101+
let contents = self.contents.0;
102+
let suffix = self.suffix.map(|t| t.0);
103+
match self.kind {
104+
LiteralKind::DocComment => {
105+
assert_eq!(suffix, None);
106+
token::DocComment(contents)
107+
}
108+
$(LiteralKind::$i => {
109+
token::Literal(token::Lit::$i(contents), suffix)
110+
})*
111+
$(LiteralKind::$raw(n) => {
112+
token::Literal(token::Lit::$raw(contents, n), suffix)
113+
})*
114+
}
115+
}
116+
}
117+
}
118+
}
119+
120+
literals!(Byte, Char, Float, Str_, Integer, ByteStr; StrRaw, ByteStrRaw);
121+
72122
pub struct Rustc<'a> {
73123
sess: &'a ParseSess,
74124
mark: Mark,
@@ -134,7 +184,9 @@ impl<'a> ::bridge::FrontendInterface for Rustc<'a> {
134184
};
135185
return TokenTree::Token(span, token).into();
136186
}
137-
TokenNode::Literal(token) => return TokenTree::Token(span, token.0).into(),
187+
TokenNode::Literal(literal) => {
188+
return TokenTree::Token(span, literal.to_internal()).into()
189+
}
138190
};
139191

140192
let token = match op {
@@ -255,7 +307,9 @@ impl<'a> ::bridge::FrontendInterface for Rustc<'a> {
255307
Question => op!('?'),
256308

257309
Ident(ident) | Lifetime(ident) => TokenNode::Term(Term(ident.name)),
258-
Literal(..) | DocComment(..) => TokenNode::Literal(::Literal(token)),
310+
Literal(..) | DocComment(..) => {
311+
TokenNode::Literal(::Literal::from_internal(token))
312+
}
259313

260314
Interpolated(_) => {
261315
let tts = token.interpolated_to_tokenstream(self.sess, span);

0 commit comments

Comments
 (0)