blob: 627ec393039ea88d05fadc569e6fff276d8b80f8 [file] [log] [blame]
Alex Crichton1fd0e8a2018-02-04 21:29:13 -08001//! A "shim crate" intended to multiplex the [`proc_macro`] API on to stable
2//! Rust.
Alex Crichtonbabc99e2017-07-05 18:00:29 -07003//!
4//! Procedural macros in Rust operate over the upstream
Alex Crichton1fd0e8a2018-02-04 21:29:13 -08005//! [`proc_macro::TokenStream`][ts] type. This type currently is quite
6//! conservative and exposed no internal implementation details. Nightly
7//! compilers, however, contain a much richer interface. This richer interface
8//! allows fine-grained inspection of the token stream which avoids
9//! stringification/re-lexing and also preserves span information.
Alex Crichtonbabc99e2017-07-05 18:00:29 -070010//!
Alex Crichton1fd0e8a2018-02-04 21:29:13 -080011//! The upcoming APIs added to [`proc_macro`] upstream are the foundation for
Alex Crichtonbabc99e2017-07-05 18:00:29 -070012//! productive procedural macros in the ecosystem. To help prepare the ecosystem
13//! for using them this crate serves to both compile on stable and nightly and
14//! mirrors the API-to-be. The intention is that procedural macros which switch
15//! to use this crate will be trivially able to switch to the upstream
16//! `proc_macro` crate once its API stabilizes.
17//!
David Tolnayd66ecf62018-01-02 20:05:42 -080018//! In the meantime this crate also has a `nightly` Cargo feature which
Alex Crichton1fd0e8a2018-02-04 21:29:13 -080019//! enables it to reimplement itself with the unstable API of [`proc_macro`].
Alex Crichtonbabc99e2017-07-05 18:00:29 -070020//! This'll allow immediate usage of the beneficial upstream API, particularly
21//! around preserving span information.
Alex Crichton1fd0e8a2018-02-04 21:29:13 -080022//!
23//! [`proc_macro`]: https://doc.rust-lang.org/proc_macro/
24//! [ts]: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html
Alex Crichtonbabc99e2017-07-05 18:00:29 -070025
David Tolnay15cc4982018-01-08 08:03:27 -080026// Proc-macro2 types in rustdoc of other crates get linked to here.
David Tolnaye3573b92018-03-31 21:28:47 +020027#![doc(html_root_url = "https://docs.rs/proc-macro2/0.3.1")]
David Tolnayd66ecf62018-01-02 20:05:42 -080028#![cfg_attr(feature = "nightly", feature(proc_macro))]
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070029
Alex Crichton0e8e7f42018-02-22 06:15:13 -080030#[cfg(feature = "proc-macro")]
Alex Crichton44bffbc2017-05-19 17:51:59 -070031extern crate proc_macro;
32
David Tolnayd66ecf62018-01-02 20:05:42 -080033#[cfg(not(feature = "nightly"))]
David Tolnayb1032662017-05-31 15:52:28 -070034extern crate unicode_xid;
Alex Crichton44bffbc2017-05-19 17:51:59 -070035
36use std::fmt;
Alex Crichton44bffbc2017-05-19 17:51:59 -070037use std::iter::FromIterator;
Alex Crichtonaf5bad42018-03-27 14:45:10 -070038use std::marker;
39use std::rc::Rc;
40use std::str::FromStr;
Alex Crichton44bffbc2017-05-19 17:51:59 -070041
David Tolnayb1032662017-05-31 15:52:28 -070042#[macro_use]
David Tolnayd66ecf62018-01-02 20:05:42 -080043#[cfg(not(feature = "nightly"))]
David Tolnayb1032662017-05-31 15:52:28 -070044mod strnom;
45
Alex Crichton44bffbc2017-05-19 17:51:59 -070046#[path = "stable.rs"]
David Tolnayd66ecf62018-01-02 20:05:42 -080047#[cfg(not(feature = "nightly"))]
Alex Crichtonb15c6352017-05-19 19:36:36 -070048mod imp;
49#[path = "unstable.rs"]
David Tolnayd66ecf62018-01-02 20:05:42 -080050#[cfg(feature = "nightly")]
Alex Crichton44bffbc2017-05-19 17:51:59 -070051mod imp;
52
David Tolnaycb1b85f2017-06-03 16:40:35 -070053#[derive(Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -070054pub struct TokenStream {
55 inner: imp::TokenStream,
56 _marker: marker::PhantomData<Rc<()>>,
57}
Alex Crichton44bffbc2017-05-19 17:51:59 -070058
Alex Crichtonaf5bad42018-03-27 14:45:10 -070059pub struct LexError {
60 inner: imp::LexError,
61 _marker: marker::PhantomData<Rc<()>>,
62}
63
64impl TokenStream {
65 fn _new(inner: imp::TokenStream) -> TokenStream {
66 TokenStream {
67 inner: inner,
68 _marker: marker::PhantomData,
69 }
70 }
71
72 pub fn empty() -> TokenStream {
73 TokenStream::_new(imp::TokenStream::empty())
74 }
75
76 pub fn is_empty(&self) -> bool {
77 self.inner.is_empty()
78 }
79}
Alex Crichton44bffbc2017-05-19 17:51:59 -070080
81impl FromStr for TokenStream {
82 type Err = LexError;
83
84 fn from_str(src: &str) -> Result<TokenStream, LexError> {
David Tolnayb28f38a2018-03-31 22:02:29 +020085 let e = src.parse().map_err(|e| LexError {
86 inner: e,
87 _marker: marker::PhantomData,
Alex Crichtonaf5bad42018-03-27 14:45:10 -070088 })?;
89 Ok(TokenStream::_new(e))
Alex Crichton44bffbc2017-05-19 17:51:59 -070090 }
91}
92
Alex Crichton0e8e7f42018-02-22 06:15:13 -080093#[cfg(feature = "proc-macro")]
Alex Crichton44bffbc2017-05-19 17:51:59 -070094impl From<proc_macro::TokenStream> for TokenStream {
95 fn from(inner: proc_macro::TokenStream) -> TokenStream {
Alex Crichtonaf5bad42018-03-27 14:45:10 -070096 TokenStream::_new(inner.into())
Alex Crichton44bffbc2017-05-19 17:51:59 -070097 }
98}
99
Alex Crichton0e8e7f42018-02-22 06:15:13 -0800100#[cfg(feature = "proc-macro")]
Alex Crichton44bffbc2017-05-19 17:51:59 -0700101impl From<TokenStream> for proc_macro::TokenStream {
102 fn from(inner: TokenStream) -> proc_macro::TokenStream {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700103 inner.inner.into()
Alex Crichton44bffbc2017-05-19 17:51:59 -0700104 }
105}
106
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700107impl FromIterator<TokenTree> for TokenStream {
108 fn from_iter<I: IntoIterator<Item = TokenTree>>(streams: I) -> Self {
109 TokenStream::_new(streams.into_iter().collect())
Alex Crichton44bffbc2017-05-19 17:51:59 -0700110 }
111}
112
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700113impl fmt::Display for TokenStream {
114 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
115 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700116 }
117}
118
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700119impl fmt::Debug for TokenStream {
120 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
121 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700122 }
123}
124
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700125impl fmt::Debug for LexError {
126 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
127 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700128 }
129}
130
Nika Layzellb35a9a32017-12-30 14:34:35 -0500131// Returned by reference, so we can't easily wrap it.
David Tolnay1ebe3972018-01-02 20:14:20 -0800132#[cfg(procmacro2_semver_exempt)]
Nika Layzellb35a9a32017-12-30 14:34:35 -0500133pub use imp::FileName;
134
David Tolnay1ebe3972018-01-02 20:14:20 -0800135#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500136#[derive(Clone, PartialEq, Eq)]
137pub struct SourceFile(imp::SourceFile);
138
David Tolnay1ebe3972018-01-02 20:14:20 -0800139#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500140impl SourceFile {
141 /// Get the path to this source file as a string.
Nika Layzellb35a9a32017-12-30 14:34:35 -0500142 pub fn path(&self) -> &FileName {
143 self.0.path()
Nika Layzellf8d5f212017-12-11 14:07:02 -0500144 }
145
146 pub fn is_real(&self) -> bool {
147 self.0.is_real()
148 }
149}
150
David Tolnay1ebe3972018-01-02 20:14:20 -0800151#[cfg(procmacro2_semver_exempt)]
Nika Layzellb35a9a32017-12-30 14:34:35 -0500152impl AsRef<FileName> for SourceFile {
153 fn as_ref(&self) -> &FileName {
154 self.0.path()
Nika Layzellf8d5f212017-12-11 14:07:02 -0500155 }
156}
157
David Tolnay1ebe3972018-01-02 20:14:20 -0800158#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500159impl fmt::Debug for SourceFile {
160 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
161 self.0.fmt(f)
162 }
163}
164
David Tolnay1ebe3972018-01-02 20:14:20 -0800165#[cfg(procmacro2_semver_exempt)]
Nika Layzell1ecb6ce2017-12-30 14:34:05 -0500166pub struct LineColumn {
167 pub line: usize,
168 pub column: usize,
169}
Nika Layzellf8d5f212017-12-11 14:07:02 -0500170
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700171#[derive(Copy, Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700172pub struct Span {
173 inner: imp::Span,
174 _marker: marker::PhantomData<Rc<()>>,
175}
Alex Crichton44bffbc2017-05-19 17:51:59 -0700176
Alex Crichton44bffbc2017-05-19 17:51:59 -0700177impl Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700178 fn _new(inner: imp::Span) -> Span {
179 Span {
180 inner: inner,
181 _marker: marker::PhantomData,
182 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700183 }
Alex Crichtone6085b72017-11-21 07:24:25 -0800184
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700185 pub fn call_site() -> Span {
186 Span::_new(imp::Span::call_site())
187 }
188
189 #[cfg(procmacro2_semver_exempt)]
Alex Crichtone6085b72017-11-21 07:24:25 -0800190 pub fn def_site() -> Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700191 Span::_new(imp::Span::def_site())
Alex Crichtone6085b72017-11-21 07:24:25 -0800192 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500193
David Tolnay4e8e3972018-01-05 18:10:22 -0800194 /// Creates a new span with the same line/column information as `self` but
195 /// that resolves symbols as though it were at `other`.
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700196 #[cfg(procmacro2_semver_exempt)]
David Tolnay4e8e3972018-01-05 18:10:22 -0800197 pub fn resolved_at(&self, other: Span) -> Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700198 Span::_new(self.inner.resolved_at(other.inner))
David Tolnay4e8e3972018-01-05 18:10:22 -0800199 }
200
201 /// Creates a new span with the same name resolution behavior as `self` but
202 /// with the line/column information of `other`.
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700203 #[cfg(procmacro2_semver_exempt)]
David Tolnay4e8e3972018-01-05 18:10:22 -0800204 pub fn located_at(&self, other: Span) -> Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700205 Span::_new(self.inner.located_at(other.inner))
David Tolnay4e8e3972018-01-05 18:10:22 -0800206 }
207
David Tolnayd66ecf62018-01-02 20:05:42 -0800208 /// This method is only available when the `"nightly"` feature is enabled.
Alex Crichton0e8e7f42018-02-22 06:15:13 -0800209 #[cfg(all(feature = "nightly", feature = "proc-macro"))]
David Tolnay16a17202017-12-31 10:47:24 -0500210 pub fn unstable(self) -> proc_macro::Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700211 self.inner.unstable()
David Tolnay16a17202017-12-31 10:47:24 -0500212 }
213
David Tolnay1ebe3972018-01-02 20:14:20 -0800214 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500215 pub fn source_file(&self) -> SourceFile {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700216 SourceFile(self.inner.source_file())
Nika Layzellf8d5f212017-12-11 14:07:02 -0500217 }
218
David Tolnay1ebe3972018-01-02 20:14:20 -0800219 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500220 pub fn start(&self) -> LineColumn {
David Tolnayb28f38a2018-03-31 22:02:29 +0200221 let imp::LineColumn { line, column } = self.inner.start();
222 LineColumn {
223 line: line,
224 column: column,
225 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500226 }
227
David Tolnay1ebe3972018-01-02 20:14:20 -0800228 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500229 pub fn end(&self) -> LineColumn {
David Tolnayb28f38a2018-03-31 22:02:29 +0200230 let imp::LineColumn { line, column } = self.inner.end();
231 LineColumn {
232 line: line,
233 column: column,
234 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500235 }
236
David Tolnay1ebe3972018-01-02 20:14:20 -0800237 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500238 pub fn join(&self, other: Span) -> Option<Span> {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700239 self.inner.join(other.inner).map(Span::_new)
240 }
Alex Crichtonb2c94622018-04-04 07:36:41 -0700241
242 #[cfg(procmacro2_semver_exempt)]
243 pub fn eq(&self, other: &Span) -> bool {
244 self.inner.eq(&other.inner)
245 }
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700246}
247
248impl fmt::Debug for Span {
249 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
250 self.inner.fmt(f)
Nika Layzellf8d5f212017-12-11 14:07:02 -0500251 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700252}
253
David Tolnay977f8282017-05-31 17:41:33 -0700254#[derive(Clone, Debug)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700255pub enum TokenTree {
256 Group(Group),
257 Term(Term),
258 Op(Op),
259 Literal(Literal),
Alex Crichton1a7f7622017-07-05 17:47:15 -0700260}
261
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700262impl TokenTree {
263 pub fn span(&self) -> Span {
264 match *self {
265 TokenTree::Group(ref t) => t.span(),
266 TokenTree::Term(ref t) => t.span(),
267 TokenTree::Op(ref t) => t.span(),
268 TokenTree::Literal(ref t) => t.span(),
269 }
270 }
271
272 pub fn set_span(&mut self, span: Span) {
273 match *self {
274 TokenTree::Group(ref mut t) => t.set_span(span),
275 TokenTree::Term(ref mut t) => t.set_span(span),
276 TokenTree::Op(ref mut t) => t.set_span(span),
277 TokenTree::Literal(ref mut t) => t.set_span(span),
278 }
279 }
280}
281
282impl From<Group> for TokenTree {
283 fn from(g: Group) -> TokenTree {
284 TokenTree::Group(g)
285 }
286}
287
288impl From<Term> for TokenTree {
289 fn from(g: Term) -> TokenTree {
290 TokenTree::Term(g)
291 }
292}
293
294impl From<Op> for TokenTree {
295 fn from(g: Op) -> TokenTree {
296 TokenTree::Op(g)
297 }
298}
299
300impl From<Literal> for TokenTree {
301 fn from(g: Literal) -> TokenTree {
302 TokenTree::Literal(g)
Alex Crichton1a7f7622017-07-05 17:47:15 -0700303 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700304}
305
Alex Crichton44bffbc2017-05-19 17:51:59 -0700306impl fmt::Display for TokenTree {
307 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700308 match *self {
309 TokenTree::Group(ref t) => t.fmt(f),
310 TokenTree::Term(ref t) => t.fmt(f),
311 TokenTree::Op(ref t) => t.fmt(f),
312 TokenTree::Literal(ref t) => t.fmt(f),
313 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700314 }
315}
316
David Tolnay977f8282017-05-31 17:41:33 -0700317#[derive(Clone, Debug)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700318pub struct Group {
319 delimiter: Delimiter,
320 stream: TokenStream,
321 span: Span,
Alex Crichton44bffbc2017-05-19 17:51:59 -0700322}
323
Michael Layzell5372f4b2017-06-02 10:29:31 -0400324#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Alex Crichton44bffbc2017-05-19 17:51:59 -0700325pub enum Delimiter {
326 Parenthesis,
327 Brace,
328 Bracket,
329 None,
330}
331
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700332impl Group {
333 pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
334 Group {
335 delimiter: delimiter,
336 stream: stream,
337 span: Span::call_site(),
338 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700339 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700340
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700341 pub fn delimiter(&self) -> Delimiter {
342 self.delimiter
Alex Crichton44bffbc2017-05-19 17:51:59 -0700343 }
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700344
345 pub fn stream(&self) -> TokenStream {
346 self.stream.clone()
347 }
348
349 pub fn span(&self) -> Span {
350 self.span
351 }
352
353 pub fn set_span(&mut self, span: Span) {
354 self.span = span;
355 }
356}
357
358impl fmt::Display for Group {
359 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
360 self.stream.fmt(f)
361 }
362}
363
364#[derive(Copy, Clone, Debug)]
365pub struct Op {
366 op: char,
367 spacing: Spacing,
368 span: Span,
Alex Crichton44bffbc2017-05-19 17:51:59 -0700369}
370
Lukas Kalbertodteb3f9302017-08-20 18:58:41 +0200371#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Alex Crichton1a7f7622017-07-05 17:47:15 -0700372pub enum Spacing {
Alex Crichton44bffbc2017-05-19 17:51:59 -0700373 Alone,
374 Joint,
375}
376
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700377impl Op {
378 pub fn new(op: char, spacing: Spacing) -> Op {
379 Op {
380 op: op,
381 spacing: spacing,
382 span: Span::call_site(),
383 }
384 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700385
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700386 pub fn op(&self) -> char {
387 self.op
388 }
389
390 pub fn spacing(&self) -> Spacing {
391 self.spacing
392 }
393
394 pub fn span(&self) -> Span {
395 self.span
396 }
397
398 pub fn set_span(&mut self, span: Span) {
399 self.span = span;
400 }
401}
402
403impl fmt::Display for Op {
404 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
405 self.op.fmt(f)
406 }
407}
408
409#[derive(Copy, Clone)]
410pub struct Term {
411 inner: imp::Term,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700412 _marker: marker::PhantomData<Rc<()>>,
413}
414
415impl Term {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700416 fn _new(inner: imp::Term) -> Term {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700417 Term {
418 inner: inner,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700419 _marker: marker::PhantomData,
420 }
421 }
422
423 pub fn new(string: &str, span: Span) -> Term {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700424 Term::_new(imp::Term::new(string, span.inner))
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700425 }
426
427 pub fn as_str(&self) -> &str {
428 self.inner.as_str()
429 }
430
431 pub fn span(&self) -> Span {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700432 Span::_new(self.inner.span())
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700433 }
434
435 pub fn set_span(&mut self, span: Span) {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700436 self.inner.set_span(span.inner);
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700437 }
438}
439
440impl fmt::Display for Term {
441 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
442 self.as_str().fmt(f)
443 }
444}
445
446impl fmt::Debug for Term {
447 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
448 self.inner.fmt(f)
449 }
450}
451
452#[derive(Clone)]
453pub struct Literal {
454 inner: imp::Literal,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700455 _marker: marker::PhantomData<Rc<()>>,
456}
457
Alex Crichtona914a612018-04-04 07:48:44 -0700458macro_rules! int_literals {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700459 ($($name:ident => $kind:ident,)*) => ($(
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700460 pub fn $name(n: $kind) -> Literal {
Alex Crichtona914a612018-04-04 07:48:44 -0700461 Literal::_new(imp::Literal::$name(n))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700462 }
463 )*)
464}
465
Alex Crichton852d53d2017-05-19 19:25:08 -0700466impl Literal {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700467 fn _new(inner: imp::Literal) -> Literal {
468 Literal {
469 inner: inner,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700470 _marker: marker::PhantomData,
471 }
Alex Crichton1a7f7622017-07-05 17:47:15 -0700472 }
473
Alex Crichtona914a612018-04-04 07:48:44 -0700474 int_literals! {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700475 u8_suffixed => u8,
476 u16_suffixed => u16,
477 u32_suffixed => u32,
478 u64_suffixed => u64,
479 usize_suffixed => usize,
480 i8_suffixed => i8,
481 i16_suffixed => i16,
482 i32_suffixed => i32,
483 i64_suffixed => i64,
484 isize_suffixed => isize,
Alex Crichton1a7f7622017-07-05 17:47:15 -0700485
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700486 u8_unsuffixed => u8,
487 u16_unsuffixed => u16,
488 u32_unsuffixed => u32,
489 u64_unsuffixed => u64,
490 usize_unsuffixed => usize,
491 i8_unsuffixed => i8,
492 i16_unsuffixed => i16,
493 i32_unsuffixed => i32,
494 i64_unsuffixed => i64,
495 isize_unsuffixed => isize,
Alex Crichton1a7f7622017-07-05 17:47:15 -0700496 }
497
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700498 pub fn f64_unsuffixed(f: f64) -> Literal {
499 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700500 Literal::_new(imp::Literal::f64_unsuffixed(f))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700501 }
502
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700503 pub fn f64_suffixed(f: f64) -> Literal {
504 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700505 Literal::_new(imp::Literal::f64_suffixed(f))
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700506 }
507
508 pub fn f32_unsuffixed(f: f32) -> Literal {
509 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700510 Literal::_new(imp::Literal::f32_unsuffixed(f))
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700511 }
512
513 pub fn f32_suffixed(f: f32) -> Literal {
514 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700515 Literal::_new(imp::Literal::f32_suffixed(f))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700516 }
517
518 pub fn string(string: &str) -> Literal {
Alex Crichtona914a612018-04-04 07:48:44 -0700519 Literal::_new(imp::Literal::string(string))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700520 }
521
522 pub fn character(ch: char) -> Literal {
Alex Crichtona914a612018-04-04 07:48:44 -0700523 Literal::_new(imp::Literal::character(ch))
Alex Crichton76a5cc82017-05-23 07:01:44 -0700524 }
525
Alex Crichton9c2fb0a2017-05-26 08:49:31 -0700526 pub fn byte_string(s: &[u8]) -> Literal {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700527 Literal::_new(imp::Literal::byte_string(s))
Alex Crichton852d53d2017-05-19 19:25:08 -0700528 }
Alex Crichton76a5cc82017-05-23 07:01:44 -0700529
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700530 pub fn span(&self) -> Span {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700531 Span::_new(self.inner.span())
Alex Crichton1a7f7622017-07-05 17:47:15 -0700532 }
533
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700534 pub fn set_span(&mut self, span: Span) {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700535 self.inner.set_span(span.inner);
Alex Crichton31316622017-05-26 12:54:47 -0700536 }
Alex Crichton852d53d2017-05-19 19:25:08 -0700537}
538
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700539impl fmt::Debug for Literal {
540 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
541 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700542 }
543}
David Tolnaycb1b85f2017-06-03 16:40:35 -0700544
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700545impl fmt::Display for Literal {
546 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
547 self.inner.fmt(f)
548 }
549}
550
551pub mod token_stream {
552 use std::fmt;
553 use std::marker;
554 use std::rc::Rc;
555
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700556 pub use TokenStream;
David Tolnayb28f38a2018-03-31 22:02:29 +0200557 use TokenTree;
558 use imp;
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700559
560 pub struct IntoIter {
561 inner: imp::TokenTreeIter,
562 _marker: marker::PhantomData<Rc<()>>,
563 }
564
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700565 impl Iterator for IntoIter {
566 type Item = TokenTree;
567
568 fn next(&mut self) -> Option<TokenTree> {
569 self.inner.next()
570 }
571 }
572
573 impl fmt::Debug for IntoIter {
574 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
575 self.inner.fmt(f)
576 }
577 }
578
579 impl IntoIterator for TokenStream {
580 type Item = TokenTree;
581 type IntoIter = IntoIter;
582
583 fn into_iter(self) -> IntoIter {
584 IntoIter {
585 inner: self.inner.into_iter(),
586 _marker: marker::PhantomData,
587 }
588 }
589 }
590}