blob: b7fbb14cab47418890ea08f3c4f4502eec29fa12 [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.
Alex Crichton47c93012018-04-29 16:39:40 -070046#![doc(html_root_url = "https://docs.rs/proc-macro2/0.3.8")]
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;
David Tolnayb1032662017-05-31 15:52:28 -070051extern crate unicode_xid;
Alex Crichton44bffbc2017-05-19 17:51:59 -070052
53use std::fmt;
Alex Crichton44bffbc2017-05-19 17:51:59 -070054use std::iter::FromIterator;
Alex Crichtonaf5bad42018-03-27 14:45:10 -070055use std::marker;
56use std::rc::Rc;
57use std::str::FromStr;
Alex Crichton44bffbc2017-05-19 17:51:59 -070058
David Tolnayb1032662017-05-31 15:52:28 -070059#[macro_use]
David Tolnayb1032662017-05-31 15:52:28 -070060mod strnom;
Alex Crichton30a4e9e2018-04-27 17:02:19 -070061mod stable;
David Tolnayb1032662017-05-31 15:52:28 -070062
David Tolnayd66ecf62018-01-02 20:05:42 -080063#[cfg(not(feature = "nightly"))]
Alex Crichton30a4e9e2018-04-27 17:02:19 -070064use stable as imp;
Alex Crichtonb15c6352017-05-19 19:36:36 -070065#[path = "unstable.rs"]
David Tolnayd66ecf62018-01-02 20:05:42 -080066#[cfg(feature = "nightly")]
Alex Crichton44bffbc2017-05-19 17:51:59 -070067mod imp;
68
David Tolnaycb1b85f2017-06-03 16:40:35 -070069#[derive(Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -070070pub struct TokenStream {
71 inner: imp::TokenStream,
72 _marker: marker::PhantomData<Rc<()>>,
73}
Alex Crichton44bffbc2017-05-19 17:51:59 -070074
Alex Crichtonaf5bad42018-03-27 14:45:10 -070075pub struct LexError {
76 inner: imp::LexError,
77 _marker: marker::PhantomData<Rc<()>>,
78}
79
80impl TokenStream {
81 fn _new(inner: imp::TokenStream) -> TokenStream {
82 TokenStream {
83 inner: inner,
84 _marker: marker::PhantomData,
85 }
86 }
87
Alex Crichton30a4e9e2018-04-27 17:02:19 -070088 fn _new_stable(inner: stable::TokenStream) -> TokenStream {
89 TokenStream {
90 inner: inner.into(),
91 _marker: marker::PhantomData,
92 }
93 }
94
Alex Crichtonaf5bad42018-03-27 14:45:10 -070095 pub fn empty() -> TokenStream {
96 TokenStream::_new(imp::TokenStream::empty())
97 }
98
99 pub fn is_empty(&self) -> bool {
100 self.inner.is_empty()
101 }
102}
Alex Crichton44bffbc2017-05-19 17:51:59 -0700103
104impl FromStr for TokenStream {
105 type Err = LexError;
106
107 fn from_str(src: &str) -> Result<TokenStream, LexError> {
David Tolnayb28f38a2018-03-31 22:02:29 +0200108 let e = src.parse().map_err(|e| LexError {
109 inner: e,
110 _marker: marker::PhantomData,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700111 })?;
112 Ok(TokenStream::_new(e))
Alex Crichton44bffbc2017-05-19 17:51:59 -0700113 }
114}
115
Alex Crichton0e8e7f42018-02-22 06:15:13 -0800116#[cfg(feature = "proc-macro")]
Alex Crichton44bffbc2017-05-19 17:51:59 -0700117impl From<proc_macro::TokenStream> for TokenStream {
118 fn from(inner: proc_macro::TokenStream) -> TokenStream {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700119 TokenStream::_new(inner.into())
Alex Crichton44bffbc2017-05-19 17:51:59 -0700120 }
121}
122
Alex Crichton0e8e7f42018-02-22 06:15:13 -0800123#[cfg(feature = "proc-macro")]
Alex Crichton44bffbc2017-05-19 17:51:59 -0700124impl From<TokenStream> for proc_macro::TokenStream {
125 fn from(inner: TokenStream) -> proc_macro::TokenStream {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700126 inner.inner.into()
Alex Crichton44bffbc2017-05-19 17:51:59 -0700127 }
128}
129
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700130impl FromIterator<TokenTree> for TokenStream {
131 fn from_iter<I: IntoIterator<Item = TokenTree>>(streams: I) -> Self {
132 TokenStream::_new(streams.into_iter().collect())
Alex Crichton44bffbc2017-05-19 17:51:59 -0700133 }
134}
135
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700136impl fmt::Display for TokenStream {
137 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
138 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700139 }
140}
141
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700142impl fmt::Debug for TokenStream {
143 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
144 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700145 }
146}
147
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700148impl fmt::Debug for LexError {
149 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
150 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700151 }
152}
153
Nika Layzellb35a9a32017-12-30 14:34:35 -0500154// Returned by reference, so we can't easily wrap it.
David Tolnay1ebe3972018-01-02 20:14:20 -0800155#[cfg(procmacro2_semver_exempt)]
Nika Layzellb35a9a32017-12-30 14:34:35 -0500156pub use imp::FileName;
157
David Tolnay1ebe3972018-01-02 20:14:20 -0800158#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500159#[derive(Clone, PartialEq, Eq)]
160pub struct SourceFile(imp::SourceFile);
161
David Tolnay1ebe3972018-01-02 20:14:20 -0800162#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500163impl SourceFile {
164 /// Get the path to this source file as a string.
Nika Layzellb35a9a32017-12-30 14:34:35 -0500165 pub fn path(&self) -> &FileName {
166 self.0.path()
Nika Layzellf8d5f212017-12-11 14:07:02 -0500167 }
168
169 pub fn is_real(&self) -> bool {
170 self.0.is_real()
171 }
172}
173
David Tolnay1ebe3972018-01-02 20:14:20 -0800174#[cfg(procmacro2_semver_exempt)]
Nika Layzellb35a9a32017-12-30 14:34:35 -0500175impl AsRef<FileName> for SourceFile {
176 fn as_ref(&self) -> &FileName {
177 self.0.path()
Nika Layzellf8d5f212017-12-11 14:07:02 -0500178 }
179}
180
David Tolnay1ebe3972018-01-02 20:14:20 -0800181#[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500182impl fmt::Debug for SourceFile {
183 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
184 self.0.fmt(f)
185 }
186}
187
David Tolnay1ebe3972018-01-02 20:14:20 -0800188#[cfg(procmacro2_semver_exempt)]
Nika Layzell1ecb6ce2017-12-30 14:34:05 -0500189pub struct LineColumn {
190 pub line: usize,
191 pub column: usize,
192}
Nika Layzellf8d5f212017-12-11 14:07:02 -0500193
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700194#[derive(Copy, Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700195pub struct Span {
196 inner: imp::Span,
197 _marker: marker::PhantomData<Rc<()>>,
198}
Alex Crichton44bffbc2017-05-19 17:51:59 -0700199
Alex Crichton44bffbc2017-05-19 17:51:59 -0700200impl Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700201 fn _new(inner: imp::Span) -> Span {
202 Span {
203 inner: inner,
204 _marker: marker::PhantomData,
205 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700206 }
Alex Crichtone6085b72017-11-21 07:24:25 -0800207
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700208 fn _new_stable(inner: stable::Span) -> Span {
209 Span {
210 inner: inner.into(),
211 _marker: marker::PhantomData,
212 }
213 }
214
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700215 pub fn call_site() -> Span {
216 Span::_new(imp::Span::call_site())
217 }
218
219 #[cfg(procmacro2_semver_exempt)]
Alex Crichtone6085b72017-11-21 07:24:25 -0800220 pub fn def_site() -> Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700221 Span::_new(imp::Span::def_site())
Alex Crichtone6085b72017-11-21 07:24:25 -0800222 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500223
David Tolnay4e8e3972018-01-05 18:10:22 -0800224 /// Creates a new span with the same line/column information as `self` but
225 /// that resolves symbols as though it were at `other`.
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700226 #[cfg(procmacro2_semver_exempt)]
David Tolnay4e8e3972018-01-05 18:10:22 -0800227 pub fn resolved_at(&self, other: Span) -> Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700228 Span::_new(self.inner.resolved_at(other.inner))
David Tolnay4e8e3972018-01-05 18:10:22 -0800229 }
230
231 /// Creates a new span with the same name resolution behavior as `self` but
232 /// with the line/column information of `other`.
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700233 #[cfg(procmacro2_semver_exempt)]
David Tolnay4e8e3972018-01-05 18:10:22 -0800234 pub fn located_at(&self, other: Span) -> Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700235 Span::_new(self.inner.located_at(other.inner))
David Tolnay4e8e3972018-01-05 18:10:22 -0800236 }
237
David Tolnayd66ecf62018-01-02 20:05:42 -0800238 /// This method is only available when the `"nightly"` feature is enabled.
Alex Crichton0e8e7f42018-02-22 06:15:13 -0800239 #[cfg(all(feature = "nightly", feature = "proc-macro"))]
David Tolnay16a17202017-12-31 10:47:24 -0500240 pub fn unstable(self) -> proc_macro::Span {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700241 self.inner.unstable()
David Tolnay16a17202017-12-31 10:47:24 -0500242 }
243
David Tolnay1ebe3972018-01-02 20:14:20 -0800244 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500245 pub fn source_file(&self) -> SourceFile {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700246 SourceFile(self.inner.source_file())
Nika Layzellf8d5f212017-12-11 14:07:02 -0500247 }
248
David Tolnay1ebe3972018-01-02 20:14:20 -0800249 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500250 pub fn start(&self) -> LineColumn {
David Tolnayb28f38a2018-03-31 22:02:29 +0200251 let imp::LineColumn { line, column } = self.inner.start();
252 LineColumn {
253 line: line,
254 column: column,
255 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500256 }
257
David Tolnay1ebe3972018-01-02 20:14:20 -0800258 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500259 pub fn end(&self) -> LineColumn {
David Tolnayb28f38a2018-03-31 22:02:29 +0200260 let imp::LineColumn { line, column } = self.inner.end();
261 LineColumn {
262 line: line,
263 column: column,
264 }
Nika Layzellf8d5f212017-12-11 14:07:02 -0500265 }
266
David Tolnay1ebe3972018-01-02 20:14:20 -0800267 #[cfg(procmacro2_semver_exempt)]
Nika Layzellf8d5f212017-12-11 14:07:02 -0500268 pub fn join(&self, other: Span) -> Option<Span> {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700269 self.inner.join(other.inner).map(Span::_new)
270 }
Alex Crichtonb2c94622018-04-04 07:36:41 -0700271
272 #[cfg(procmacro2_semver_exempt)]
273 pub fn eq(&self, other: &Span) -> bool {
274 self.inner.eq(&other.inner)
275 }
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700276}
277
278impl fmt::Debug for Span {
279 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
280 self.inner.fmt(f)
Nika Layzellf8d5f212017-12-11 14:07:02 -0500281 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700282}
283
David Tolnay034205f2018-04-22 16:45:28 -0700284#[derive(Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700285pub enum TokenTree {
286 Group(Group),
287 Term(Term),
288 Op(Op),
289 Literal(Literal),
Alex Crichton1a7f7622017-07-05 17:47:15 -0700290}
291
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700292impl TokenTree {
293 pub fn span(&self) -> Span {
294 match *self {
295 TokenTree::Group(ref t) => t.span(),
296 TokenTree::Term(ref t) => t.span(),
297 TokenTree::Op(ref t) => t.span(),
298 TokenTree::Literal(ref t) => t.span(),
299 }
300 }
301
302 pub fn set_span(&mut self, span: Span) {
303 match *self {
304 TokenTree::Group(ref mut t) => t.set_span(span),
305 TokenTree::Term(ref mut t) => t.set_span(span),
306 TokenTree::Op(ref mut t) => t.set_span(span),
307 TokenTree::Literal(ref mut t) => t.set_span(span),
308 }
309 }
310}
311
312impl From<Group> for TokenTree {
313 fn from(g: Group) -> TokenTree {
314 TokenTree::Group(g)
315 }
316}
317
318impl From<Term> for TokenTree {
319 fn from(g: Term) -> TokenTree {
320 TokenTree::Term(g)
321 }
322}
323
324impl From<Op> for TokenTree {
325 fn from(g: Op) -> TokenTree {
326 TokenTree::Op(g)
327 }
328}
329
330impl From<Literal> for TokenTree {
331 fn from(g: Literal) -> TokenTree {
332 TokenTree::Literal(g)
Alex Crichton1a7f7622017-07-05 17:47:15 -0700333 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700334}
335
Alex Crichton44bffbc2017-05-19 17:51:59 -0700336impl fmt::Display for TokenTree {
337 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700338 match *self {
339 TokenTree::Group(ref t) => t.fmt(f),
340 TokenTree::Term(ref t) => t.fmt(f),
341 TokenTree::Op(ref t) => t.fmt(f),
342 TokenTree::Literal(ref t) => t.fmt(f),
343 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700344 }
345}
346
David Tolnay034205f2018-04-22 16:45:28 -0700347impl fmt::Debug for TokenTree {
348 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
349 // Each of these has the name in the struct type in the derived debug,
350 // so don't bother with an extra layer of indirection
351 match *self {
352 TokenTree::Group(ref t) => t.fmt(f),
353 TokenTree::Term(ref t) => t.fmt(f),
354 TokenTree::Op(ref t) => t.fmt(f),
355 TokenTree::Literal(ref t) => t.fmt(f),
356 }
357 }
358}
359
360#[derive(Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700361pub struct Group {
362 delimiter: Delimiter,
363 stream: TokenStream,
364 span: Span,
Alex Crichton44bffbc2017-05-19 17:51:59 -0700365}
366
Michael Layzell5372f4b2017-06-02 10:29:31 -0400367#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Alex Crichton44bffbc2017-05-19 17:51:59 -0700368pub enum Delimiter {
369 Parenthesis,
370 Brace,
371 Bracket,
372 None,
373}
374
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700375impl Group {
376 pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
377 Group {
378 delimiter: delimiter,
379 stream: stream,
380 span: Span::call_site(),
381 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700382 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700383
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700384 pub fn delimiter(&self) -> Delimiter {
385 self.delimiter
Alex Crichton44bffbc2017-05-19 17:51:59 -0700386 }
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700387
388 pub fn stream(&self) -> TokenStream {
389 self.stream.clone()
390 }
391
392 pub fn span(&self) -> Span {
393 self.span
394 }
395
396 pub fn set_span(&mut self, span: Span) {
397 self.span = span;
398 }
399}
400
401impl fmt::Display for Group {
402 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
403 self.stream.fmt(f)
404 }
405}
406
David Tolnay034205f2018-04-22 16:45:28 -0700407impl fmt::Debug for Group {
408 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
409 let mut debug = fmt.debug_struct("Group");
410 debug.field("delimiter", &self.delimiter);
411 debug.field("stream", &self.stream);
412 #[cfg(procmacro2_semver_exempt)]
413 debug.field("span", &self.span);
414 debug.finish()
415 }
416}
417
418#[derive(Copy, Clone)]
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700419pub struct Op {
420 op: char,
421 spacing: Spacing,
422 span: Span,
Alex Crichton44bffbc2017-05-19 17:51:59 -0700423}
424
Lukas Kalbertodteb3f9302017-08-20 18:58:41 +0200425#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Alex Crichton1a7f7622017-07-05 17:47:15 -0700426pub enum Spacing {
Alex Crichton44bffbc2017-05-19 17:51:59 -0700427 Alone,
428 Joint,
429}
430
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700431impl Op {
432 pub fn new(op: char, spacing: Spacing) -> Op {
433 Op {
434 op: op,
435 spacing: spacing,
436 span: Span::call_site(),
437 }
438 }
Alex Crichton44bffbc2017-05-19 17:51:59 -0700439
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700440 pub fn op(&self) -> char {
441 self.op
442 }
443
444 pub fn spacing(&self) -> Spacing {
445 self.spacing
446 }
447
448 pub fn span(&self) -> Span {
449 self.span
450 }
451
452 pub fn set_span(&mut self, span: Span) {
453 self.span = span;
454 }
455}
456
457impl fmt::Display for Op {
458 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
459 self.op.fmt(f)
460 }
461}
462
David Tolnay034205f2018-04-22 16:45:28 -0700463impl fmt::Debug for Op {
464 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
465 let mut debug = fmt.debug_struct("Op");
466 debug.field("op", &self.op);
467 debug.field("spacing", &self.spacing);
468 #[cfg(procmacro2_semver_exempt)]
469 debug.field("span", &self.span);
470 debug.finish()
471 }
472}
473
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700474#[derive(Copy, Clone)]
475pub struct Term {
476 inner: imp::Term,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700477 _marker: marker::PhantomData<Rc<()>>,
478}
479
480impl Term {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700481 fn _new(inner: imp::Term) -> Term {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700482 Term {
483 inner: inner,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700484 _marker: marker::PhantomData,
485 }
486 }
487
488 pub fn new(string: &str, span: Span) -> Term {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700489 Term::_new(imp::Term::new(string, span.inner))
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700490 }
491
492 pub fn as_str(&self) -> &str {
493 self.inner.as_str()
494 }
495
496 pub fn span(&self) -> Span {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700497 Span::_new(self.inner.span())
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700498 }
499
500 pub fn set_span(&mut self, span: Span) {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700501 self.inner.set_span(span.inner);
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700502 }
503}
504
505impl fmt::Display for Term {
506 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
507 self.as_str().fmt(f)
508 }
509}
510
511impl fmt::Debug for Term {
512 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
513 self.inner.fmt(f)
514 }
515}
516
517#[derive(Clone)]
518pub struct Literal {
519 inner: imp::Literal,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700520 _marker: marker::PhantomData<Rc<()>>,
521}
522
Alex Crichtona914a612018-04-04 07:48:44 -0700523macro_rules! int_literals {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700524 ($($name:ident => $kind:ident,)*) => ($(
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700525 pub fn $name(n: $kind) -> Literal {
Alex Crichtona914a612018-04-04 07:48:44 -0700526 Literal::_new(imp::Literal::$name(n))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700527 }
528 )*)
529}
530
Alex Crichton852d53d2017-05-19 19:25:08 -0700531impl Literal {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700532 fn _new(inner: imp::Literal) -> Literal {
533 Literal {
534 inner: inner,
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700535 _marker: marker::PhantomData,
536 }
Alex Crichton1a7f7622017-07-05 17:47:15 -0700537 }
538
Alex Crichton30a4e9e2018-04-27 17:02:19 -0700539 fn _new_stable(inner: stable::Literal) -> Literal {
540 Literal {
541 inner: inner.into(),
542 _marker: marker::PhantomData,
543 }
544 }
545
Alex Crichtona914a612018-04-04 07:48:44 -0700546 int_literals! {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700547 u8_suffixed => u8,
548 u16_suffixed => u16,
549 u32_suffixed => u32,
550 u64_suffixed => u64,
551 usize_suffixed => usize,
552 i8_suffixed => i8,
553 i16_suffixed => i16,
554 i32_suffixed => i32,
555 i64_suffixed => i64,
556 isize_suffixed => isize,
Alex Crichton1a7f7622017-07-05 17:47:15 -0700557
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700558 u8_unsuffixed => u8,
559 u16_unsuffixed => u16,
560 u32_unsuffixed => u32,
561 u64_unsuffixed => u64,
562 usize_unsuffixed => usize,
563 i8_unsuffixed => i8,
564 i16_unsuffixed => i16,
565 i32_unsuffixed => i32,
566 i64_unsuffixed => i64,
567 isize_unsuffixed => isize,
Alex Crichton1a7f7622017-07-05 17:47:15 -0700568 }
569
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700570 pub fn f64_unsuffixed(f: f64) -> Literal {
571 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700572 Literal::_new(imp::Literal::f64_unsuffixed(f))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700573 }
574
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700575 pub fn f64_suffixed(f: f64) -> Literal {
576 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700577 Literal::_new(imp::Literal::f64_suffixed(f))
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700578 }
579
580 pub fn f32_unsuffixed(f: f32) -> Literal {
581 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700582 Literal::_new(imp::Literal::f32_unsuffixed(f))
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700583 }
584
585 pub fn f32_suffixed(f: f32) -> Literal {
586 assert!(f.is_finite());
Alex Crichtona914a612018-04-04 07:48:44 -0700587 Literal::_new(imp::Literal::f32_suffixed(f))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700588 }
589
590 pub fn string(string: &str) -> Literal {
Alex Crichtona914a612018-04-04 07:48:44 -0700591 Literal::_new(imp::Literal::string(string))
Alex Crichton1a7f7622017-07-05 17:47:15 -0700592 }
593
594 pub fn character(ch: char) -> Literal {
Alex Crichtona914a612018-04-04 07:48:44 -0700595 Literal::_new(imp::Literal::character(ch))
Alex Crichton76a5cc82017-05-23 07:01:44 -0700596 }
597
Alex Crichton9c2fb0a2017-05-26 08:49:31 -0700598 pub fn byte_string(s: &[u8]) -> Literal {
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700599 Literal::_new(imp::Literal::byte_string(s))
Alex Crichton852d53d2017-05-19 19:25:08 -0700600 }
Alex Crichton76a5cc82017-05-23 07:01:44 -0700601
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700602 pub fn span(&self) -> Span {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700603 Span::_new(self.inner.span())
Alex Crichton1a7f7622017-07-05 17:47:15 -0700604 }
605
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700606 pub fn set_span(&mut self, span: Span) {
Alex Crichtonb2c94622018-04-04 07:36:41 -0700607 self.inner.set_span(span.inner);
Alex Crichton31316622017-05-26 12:54:47 -0700608 }
Alex Crichton852d53d2017-05-19 19:25:08 -0700609}
610
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700611impl fmt::Debug for Literal {
612 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
613 self.inner.fmt(f)
Alex Crichton44bffbc2017-05-19 17:51:59 -0700614 }
615}
David Tolnaycb1b85f2017-06-03 16:40:35 -0700616
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700617impl fmt::Display for Literal {
618 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
619 self.inner.fmt(f)
620 }
621}
622
623pub mod token_stream {
624 use std::fmt;
625 use std::marker;
626 use std::rc::Rc;
627
David Tolnay48ea5042018-04-23 19:17:35 -0700628 use imp;
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700629 pub use TokenStream;
David Tolnayb28f38a2018-03-31 22:02:29 +0200630 use TokenTree;
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700631
632 pub struct IntoIter {
633 inner: imp::TokenTreeIter,
634 _marker: marker::PhantomData<Rc<()>>,
635 }
636
Alex Crichtonaf5bad42018-03-27 14:45:10 -0700637 impl Iterator for IntoIter {
638 type Item = TokenTree;
639
640 fn next(&mut self) -> Option<TokenTree> {
641 self.inner.next()
642 }
643 }
644
645 impl fmt::Debug for IntoIter {
646 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
647 self.inner.fmt(f)
648 }
649 }
650
651 impl IntoIterator for TokenStream {
652 type Item = TokenTree;
653 type IntoIter = IntoIter;
654
655 fn into_iter(self) -> IntoIter {
656 IntoIter {
657 inner: self.inner.into_iter(),
658 _marker: marker::PhantomData,
659 }
660 }
661 }
662}