blob: 91b3add694820ae08ffa66d8e4ee585f92bee9bf [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//!
David Tolnay6b46deb2018-04-25 21:22:46 -070023//! # Unstable Features
24//!
25//! `proc-macro2` supports exporting some methods from `proc_macro` which are
26//! currently highly unstable, and may not be stabilized in the first pass of
27//! `proc_macro` stabilizations. These features are not exported by default.
28//! Minor versions of `proc-macro2` may make breaking changes to them at any
29//! time.
30//!
31//! To enable these features, the `procmacro2_semver_exempt` config flag must be
32//! passed to rustc.
33//!
34//! ```sh
35//! RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build
36//! ```
37//!
38//! Note that this must not only be done for your crate, but for any crate that
39//! depends on your crate. This infectious nature is intentional, as it serves
40//! as a reminder that you are outside of the normal semver guarantees.
41//!
Alex Crichton1fd0e8a2018-02-04 21:29:13 -080042//! [`proc_macro`]: https://doc.rust-lang.org/proc_macro/
43//! [ts]: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html
Alex Crichtonbabc99e2017-07-05 18:00:29 -070044
David Tolnay15cc4982018-01-08 08:03:27 -080045// Proc-macro2 types in rustdoc of other crates get linked to here.
David Tolnay2c1dac52018-04-23 19:18:07 -070046#![doc(html_root_url = "https://docs.rs/proc-macro2/0.3.7")]
David Tolnayd66ecf62018-01-02 20:05:42 -080047#![cfg_attr(feature = "nightly", feature(proc_macro))]
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070048
Alex Crichton0e8e7f42018-02-22 06:15:13 -080049#[cfg(feature = "proc-macro")]
Alex Crichton44bffbc2017-05-19 17:51:59 -070050extern crate proc_macro;
51
David Tolnayd66ecf62018-01-02 20:05:42 -080052#[cfg(not(feature = "nightly"))]
David Tolnayb1032662017-05-31 15:52:28 -070053extern crate unicode_xid;
Alex Crichton44bffbc2017-05-19 17:51:59 -070054
55use std::fmt;
Alex Crichton44bffbc2017-05-19 17:51:59 -070056use std::iter::FromIterator;
Alex Crichtonaf5bad42018-03-27 14:45:10 -070057use std::marker;
58use std::rc::Rc;
59use std::str::FromStr;
Alex Crichton44bffbc2017-05-19 17:51:59 -070060
David Tolnayb1032662017-05-31 15:52:28 -070061#[macro_use]
David Tolnayd66ecf62018-01-02 20:05:42 -080062#[cfg(not(feature = "nightly"))]
David Tolnayb1032662017-05-31 15:52:28 -070063mod strnom;
64
Alex Crichton44bffbc2017-05-19 17:51:59 -070065#[path = "stable.rs"]
David Tolnayd66ecf62018-01-02 20:05:42 -080066#[cfg(not(feature = "nightly"))]
Alex Crichtonb15c6352017-05-19 19:36:36 -070067mod imp;
68#[path = "unstable.rs"]
David Tolnayd66ecf62018-01-02 20:05:42 -080069#[cfg(feature = "nightly")]
Alex Crichton44bffbc2017-05-19 17:51:59 -070070mod imp;
71
David Tolnaycb1b85f2017-06-03 16:40:35 -070072#[derive(Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -070073pub struct TokenStream {
74 inner: imp::TokenStream,
75 _marker: marker::PhantomData<Rc<()>>,
76}
Alex Crichton44bffbc2017-05-19 17:51:59 -070077
Alex Crichtonaf5bad42018-03-27 14:45:10 -070078pub struct LexError {
79 inner: imp::LexError,
80 _marker: marker::PhantomData<Rc<()>>,
81}
82
83impl TokenStream {
84 fn _new(inner: imp::TokenStream) -> TokenStream {
85 TokenStream {
86 inner: inner,
87 _marker: marker::PhantomData,
88 }
89 }
90
91 pub fn empty() -> TokenStream {
92 TokenStream::_new(imp::TokenStream::empty())
93 }
94
95 pub fn is_empty(&self) -> bool {
96 self.inner.is_empty()
97 }
98}
Alex Crichton44bffbc2017-05-19 17:51:59 -070099
100impl FromStr for TokenStream {
101 type Err = LexError;
102
103 fn from_str(src: &str) -> Result<TokenStream, LexError> {
David Tolnayb28f38a2018-03-31 22:02:29 +0200104 let e = src.parse().map_err(|e| LexError {
105 inner: e,
106 _marker: marker::PhantomData,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700107 })?;
108 Ok(TokenStream::_new(e))
Alex Crichton44bffbc2017-05-19 17:51:59 -0700109 }
110}
111
Alex Crichton0e8e7f42018-02-22 06:15:13 -0800112#[cfg(feature = "proc-macro")]
Alex Crichton44bffbc2017-05-19 17:51:59 -0700113impl From<proc_macro::TokenStream> for TokenStream {
114 fn from(inner: proc_macro::TokenStream) -> TokenStream {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700115 TokenStream::_new(inner.into())
Alex Crichton44bffbc2017-05-19 17:51:59 -0700116 }
117}
118
Alex Crichton0e8e7f42018-02-22 06:15:13 -0800119#[cfg(feature = "proc-macro")]
Alex Crichton44bffbc2017-05-19 17:51:59 -0700120impl From<TokenStream> for proc_macro::TokenStream {
121 fn from(inner: TokenStream) -> proc_macro::TokenStream {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700122 inner.inner.into()
Alex Crichton44bffbc2017-05-19 17:51:59 -0700123 }
124}
125
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700126impl FromIterator<TokenTree> for TokenStream {
127 fn from_iter<I: IntoIterator<Item = TokenTree>>(streams: I) -> Self {
128 TokenStream::_new(streams.into_iter().collect())
Alex Crichton44bffbc2017-05-19 17:51:59 -0700129 }
130}
131
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700132impl fmt::Display for TokenStream {
133 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
134 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700135 }
136}
137
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700138impl fmt::Debug for TokenStream {
139 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
140 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700141 }
142}
143
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700144impl fmt::Debug for LexError {
145 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
146 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700147 }
148}
149
Nika Layzellb35a9a32017-12-30 14:34:35 -0500150// Returned by reference, so we can't easily wrap it.
David Tolnay1ebe3972018-01-02 20:14:20 -0800151#[cfg(procmacro2_semver_exempt)]
Nika Layzellb35a9a32017-12-30 14:34:35 -0500152pub use imp::FileName;
153
David Tolnay1ebe3972018-01-02 20:14:20 -0800154#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500155#[derive(Clone, PartialEq, Eq)]
156pub struct SourceFile(imp::SourceFile);
157
David Tolnay1ebe3972018-01-02 20:14:20 -0800158#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500159impl SourceFile {
160 /// Get the path to this source file as a string.
Nika Layzellb35a9a32017-12-30 14:34:35 -0500161 pub fn path(&self) -> &FileName {
162 self.0.path()
Nika Layzellf8d5f212017-12-11 14:07:02 -0500163 }
164
165 pub fn is_real(&self) -> bool {
166 self.0.is_real()
167 }
168}
169
David Tolnay1ebe3972018-01-02 20:14:20 -0800170#[cfg(procmacro2_semver_exempt)]
Nika Layzellb35a9a32017-12-30 14:34:35 -0500171impl AsRef<FileName> for SourceFile {
172 fn as_ref(&self) -> &FileName {
173 self.0.path()
Nika Layzellf8d5f212017-12-11 14:07:02 -0500174 }
175}
176
David Tolnay1ebe3972018-01-02 20:14:20 -0800177#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500178impl fmt::Debug for SourceFile {
179 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
180 self.0.fmt(f)
181 }
182}
183
David Tolnay1ebe3972018-01-02 20:14:20 -0800184#[cfg(procmacro2_semver_exempt)]
Nika Layzell1ecb6ce2017-12-30 14:34:05 -0500185pub struct LineColumn {
186 pub line: usize,
187 pub column: usize,
188}
Nika Layzellf8d5f212017-12-11 14:07:02 -0500189
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700190#[derive(Copy, Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700191pub struct Span {
192 inner: imp::Span,
193 _marker: marker::PhantomData<Rc<()>>,
194}
Alex Crichton44bffbc2017-05-19 17:51:59 -0700195
Alex Crichton44bffbc2017-05-19 17:51:59 -0700196impl Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700197 fn _new(inner: imp::Span) -> Span {
198 Span {
199 inner: inner,
200 _marker: marker::PhantomData,
201 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700202 }
Alex Crichtone6085b72017-11-21 07:24:25 -0800203
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700204 pub fn call_site() -> Span {
205 Span::_new(imp::Span::call_site())
206 }
207
208 #[cfg(procmacro2_semver_exempt)]
Alex Crichtone6085b72017-11-21 07:24:25 -0800209 pub fn def_site() -> Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700210 Span::_new(imp::Span::def_site())
Alex Crichtone6085b72017-11-21 07:24:25 -0800211 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500212
David Tolnay4e8e3972018-01-05 18:10:22 -0800213 /// Creates a new span with the same line/column information as `self` but
214 /// that resolves symbols as though it were at `other`.
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700215 #[cfg(procmacro2_semver_exempt)]
David Tolnay4e8e3972018-01-05 18:10:22 -0800216 pub fn resolved_at(&self, other: Span) -> Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700217 Span::_new(self.inner.resolved_at(other.inner))
David Tolnay4e8e3972018-01-05 18:10:22 -0800218 }
219
220 /// Creates a new span with the same name resolution behavior as `self` but
221 /// with the line/column information of `other`.
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700222 #[cfg(procmacro2_semver_exempt)]
David Tolnay4e8e3972018-01-05 18:10:22 -0800223 pub fn located_at(&self, other: Span) -> Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700224 Span::_new(self.inner.located_at(other.inner))
David Tolnay4e8e3972018-01-05 18:10:22 -0800225 }
226
David Tolnayd66ecf62018-01-02 20:05:42 -0800227 /// This method is only available when the `"nightly"` feature is enabled.
Alex Crichton0e8e7f42018-02-22 06:15:13 -0800228 #[cfg(all(feature = "nightly", feature = "proc-macro"))]
David Tolnay16a17202017-12-31 10:47:24 -0500229 pub fn unstable(self) -> proc_macro::Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700230 self.inner.unstable()
David Tolnay16a17202017-12-31 10:47:24 -0500231 }
232
David Tolnay1ebe3972018-01-02 20:14:20 -0800233 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500234 pub fn source_file(&self) -> SourceFile {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700235 SourceFile(self.inner.source_file())
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 start(&self) -> LineColumn {
David Tolnayb28f38a2018-03-31 22:02:29 +0200240 let imp::LineColumn { line, column } = self.inner.start();
241 LineColumn {
242 line: line,
243 column: column,
244 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500245 }
246
David Tolnay1ebe3972018-01-02 20:14:20 -0800247 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500248 pub fn end(&self) -> LineColumn {
David Tolnayb28f38a2018-03-31 22:02:29 +0200249 let imp::LineColumn { line, column } = self.inner.end();
250 LineColumn {
251 line: line,
252 column: column,
253 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500254 }
255
David Tolnay1ebe3972018-01-02 20:14:20 -0800256 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500257 pub fn join(&self, other: Span) -> Option<Span> {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700258 self.inner.join(other.inner).map(Span::_new)
259 }
Alex Crichtonb2c94622018-04-04 07:36:41 -0700260
261 #[cfg(procmacro2_semver_exempt)]
262 pub fn eq(&self, other: &Span) -> bool {
263 self.inner.eq(&other.inner)
264 }
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700265}
266
267impl fmt::Debug for Span {
268 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
269 self.inner.fmt(f)
Nika Layzellf8d5f212017-12-11 14:07:02 -0500270 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700271}
272
David Tolnay034205f2018-04-22 16:45:28 -0700273#[derive(Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700274pub enum TokenTree {
275 Group(Group),
276 Term(Term),
277 Op(Op),
278 Literal(Literal),
Alex Crichton1a7f7622017-07-05 17:47:15 -0700279}
280
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700281impl TokenTree {
282 pub fn span(&self) -> Span {
283 match *self {
284 TokenTree::Group(ref t) => t.span(),
285 TokenTree::Term(ref t) => t.span(),
286 TokenTree::Op(ref t) => t.span(),
287 TokenTree::Literal(ref t) => t.span(),
288 }
289 }
290
291 pub fn set_span(&mut self, span: Span) {
292 match *self {
293 TokenTree::Group(ref mut t) => t.set_span(span),
294 TokenTree::Term(ref mut t) => t.set_span(span),
295 TokenTree::Op(ref mut t) => t.set_span(span),
296 TokenTree::Literal(ref mut t) => t.set_span(span),
297 }
298 }
299}
300
301impl From<Group> for TokenTree {
302 fn from(g: Group) -> TokenTree {
303 TokenTree::Group(g)
304 }
305}
306
307impl From<Term> for TokenTree {
308 fn from(g: Term) -> TokenTree {
309 TokenTree::Term(g)
310 }
311}
312
313impl From<Op> for TokenTree {
314 fn from(g: Op) -> TokenTree {
315 TokenTree::Op(g)
316 }
317}
318
319impl From<Literal> for TokenTree {
320 fn from(g: Literal) -> TokenTree {
321 TokenTree::Literal(g)
Alex Crichton1a7f7622017-07-05 17:47:15 -0700322 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700323}
324
Alex Crichton44bffbc2017-05-19 17:51:59 -0700325impl fmt::Display for TokenTree {
326 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700327 match *self {
328 TokenTree::Group(ref t) => t.fmt(f),
329 TokenTree::Term(ref t) => t.fmt(f),
330 TokenTree::Op(ref t) => t.fmt(f),
331 TokenTree::Literal(ref t) => t.fmt(f),
332 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700333 }
334}
335
David Tolnay034205f2018-04-22 16:45:28 -0700336impl fmt::Debug for TokenTree {
337 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
338 // Each of these has the name in the struct type in the derived debug,
339 // so don't bother with an extra layer of indirection
340 match *self {
341 TokenTree::Group(ref t) => t.fmt(f),
342 TokenTree::Term(ref t) => t.fmt(f),
343 TokenTree::Op(ref t) => t.fmt(f),
344 TokenTree::Literal(ref t) => t.fmt(f),
345 }
346 }
347}
348
349#[derive(Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700350pub struct Group {
351 delimiter: Delimiter,
352 stream: TokenStream,
353 span: Span,
Alex Crichton44bffbc2017-05-19 17:51:59 -0700354}
355
Michael Layzell5372f4b2017-06-02 10:29:31 -0400356#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Alex Crichton44bffbc2017-05-19 17:51:59 -0700357pub enum Delimiter {
358 Parenthesis,
359 Brace,
360 Bracket,
361 None,
362}
363
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700364impl Group {
365 pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
366 Group {
367 delimiter: delimiter,
368 stream: stream,
369 span: Span::call_site(),
370 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700371 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700372
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700373 pub fn delimiter(&self) -> Delimiter {
374 self.delimiter
Alex Crichton44bffbc2017-05-19 17:51:59 -0700375 }
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700376
377 pub fn stream(&self) -> TokenStream {
378 self.stream.clone()
379 }
380
381 pub fn span(&self) -> Span {
382 self.span
383 }
384
385 pub fn set_span(&mut self, span: Span) {
386 self.span = span;
387 }
388}
389
390impl fmt::Display for Group {
391 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
392 self.stream.fmt(f)
393 }
394}
395
David Tolnay034205f2018-04-22 16:45:28 -0700396impl fmt::Debug for Group {
397 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
398 let mut debug = fmt.debug_struct("Group");
399 debug.field("delimiter", &self.delimiter);
400 debug.field("stream", &self.stream);
401 #[cfg(procmacro2_semver_exempt)]
402 debug.field("span", &self.span);
403 debug.finish()
404 }
405}
406
407#[derive(Copy, Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700408pub struct Op {
409 op: char,
410 spacing: Spacing,
411 span: Span,
Alex Crichton44bffbc2017-05-19 17:51:59 -0700412}
413
Lukas Kalbertodteb3f9302017-08-20 18:58:41 +0200414#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Alex Crichton1a7f7622017-07-05 17:47:15 -0700415pub enum Spacing {
Alex Crichton44bffbc2017-05-19 17:51:59 -0700416 Alone,
417 Joint,
418}
419
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700420impl Op {
421 pub fn new(op: char, spacing: Spacing) -> Op {
422 Op {
423 op: op,
424 spacing: spacing,
425 span: Span::call_site(),
426 }
427 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700428
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700429 pub fn op(&self) -> char {
430 self.op
431 }
432
433 pub fn spacing(&self) -> Spacing {
434 self.spacing
435 }
436
437 pub fn span(&self) -> Span {
438 self.span
439 }
440
441 pub fn set_span(&mut self, span: Span) {
442 self.span = span;
443 }
444}
445
446impl fmt::Display for Op {
447 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
448 self.op.fmt(f)
449 }
450}
451
David Tolnay034205f2018-04-22 16:45:28 -0700452impl fmt::Debug for Op {
453 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
454 let mut debug = fmt.debug_struct("Op");
455 debug.field("op", &self.op);
456 debug.field("spacing", &self.spacing);
457 #[cfg(procmacro2_semver_exempt)]
458 debug.field("span", &self.span);
459 debug.finish()
460 }
461}
462
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700463#[derive(Copy, Clone)]
464pub struct Term {
465 inner: imp::Term,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700466 _marker: marker::PhantomData<Rc<()>>,
467}
468
469impl Term {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700470 fn _new(inner: imp::Term) -> Term {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700471 Term {
472 inner: inner,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700473 _marker: marker::PhantomData,
474 }
475 }
476
477 pub fn new(string: &str, span: Span) -> Term {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700478 Term::_new(imp::Term::new(string, span.inner))
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700479 }
480
481 pub fn as_str(&self) -> &str {
482 self.inner.as_str()
483 }
484
485 pub fn span(&self) -> Span {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700486 Span::_new(self.inner.span())
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700487 }
488
489 pub fn set_span(&mut self, span: Span) {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700490 self.inner.set_span(span.inner);
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700491 }
492}
493
494impl fmt::Display for Term {
495 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
496 self.as_str().fmt(f)
497 }
498}
499
500impl fmt::Debug for Term {
501 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
502 self.inner.fmt(f)
503 }
504}
505
506#[derive(Clone)]
507pub struct Literal {
508 inner: imp::Literal,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700509 _marker: marker::PhantomData<Rc<()>>,
510}
511
Alex Crichtona914a612018-04-04 07:48:44 -0700512macro_rules! int_literals {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700513 ($($name:ident => $kind:ident,)*) => ($(
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700514 pub fn $name(n: $kind) -> Literal {
Alex Crichtona914a612018-04-04 07:48:44 -0700515 Literal::_new(imp::Literal::$name(n))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700516 }
517 )*)
518}
519
Alex Crichton852d53d2017-05-19 19:25:08 -0700520impl Literal {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700521 fn _new(inner: imp::Literal) -> Literal {
522 Literal {
523 inner: inner,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700524 _marker: marker::PhantomData,
525 }
Alex Crichton1a7f7622017-07-05 17:47:15 -0700526 }
527
Alex Crichtona914a612018-04-04 07:48:44 -0700528 int_literals! {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700529 u8_suffixed => u8,
530 u16_suffixed => u16,
531 u32_suffixed => u32,
532 u64_suffixed => u64,
533 usize_suffixed => usize,
534 i8_suffixed => i8,
535 i16_suffixed => i16,
536 i32_suffixed => i32,
537 i64_suffixed => i64,
538 isize_suffixed => isize,
Alex Crichton1a7f7622017-07-05 17:47:15 -0700539
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700540 u8_unsuffixed => u8,
541 u16_unsuffixed => u16,
542 u32_unsuffixed => u32,
543 u64_unsuffixed => u64,
544 usize_unsuffixed => usize,
545 i8_unsuffixed => i8,
546 i16_unsuffixed => i16,
547 i32_unsuffixed => i32,
548 i64_unsuffixed => i64,
549 isize_unsuffixed => isize,
Alex Crichton1a7f7622017-07-05 17:47:15 -0700550 }
551
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700552 pub fn f64_unsuffixed(f: f64) -> Literal {
553 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700554 Literal::_new(imp::Literal::f64_unsuffixed(f))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700555 }
556
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700557 pub fn f64_suffixed(f: f64) -> Literal {
558 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700559 Literal::_new(imp::Literal::f64_suffixed(f))
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700560 }
561
562 pub fn f32_unsuffixed(f: f32) -> Literal {
563 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700564 Literal::_new(imp::Literal::f32_unsuffixed(f))
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700565 }
566
567 pub fn f32_suffixed(f: f32) -> Literal {
568 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700569 Literal::_new(imp::Literal::f32_suffixed(f))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700570 }
571
572 pub fn string(string: &str) -> Literal {
Alex Crichtona914a612018-04-04 07:48:44 -0700573 Literal::_new(imp::Literal::string(string))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700574 }
575
576 pub fn character(ch: char) -> Literal {
Alex Crichtona914a612018-04-04 07:48:44 -0700577 Literal::_new(imp::Literal::character(ch))
Alex Crichton76a5cc82017-05-23 07:01:44 -0700578 }
579
Alex Crichton9c2fb0a2017-05-26 08:49:31 -0700580 pub fn byte_string(s: &[u8]) -> Literal {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700581 Literal::_new(imp::Literal::byte_string(s))
Alex Crichton852d53d2017-05-19 19:25:08 -0700582 }
Alex Crichton76a5cc82017-05-23 07:01:44 -0700583
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700584 pub fn span(&self) -> Span {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700585 Span::_new(self.inner.span())
Alex Crichton1a7f7622017-07-05 17:47:15 -0700586 }
587
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700588 pub fn set_span(&mut self, span: Span) {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700589 self.inner.set_span(span.inner);
Alex Crichton31316622017-05-26 12:54:47 -0700590 }
Alex Crichton852d53d2017-05-19 19:25:08 -0700591}
592
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700593impl fmt::Debug for Literal {
594 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
595 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700596 }
597}
David Tolnaycb1b85f2017-06-03 16:40:35 -0700598
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700599impl fmt::Display for Literal {
600 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
601 self.inner.fmt(f)
602 }
603}
604
605pub mod token_stream {
606 use std::fmt;
607 use std::marker;
608 use std::rc::Rc;
609
David Tolnay48ea5042018-04-23 19:17:35 -0700610 use imp;
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700611 pub use TokenStream;
David Tolnayb28f38a2018-03-31 22:02:29 +0200612 use TokenTree;
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700613
614 pub struct IntoIter {
615 inner: imp::TokenTreeIter,
616 _marker: marker::PhantomData<Rc<()>>,
617 }
618
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700619 impl Iterator for IntoIter {
620 type Item = TokenTree;
621
622 fn next(&mut self) -> Option<TokenTree> {
623 self.inner.next()
624 }
625 }
626
627 impl fmt::Debug for IntoIter {
628 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
629 self.inner.fmt(f)
630 }
631 }
632
633 impl IntoIterator for TokenStream {
634 type Item = TokenTree;
635 type IntoIter = IntoIter;
636
637 fn into_iter(self) -> IntoIter {
638 IntoIter {
639 inner: self.inner.into_iter(),
640 _marker: marker::PhantomData,
641 }
642 }
643 }
644}