blob: 490ec7a5d2db2363dbeaa42142dd7fdc7f11de8d [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 Tolnay15cc4982018-01-08 08:03:27 -080028
David Tolnayd66ecf62018-01-02 20:05:42 -080029#![cfg_attr(feature = "nightly", feature(proc_macro))]
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070030
Alex Crichton0e8e7f42018-02-22 06:15:13 -080031#[cfg(feature = "proc-macro")]
Alex Crichton44bffbc2017-05-19 17:51:59 -070032extern crate proc_macro;
33
David Tolnayd66ecf62018-01-02 20:05:42 -080034#[cfg(not(feature = "nightly"))]
David Tolnayb1032662017-05-31 15:52:28 -070035extern crate unicode_xid;
Alex Crichton44bffbc2017-05-19 17:51:59 -070036
37use std::fmt;
Alex Crichton44bffbc2017-05-19 17:51:59 -070038use std::iter::FromIterator;
Alex Crichtonaf5bad42018-03-27 14:45:10 -070039use std::marker;
40use std::rc::Rc;
41use std::str::FromStr;
Alex Crichton44bffbc2017-05-19 17:51:59 -070042
David Tolnayb1032662017-05-31 15:52:28 -070043#[macro_use]
David Tolnayd66ecf62018-01-02 20:05:42 -080044#[cfg(not(feature = "nightly"))]
David Tolnayb1032662017-05-31 15:52:28 -070045mod strnom;
46
Alex Crichton44bffbc2017-05-19 17:51:59 -070047#[path = "stable.rs"]
David Tolnayd66ecf62018-01-02 20:05:42 -080048#[cfg(not(feature = "nightly"))]
Alex Crichtonb15c6352017-05-19 19:36:36 -070049mod imp;
50#[path = "unstable.rs"]
David Tolnayd66ecf62018-01-02 20:05:42 -080051#[cfg(feature = "nightly")]
Alex Crichton44bffbc2017-05-19 17:51:59 -070052mod imp;
53
David Tolnaycb1b85f2017-06-03 16:40:35 -070054#[derive(Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -070055pub struct TokenStream {
56 inner: imp::TokenStream,
57 _marker: marker::PhantomData<Rc<()>>,
58}
Alex Crichton44bffbc2017-05-19 17:51:59 -070059
Alex Crichtonaf5bad42018-03-27 14:45:10 -070060pub struct LexError {
61 inner: imp::LexError,
62 _marker: marker::PhantomData<Rc<()>>,
63}
64
65impl TokenStream {
66 fn _new(inner: imp::TokenStream) -> TokenStream {
67 TokenStream {
68 inner: inner,
69 _marker: marker::PhantomData,
70 }
71 }
72
73 pub fn empty() -> TokenStream {
74 TokenStream::_new(imp::TokenStream::empty())
75 }
76
77 pub fn is_empty(&self) -> bool {
78 self.inner.is_empty()
79 }
80}
Alex Crichton44bffbc2017-05-19 17:51:59 -070081
82impl FromStr for TokenStream {
83 type Err = LexError;
84
85 fn from_str(src: &str) -> Result<TokenStream, LexError> {
Alex Crichtonaf5bad42018-03-27 14:45:10 -070086 let e = src.parse().map_err(|e| {
87 LexError { inner: e, _marker: marker::PhantomData }
88 })?;
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 {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700222 let imp::LineColumn{ line, column } = self.inner.start();
David Tolnay79105e52017-12-31 11:03:04 -0500223 LineColumn { line: line, column: column }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500224 }
225
David Tolnay1ebe3972018-01-02 20:14:20 -0800226 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500227 pub fn end(&self) -> LineColumn {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700228 let imp::LineColumn{ line, column } = self.inner.end();
David Tolnay79105e52017-12-31 11:03:04 -0500229 LineColumn { line: line, column: column }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500230 }
231
David Tolnay1ebe3972018-01-02 20:14:20 -0800232 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500233 pub fn join(&self, other: Span) -> Option<Span> {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700234 self.inner.join(other.inner).map(Span::_new)
235 }
236}
237
238impl fmt::Debug for Span {
239 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
240 self.inner.fmt(f)
Nika Layzellf8d5f212017-12-11 14:07:02 -0500241 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700242}
243
David Tolnay977f8282017-05-31 17:41:33 -0700244#[derive(Clone, Debug)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700245pub enum TokenTree {
246 Group(Group),
247 Term(Term),
248 Op(Op),
249 Literal(Literal),
Alex Crichton1a7f7622017-07-05 17:47:15 -0700250}
251
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700252impl TokenTree {
253 pub fn span(&self) -> Span {
254 match *self {
255 TokenTree::Group(ref t) => t.span(),
256 TokenTree::Term(ref t) => t.span(),
257 TokenTree::Op(ref t) => t.span(),
258 TokenTree::Literal(ref t) => t.span(),
259 }
260 }
261
262 pub fn set_span(&mut self, span: Span) {
263 match *self {
264 TokenTree::Group(ref mut t) => t.set_span(span),
265 TokenTree::Term(ref mut t) => t.set_span(span),
266 TokenTree::Op(ref mut t) => t.set_span(span),
267 TokenTree::Literal(ref mut t) => t.set_span(span),
268 }
269 }
270}
271
272impl From<Group> for TokenTree {
273 fn from(g: Group) -> TokenTree {
274 TokenTree::Group(g)
275 }
276}
277
278impl From<Term> for TokenTree {
279 fn from(g: Term) -> TokenTree {
280 TokenTree::Term(g)
281 }
282}
283
284impl From<Op> for TokenTree {
285 fn from(g: Op) -> TokenTree {
286 TokenTree::Op(g)
287 }
288}
289
290impl From<Literal> for TokenTree {
291 fn from(g: Literal) -> TokenTree {
292 TokenTree::Literal(g)
Alex Crichton1a7f7622017-07-05 17:47:15 -0700293 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700294}
295
Alex Crichton44bffbc2017-05-19 17:51:59 -0700296impl fmt::Display for TokenTree {
297 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700298 match *self {
299 TokenTree::Group(ref t) => t.fmt(f),
300 TokenTree::Term(ref t) => t.fmt(f),
301 TokenTree::Op(ref t) => t.fmt(f),
302 TokenTree::Literal(ref t) => t.fmt(f),
303 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700304 }
305}
306
David Tolnay977f8282017-05-31 17:41:33 -0700307#[derive(Clone, Debug)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700308pub struct Group {
309 delimiter: Delimiter,
310 stream: TokenStream,
311 span: Span,
Alex Crichton44bffbc2017-05-19 17:51:59 -0700312}
313
Michael Layzell5372f4b2017-06-02 10:29:31 -0400314#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Alex Crichton44bffbc2017-05-19 17:51:59 -0700315pub enum Delimiter {
316 Parenthesis,
317 Brace,
318 Bracket,
319 None,
320}
321
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700322impl Group {
323 pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
324 Group {
325 delimiter: delimiter,
326 stream: stream,
327 span: Span::call_site(),
328 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700329 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700330
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700331 pub fn delimiter(&self) -> Delimiter {
332 self.delimiter
Alex Crichton44bffbc2017-05-19 17:51:59 -0700333 }
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700334
335 pub fn stream(&self) -> TokenStream {
336 self.stream.clone()
337 }
338
339 pub fn span(&self) -> Span {
340 self.span
341 }
342
343 pub fn set_span(&mut self, span: Span) {
344 self.span = span;
345 }
346}
347
348impl fmt::Display for Group {
349 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
350 self.stream.fmt(f)
351 }
352}
353
354#[derive(Copy, Clone, Debug)]
355pub struct Op {
356 op: char,
357 spacing: Spacing,
358 span: Span,
Alex Crichton44bffbc2017-05-19 17:51:59 -0700359}
360
Lukas Kalbertodteb3f9302017-08-20 18:58:41 +0200361#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Alex Crichton1a7f7622017-07-05 17:47:15 -0700362pub enum Spacing {
Alex Crichton44bffbc2017-05-19 17:51:59 -0700363 Alone,
364 Joint,
365}
366
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700367impl Op {
368 pub fn new(op: char, spacing: Spacing) -> Op {
369 Op {
370 op: op,
371 spacing: spacing,
372 span: Span::call_site(),
373 }
374 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700375
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700376 pub fn op(&self) -> char {
377 self.op
378 }
379
380 pub fn spacing(&self) -> Spacing {
381 self.spacing
382 }
383
384 pub fn span(&self) -> Span {
385 self.span
386 }
387
388 pub fn set_span(&mut self, span: Span) {
389 self.span = span;
390 }
391}
392
393impl fmt::Display for Op {
394 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
395 self.op.fmt(f)
396 }
397}
398
399#[derive(Copy, Clone)]
400pub struct Term {
401 inner: imp::Term,
402 span: Span,
403 _marker: marker::PhantomData<Rc<()>>,
404}
405
406impl Term {
407 fn _new(inner: imp::Term, span: Span) -> Term {
408 Term {
409 inner: inner,
410 span: span,
411 _marker: marker::PhantomData,
412 }
413 }
414
415 pub fn new(string: &str, span: Span) -> Term {
416 Term::_new(imp::Term::intern(string), span)
417 }
418
419 pub fn as_str(&self) -> &str {
420 self.inner.as_str()
421 }
422
423 pub fn span(&self) -> Span {
424 self.span
425 }
426
427 pub fn set_span(&mut self, span: Span) {
428 self.span = span;
429 }
430}
431
432impl fmt::Display for Term {
433 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
434 self.as_str().fmt(f)
435 }
436}
437
438impl fmt::Debug for Term {
439 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
440 self.inner.fmt(f)
441 }
442}
443
444#[derive(Clone)]
445pub struct Literal {
446 inner: imp::Literal,
447 span: Span,
448 _marker: marker::PhantomData<Rc<()>>,
449}
450
451macro_rules! suffixed_int_literals {
452 ($($name:ident => $kind:ident,)*) => ($(
453 #[allow(unused_comparisons)]
454 pub fn $name(n: $kind) -> Literal {
455 Literal::_new(n.into())
456 }
457 )*)
458}
459
460macro_rules! unsuffixed_int_literals {
461 ($($name:ident => $kind:ident,)*) => ($(
462 #[allow(unused_comparisons)]
463 pub fn $name(n: $kind) -> Literal {
464 Literal::_new(imp::Literal::integer(n as i64))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700465 }
466 )*)
467}
468
Alex Crichton852d53d2017-05-19 19:25:08 -0700469impl Literal {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700470 fn _new(inner: imp::Literal) -> Literal {
471 Literal {
472 inner: inner,
473 span: Span::call_site(),
474 _marker: marker::PhantomData,
475 }
Alex Crichton1a7f7622017-07-05 17:47:15 -0700476 }
477
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700478 suffixed_int_literals! {
479 u8_suffixed => u8,
480 u16_suffixed => u16,
481 u32_suffixed => u32,
482 u64_suffixed => u64,
483 usize_suffixed => usize,
484 i8_suffixed => i8,
485 i16_suffixed => i16,
486 i32_suffixed => i32,
487 i64_suffixed => i64,
488 isize_suffixed => isize,
Alex Crichton1a7f7622017-07-05 17:47:15 -0700489 }
490
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700491 unsuffixed_int_literals! {
492 u8_unsuffixed => u8,
493 u16_unsuffixed => u16,
494 u32_unsuffixed => u32,
495 u64_unsuffixed => u64,
496 usize_unsuffixed => usize,
497 i8_unsuffixed => i8,
498 i16_unsuffixed => i16,
499 i32_unsuffixed => i32,
500 i64_unsuffixed => i64,
501 isize_unsuffixed => isize,
Alex Crichton1a7f7622017-07-05 17:47:15 -0700502 }
503
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700504 pub fn f64_unsuffixed(f: f64) -> Literal {
505 assert!(f.is_finite());
506 Literal::_new(imp::Literal::float(f))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700507 }
508
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700509 pub fn f64_suffixed(f: f64) -> Literal {
510 assert!(f.is_finite());
511 Literal::_new(f.into())
512 }
513
514 pub fn f32_unsuffixed(f: f32) -> Literal {
515 assert!(f.is_finite());
516 Literal::_new(imp::Literal::float(f as f64))
517 }
518
519 pub fn f32_suffixed(f: f32) -> Literal {
520 assert!(f.is_finite());
521 Literal::_new(f.into())
Alex Crichton1a7f7622017-07-05 17:47:15 -0700522 }
523
524 pub fn string(string: &str) -> Literal {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700525 Literal::_new(string.into())
Alex Crichton1a7f7622017-07-05 17:47:15 -0700526 }
527
528 pub fn character(ch: char) -> Literal {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700529 Literal::_new(ch.into())
Alex Crichton76a5cc82017-05-23 07:01:44 -0700530 }
531
Alex Crichton9c2fb0a2017-05-26 08:49:31 -0700532 pub fn byte_string(s: &[u8]) -> Literal {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700533 Literal::_new(imp::Literal::byte_string(s))
Alex Crichton852d53d2017-05-19 19:25:08 -0700534 }
Alex Crichton76a5cc82017-05-23 07:01:44 -0700535
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700536 pub fn span(&self) -> Span {
537 self.span
Alex Crichton1a7f7622017-07-05 17:47:15 -0700538 }
539
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700540 pub fn set_span(&mut self, span: Span) {
541 self.span = span;
Alex Crichton31316622017-05-26 12:54:47 -0700542 }
Alex Crichton852d53d2017-05-19 19:25:08 -0700543}
544
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700545impl fmt::Debug for Literal {
546 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
547 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700548 }
549}
David Tolnaycb1b85f2017-06-03 16:40:35 -0700550
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700551impl fmt::Display for Literal {
552 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
553 self.inner.fmt(f)
554 }
555}
556
557pub mod token_stream {
558 use std::fmt;
559 use std::marker;
560 use std::rc::Rc;
561
562 use imp;
563 use TokenTree;
564 pub use TokenStream;
565
566 pub struct IntoIter {
567 inner: imp::TokenTreeIter,
568 _marker: marker::PhantomData<Rc<()>>,
569 }
570
571
572 impl Iterator for IntoIter {
573 type Item = TokenTree;
574
575 fn next(&mut self) -> Option<TokenTree> {
576 self.inner.next()
577 }
578 }
579
580 impl fmt::Debug for IntoIter {
581 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
582 self.inner.fmt(f)
583 }
584 }
585
586 impl IntoIterator for TokenStream {
587 type Item = TokenTree;
588 type IntoIter = IntoIter;
589
590 fn into_iter(self) -> IntoIter {
591 IntoIter {
592 inner: self.inner.into_iter(),
593 _marker: marker::PhantomData,
594 }
595 }
596 }
597}