blob: 7ec1a737d51f5e4d420c10581925a38350436dcb [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)]
172#[cfg_attr(procmacro2_semver_exempt, derive(PartialEq, Eq))]
173pub struct Span {
174 inner: imp::Span,
175 _marker: marker::PhantomData<Rc<()>>,
176}
Alex Crichton44bffbc2017-05-19 17:51:59 -0700177
Alex Crichton44bffbc2017-05-19 17:51:59 -0700178impl Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700179 fn _new(inner: imp::Span) -> Span {
180 Span {
181 inner: inner,
182 _marker: marker::PhantomData,
183 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700184 }
Alex Crichtone6085b72017-11-21 07:24:25 -0800185
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700186 pub fn call_site() -> Span {
187 Span::_new(imp::Span::call_site())
188 }
189
190 #[cfg(procmacro2_semver_exempt)]
Alex Crichtone6085b72017-11-21 07:24:25 -0800191 pub fn def_site() -> Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700192 Span::_new(imp::Span::def_site())
Alex Crichtone6085b72017-11-21 07:24:25 -0800193 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500194
David Tolnay4e8e3972018-01-05 18:10:22 -0800195 /// Creates a new span with the same line/column information as `self` but
196 /// that resolves symbols as though it were at `other`.
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700197 #[cfg(procmacro2_semver_exempt)]
David Tolnay4e8e3972018-01-05 18:10:22 -0800198 pub fn resolved_at(&self, other: Span) -> Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700199 Span::_new(self.inner.resolved_at(other.inner))
David Tolnay4e8e3972018-01-05 18:10:22 -0800200 }
201
202 /// Creates a new span with the same name resolution behavior as `self` but
203 /// with the line/column information of `other`.
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700204 #[cfg(procmacro2_semver_exempt)]
David Tolnay4e8e3972018-01-05 18:10:22 -0800205 pub fn located_at(&self, other: Span) -> Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700206 Span::_new(self.inner.located_at(other.inner))
David Tolnay4e8e3972018-01-05 18:10:22 -0800207 }
208
David Tolnayd66ecf62018-01-02 20:05:42 -0800209 /// This method is only available when the `"nightly"` feature is enabled.
Alex Crichton0e8e7f42018-02-22 06:15:13 -0800210 #[cfg(all(feature = "nightly", feature = "proc-macro"))]
David Tolnay16a17202017-12-31 10:47:24 -0500211 pub fn unstable(self) -> proc_macro::Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700212 self.inner.unstable()
David Tolnay16a17202017-12-31 10:47:24 -0500213 }
214
David Tolnay1ebe3972018-01-02 20:14:20 -0800215 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500216 pub fn source_file(&self) -> SourceFile {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700217 SourceFile(self.inner.source_file())
Nika Layzellf8d5f212017-12-11 14:07:02 -0500218 }
219
David Tolnay1ebe3972018-01-02 20:14:20 -0800220 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500221 pub fn start(&self) -> LineColumn {
David Tolnayb28f38a2018-03-31 22:02:29 +0200222 let imp::LineColumn { line, column } = self.inner.start();
223 LineColumn {
224 line: line,
225 column: column,
226 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500227 }
228
David Tolnay1ebe3972018-01-02 20:14:20 -0800229 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500230 pub fn end(&self) -> LineColumn {
David Tolnayb28f38a2018-03-31 22:02:29 +0200231 let imp::LineColumn { line, column } = self.inner.end();
232 LineColumn {
233 line: line,
234 column: column,
235 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500236 }
237
David Tolnay1ebe3972018-01-02 20:14:20 -0800238 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500239 pub fn join(&self, other: Span) -> Option<Span> {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700240 self.inner.join(other.inner).map(Span::_new)
241 }
242}
243
244impl fmt::Debug for Span {
245 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
246 self.inner.fmt(f)
Nika Layzellf8d5f212017-12-11 14:07:02 -0500247 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700248}
249
David Tolnay977f8282017-05-31 17:41:33 -0700250#[derive(Clone, Debug)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700251pub enum TokenTree {
252 Group(Group),
253 Term(Term),
254 Op(Op),
255 Literal(Literal),
Alex Crichton1a7f7622017-07-05 17:47:15 -0700256}
257
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700258impl TokenTree {
259 pub fn span(&self) -> Span {
260 match *self {
261 TokenTree::Group(ref t) => t.span(),
262 TokenTree::Term(ref t) => t.span(),
263 TokenTree::Op(ref t) => t.span(),
264 TokenTree::Literal(ref t) => t.span(),
265 }
266 }
267
268 pub fn set_span(&mut self, span: Span) {
269 match *self {
270 TokenTree::Group(ref mut t) => t.set_span(span),
271 TokenTree::Term(ref mut t) => t.set_span(span),
272 TokenTree::Op(ref mut t) => t.set_span(span),
273 TokenTree::Literal(ref mut t) => t.set_span(span),
274 }
275 }
276}
277
278impl From<Group> for TokenTree {
279 fn from(g: Group) -> TokenTree {
280 TokenTree::Group(g)
281 }
282}
283
284impl From<Term> for TokenTree {
285 fn from(g: Term) -> TokenTree {
286 TokenTree::Term(g)
287 }
288}
289
290impl From<Op> for TokenTree {
291 fn from(g: Op) -> TokenTree {
292 TokenTree::Op(g)
293 }
294}
295
296impl From<Literal> for TokenTree {
297 fn from(g: Literal) -> TokenTree {
298 TokenTree::Literal(g)
Alex Crichton1a7f7622017-07-05 17:47:15 -0700299 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700300}
301
Alex Crichton44bffbc2017-05-19 17:51:59 -0700302impl fmt::Display for TokenTree {
303 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700304 match *self {
305 TokenTree::Group(ref t) => t.fmt(f),
306 TokenTree::Term(ref t) => t.fmt(f),
307 TokenTree::Op(ref t) => t.fmt(f),
308 TokenTree::Literal(ref t) => t.fmt(f),
309 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700310 }
311}
312
David Tolnay977f8282017-05-31 17:41:33 -0700313#[derive(Clone, Debug)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700314pub struct Group {
315 delimiter: Delimiter,
316 stream: TokenStream,
317 span: Span,
Alex Crichton44bffbc2017-05-19 17:51:59 -0700318}
319
Michael Layzell5372f4b2017-06-02 10:29:31 -0400320#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Alex Crichton44bffbc2017-05-19 17:51:59 -0700321pub enum Delimiter {
322 Parenthesis,
323 Brace,
324 Bracket,
325 None,
326}
327
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700328impl Group {
329 pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
330 Group {
331 delimiter: delimiter,
332 stream: stream,
333 span: Span::call_site(),
334 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700335 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700336
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700337 pub fn delimiter(&self) -> Delimiter {
338 self.delimiter
Alex Crichton44bffbc2017-05-19 17:51:59 -0700339 }
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700340
341 pub fn stream(&self) -> TokenStream {
342 self.stream.clone()
343 }
344
345 pub fn span(&self) -> Span {
346 self.span
347 }
348
349 pub fn set_span(&mut self, span: Span) {
350 self.span = span;
351 }
352}
353
354impl fmt::Display for Group {
355 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
356 self.stream.fmt(f)
357 }
358}
359
360#[derive(Copy, Clone, Debug)]
361pub struct Op {
362 op: char,
363 spacing: Spacing,
364 span: Span,
Alex Crichton44bffbc2017-05-19 17:51:59 -0700365}
366
Lukas Kalbertodteb3f9302017-08-20 18:58:41 +0200367#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Alex Crichton1a7f7622017-07-05 17:47:15 -0700368pub enum Spacing {
Alex Crichton44bffbc2017-05-19 17:51:59 -0700369 Alone,
370 Joint,
371}
372
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700373impl Op {
374 pub fn new(op: char, spacing: Spacing) -> Op {
375 Op {
376 op: op,
377 spacing: spacing,
378 span: Span::call_site(),
379 }
380 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700381
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700382 pub fn op(&self) -> char {
383 self.op
384 }
385
386 pub fn spacing(&self) -> Spacing {
387 self.spacing
388 }
389
390 pub fn span(&self) -> Span {
391 self.span
392 }
393
394 pub fn set_span(&mut self, span: Span) {
395 self.span = span;
396 }
397}
398
399impl fmt::Display for Op {
400 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
401 self.op.fmt(f)
402 }
403}
404
405#[derive(Copy, Clone)]
406pub struct Term {
407 inner: imp::Term,
408 span: Span,
409 _marker: marker::PhantomData<Rc<()>>,
410}
411
412impl Term {
413 fn _new(inner: imp::Term, span: Span) -> Term {
414 Term {
415 inner: inner,
416 span: span,
417 _marker: marker::PhantomData,
418 }
419 }
420
421 pub fn new(string: &str, span: Span) -> Term {
422 Term::_new(imp::Term::intern(string), span)
423 }
424
425 pub fn as_str(&self) -> &str {
426 self.inner.as_str()
427 }
428
429 pub fn span(&self) -> Span {
430 self.span
431 }
432
433 pub fn set_span(&mut self, span: Span) {
434 self.span = span;
435 }
436}
437
438impl fmt::Display for Term {
439 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
440 self.as_str().fmt(f)
441 }
442}
443
444impl fmt::Debug for Term {
445 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
446 self.inner.fmt(f)
447 }
448}
449
450#[derive(Clone)]
451pub struct Literal {
452 inner: imp::Literal,
453 span: Span,
454 _marker: marker::PhantomData<Rc<()>>,
455}
456
457macro_rules! suffixed_int_literals {
458 ($($name:ident => $kind:ident,)*) => ($(
459 #[allow(unused_comparisons)]
460 pub fn $name(n: $kind) -> Literal {
461 Literal::_new(n.into())
462 }
463 )*)
464}
465
466macro_rules! unsuffixed_int_literals {
467 ($($name:ident => $kind:ident,)*) => ($(
468 #[allow(unused_comparisons)]
469 pub fn $name(n: $kind) -> Literal {
470 Literal::_new(imp::Literal::integer(n as i64))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700471 }
472 )*)
473}
474
Alex Crichton852d53d2017-05-19 19:25:08 -0700475impl Literal {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700476 fn _new(inner: imp::Literal) -> Literal {
477 Literal {
478 inner: inner,
479 span: Span::call_site(),
480 _marker: marker::PhantomData,
481 }
Alex Crichton1a7f7622017-07-05 17:47:15 -0700482 }
483
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700484 suffixed_int_literals! {
485 u8_suffixed => u8,
486 u16_suffixed => u16,
487 u32_suffixed => u32,
488 u64_suffixed => u64,
489 usize_suffixed => usize,
490 i8_suffixed => i8,
491 i16_suffixed => i16,
492 i32_suffixed => i32,
493 i64_suffixed => i64,
494 isize_suffixed => isize,
Alex Crichton1a7f7622017-07-05 17:47:15 -0700495 }
496
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700497 unsuffixed_int_literals! {
498 u8_unsuffixed => u8,
499 u16_unsuffixed => u16,
500 u32_unsuffixed => u32,
501 u64_unsuffixed => u64,
502 usize_unsuffixed => usize,
503 i8_unsuffixed => i8,
504 i16_unsuffixed => i16,
505 i32_unsuffixed => i32,
506 i64_unsuffixed => i64,
507 isize_unsuffixed => isize,
Alex Crichton1a7f7622017-07-05 17:47:15 -0700508 }
509
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700510 pub fn f64_unsuffixed(f: f64) -> Literal {
511 assert!(f.is_finite());
512 Literal::_new(imp::Literal::float(f))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700513 }
514
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700515 pub fn f64_suffixed(f: f64) -> Literal {
516 assert!(f.is_finite());
517 Literal::_new(f.into())
518 }
519
520 pub fn f32_unsuffixed(f: f32) -> Literal {
521 assert!(f.is_finite());
522 Literal::_new(imp::Literal::float(f as f64))
523 }
524
525 pub fn f32_suffixed(f: f32) -> Literal {
526 assert!(f.is_finite());
527 Literal::_new(f.into())
Alex Crichton1a7f7622017-07-05 17:47:15 -0700528 }
529
530 pub fn string(string: &str) -> Literal {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700531 Literal::_new(string.into())
Alex Crichton1a7f7622017-07-05 17:47:15 -0700532 }
533
534 pub fn character(ch: char) -> Literal {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700535 Literal::_new(ch.into())
Alex Crichton76a5cc82017-05-23 07:01:44 -0700536 }
537
Alex Crichton9c2fb0a2017-05-26 08:49:31 -0700538 pub fn byte_string(s: &[u8]) -> Literal {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700539 Literal::_new(imp::Literal::byte_string(s))
Alex Crichton852d53d2017-05-19 19:25:08 -0700540 }
Alex Crichton76a5cc82017-05-23 07:01:44 -0700541
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700542 pub fn span(&self) -> Span {
543 self.span
Alex Crichton1a7f7622017-07-05 17:47:15 -0700544 }
545
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700546 pub fn set_span(&mut self, span: Span) {
547 self.span = span;
Alex Crichton31316622017-05-26 12:54:47 -0700548 }
Alex Crichton852d53d2017-05-19 19:25:08 -0700549}
550
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700551impl fmt::Debug for Literal {
552 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
553 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700554 }
555}
David Tolnaycb1b85f2017-06-03 16:40:35 -0700556
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700557impl fmt::Display for Literal {
558 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
559 self.inner.fmt(f)
560 }
561}
562
563pub mod token_stream {
564 use std::fmt;
565 use std::marker;
566 use std::rc::Rc;
567
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700568 pub use TokenStream;
David Tolnayb28f38a2018-03-31 22:02:29 +0200569 use TokenTree;
570 use imp;
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700571
572 pub struct IntoIter {
573 inner: imp::TokenTreeIter,
574 _marker: marker::PhantomData<Rc<()>>,
575 }
576
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700577 impl Iterator for IntoIter {
578 type Item = TokenTree;
579
580 fn next(&mut self) -> Option<TokenTree> {
581 self.inner.next()
582 }
583 }
584
585 impl fmt::Debug for IntoIter {
586 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
587 self.inner.fmt(f)
588 }
589 }
590
591 impl IntoIterator for TokenStream {
592 type Item = TokenTree;
593 type IntoIter = IntoIter;
594
595 fn into_iter(self) -> IntoIter {
596 IntoIter {
597 inner: self.inner.into_iter(),
598 _marker: marker::PhantomData,
599 }
600 }
601 }
602}