]>
Commit | Line | Data |
---|---|---|
dc9dc135 XL |
1 | //! A wrapper around the procedural macro API of the compiler's [`proc_macro`] |
2 | //! crate. This library serves three purposes: | |
0531ce1d | 3 | //! |
dc9dc135 XL |
4 | //! [`proc_macro`]: https://doc.rust-lang.org/proc_macro/ |
5 | //! | |
6 | //! - **Bring proc-macro-like functionality to other contexts like build.rs and | |
7 | //! main.rs.** Types from `proc_macro` are entirely specific to procedural | |
8 | //! macros and cannot ever exist in code outside of a procedural macro. | |
9 | //! Meanwhile `proc_macro2` types may exist anywhere including non-macro code. | |
10 | //! By developing foundational libraries like [syn] and [quote] against | |
11 | //! `proc_macro2` rather than `proc_macro`, the procedural macro ecosystem | |
12 | //! becomes easily applicable to many other use cases and we avoid | |
13 | //! reimplementing non-macro equivalents of those libraries. | |
14 | //! | |
15 | //! - **Make procedural macros unit testable.** As a consequence of being | |
16 | //! specific to procedural macros, nothing that uses `proc_macro` can be | |
17 | //! executed from a unit test. In order for helper libraries or components of | |
18 | //! a macro to be testable in isolation, they must be implemented using | |
19 | //! `proc_macro2`. | |
20 | //! | |
21 | //! - **Provide the latest and greatest APIs across all compiler versions.** | |
22 | //! Procedural macros were first introduced to Rust in 1.15.0 with an | |
23 | //! extremely minimal interface. Since then, many improvements have landed to | |
24 | //! make macros more flexible and easier to write. This library tracks the | |
25 | //! procedural macro API of the most recent stable compiler but employs a | |
26 | //! polyfill to provide that API consistently across any compiler since | |
27 | //! 1.15.0. | |
28 | //! | |
29 | //! [syn]: https://github.com/dtolnay/syn | |
30 | //! [quote]: https://github.com/dtolnay/quote | |
31 | //! | |
32 | //! # Usage | |
33 | //! | |
34 | //! The skeleton of a typical procedural macro typically looks like this: | |
35 | //! | |
36 | //! ```edition2018 | |
37 | //! extern crate proc_macro; | |
0531ce1d | 38 | //! |
dc9dc135 XL |
39 | //! # const IGNORE: &str = stringify! { |
40 | //! #[proc_macro_derive(MyDerive)] | |
41 | //! # }; | |
42 | //! pub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { | |
43 | //! let input = proc_macro2::TokenStream::from(input); | |
0531ce1d | 44 | //! |
dc9dc135 XL |
45 | //! let output: proc_macro2::TokenStream = { |
46 | //! /* transform input */ | |
47 | //! # input | |
48 | //! }; | |
0531ce1d | 49 | //! |
dc9dc135 XL |
50 | //! proc_macro::TokenStream::from(output) |
51 | //! } | |
52 | //! ``` | |
53 | //! | |
54 | //! If parsing with [Syn], you'll use [`parse_macro_input!`] instead to | |
55 | //! propagate parse errors correctly back to the compiler when parsing fails. | |
56 | //! | |
57 | //! [`parse_macro_input!`]: https://docs.rs/syn/0.15/syn/macro.parse_macro_input.html | |
58 | //! | |
59 | //! # Unstable features | |
8faf50e0 | 60 | //! |
dc9dc135 XL |
61 | //! The default feature set of proc-macro2 tracks the most recent stable |
62 | //! compiler API. Functionality in `proc_macro` that is not yet stable is not | |
63 | //! exposed by proc-macro2 by default. | |
8faf50e0 | 64 | //! |
dc9dc135 XL |
65 | //! To opt into the additional APIs available in the most recent nightly |
66 | //! compiler, the `procmacro2_semver_exempt` config flag must be passed to | |
67 | //! rustc. As usual, we will polyfill those nightly-only APIs all the way back | |
68 | //! to Rust 1.15.0. As these are unstable APIs that track the nightly compiler, | |
69 | //! minor versions of proc-macro2 may make breaking changes to them at any time. | |
8faf50e0 XL |
70 | //! |
71 | //! ```sh | |
72 | //! RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build | |
73 | //! ``` | |
74 | //! | |
75 | //! Note that this must not only be done for your crate, but for any crate that | |
76 | //! depends on your crate. This infectious nature is intentional, as it serves | |
77 | //! as a reminder that you are outside of the normal semver guarantees. | |
78 | //! | |
dc9dc135 | 79 | //! Semver exempt methods are marked as such in the proc-macro2 documentation. |
0531ce1d XL |
80 | |
81 | // Proc-macro2 types in rustdoc of other crates get linked to here. | |
dc9dc135 XL |
82 | #![doc(html_root_url = "https://docs.rs/proc-macro2/0.4.30")] |
83 | #![cfg_attr(any(proc_macro_span, super_unstable), feature(proc_macro_span))] | |
84 | #![cfg_attr(super_unstable, feature(proc_macro_raw_ident, proc_macro_def_site))] | |
0531ce1d | 85 | |
b7449926 | 86 | #[cfg(use_proc_macro)] |
0531ce1d | 87 | extern crate proc_macro; |
0531ce1d XL |
88 | extern crate unicode_xid; |
89 | ||
8faf50e0 | 90 | use std::cmp::Ordering; |
0531ce1d | 91 | use std::fmt; |
8faf50e0 | 92 | use std::hash::{Hash, Hasher}; |
0531ce1d | 93 | use std::iter::FromIterator; |
83c7162d | 94 | use std::marker; |
13cf67c4 XL |
95 | #[cfg(procmacro2_semver_exempt)] |
96 | use std::path::PathBuf; | |
83c7162d XL |
97 | use std::rc::Rc; |
98 | use std::str::FromStr; | |
0531ce1d XL |
99 | |
100 | #[macro_use] | |
0531ce1d | 101 | mod strnom; |
dc9dc135 | 102 | mod fallback; |
0531ce1d | 103 | |
13cf67c4 | 104 | #[cfg(not(wrap_proc_macro))] |
dc9dc135 XL |
105 | use fallback as imp; |
106 | #[path = "wrapper.rs"] | |
13cf67c4 | 107 | #[cfg(wrap_proc_macro)] |
0531ce1d XL |
108 | mod imp; |
109 | ||
8faf50e0 XL |
110 | /// An abstract stream of tokens, or more concretely a sequence of token trees. |
111 | /// | |
112 | /// This type provides interfaces for iterating over token trees and for | |
113 | /// collecting token trees into one stream. | |
114 | /// | |
115 | /// Token stream is both the input and output of `#[proc_macro]`, | |
116 | /// `#[proc_macro_attribute]` and `#[proc_macro_derive]` definitions. | |
0531ce1d | 117 | #[derive(Clone)] |
83c7162d XL |
118 | pub struct TokenStream { |
119 | inner: imp::TokenStream, | |
120 | _marker: marker::PhantomData<Rc<()>>, | |
121 | } | |
122 | ||
8faf50e0 | 123 | /// Error returned from `TokenStream::from_str`. |
83c7162d XL |
124 | pub struct LexError { |
125 | inner: imp::LexError, | |
126 | _marker: marker::PhantomData<Rc<()>>, | |
127 | } | |
128 | ||
129 | impl TokenStream { | |
130 | fn _new(inner: imp::TokenStream) -> TokenStream { | |
131 | TokenStream { | |
132 | inner: inner, | |
133 | _marker: marker::PhantomData, | |
134 | } | |
135 | } | |
0531ce1d | 136 | |
dc9dc135 | 137 | fn _new_stable(inner: fallback::TokenStream) -> TokenStream { |
8faf50e0 XL |
138 | TokenStream { |
139 | inner: inner.into(), | |
140 | _marker: marker::PhantomData, | |
141 | } | |
142 | } | |
143 | ||
144 | /// Returns an empty `TokenStream` containing no token trees. | |
145 | pub fn new() -> TokenStream { | |
146 | TokenStream::_new(imp::TokenStream::new()) | |
147 | } | |
148 | ||
149 | #[deprecated(since = "0.4.4", note = "please use TokenStream::new")] | |
83c7162d | 150 | pub fn empty() -> TokenStream { |
8faf50e0 | 151 | TokenStream::new() |
83c7162d XL |
152 | } |
153 | ||
8faf50e0 | 154 | /// Checks if this `TokenStream` is empty. |
83c7162d XL |
155 | pub fn is_empty(&self) -> bool { |
156 | self.inner.is_empty() | |
157 | } | |
158 | } | |
0531ce1d | 159 | |
8faf50e0 XL |
160 | /// `TokenStream::default()` returns an empty stream, |
161 | /// i.e. this is equivalent with `TokenStream::new()`. | |
162 | impl Default for TokenStream { | |
163 | fn default() -> Self { | |
164 | TokenStream::new() | |
165 | } | |
166 | } | |
167 | ||
168 | /// Attempts to break the string into tokens and parse those tokens into a token | |
169 | /// stream. | |
170 | /// | |
171 | /// May fail for a number of reasons, for example, if the string contains | |
172 | /// unbalanced delimiters or characters not existing in the language. | |
173 | /// | |
174 | /// NOTE: Some errors may cause panics instead of returning `LexError`. We | |
175 | /// reserve the right to change these errors into `LexError`s later. | |
0531ce1d XL |
176 | impl FromStr for TokenStream { |
177 | type Err = LexError; | |
178 | ||
179 | fn from_str(src: &str) -> Result<TokenStream, LexError> { | |
83c7162d XL |
180 | let e = src.parse().map_err(|e| LexError { |
181 | inner: e, | |
182 | _marker: marker::PhantomData, | |
183 | })?; | |
184 | Ok(TokenStream::_new(e)) | |
0531ce1d XL |
185 | } |
186 | } | |
187 | ||
b7449926 | 188 | #[cfg(use_proc_macro)] |
0531ce1d XL |
189 | impl From<proc_macro::TokenStream> for TokenStream { |
190 | fn from(inner: proc_macro::TokenStream) -> TokenStream { | |
83c7162d | 191 | TokenStream::_new(inner.into()) |
0531ce1d XL |
192 | } |
193 | } | |
194 | ||
b7449926 | 195 | #[cfg(use_proc_macro)] |
0531ce1d XL |
196 | impl From<TokenStream> for proc_macro::TokenStream { |
197 | fn from(inner: TokenStream) -> proc_macro::TokenStream { | |
83c7162d | 198 | inner.inner.into() |
0531ce1d XL |
199 | } |
200 | } | |
201 | ||
8faf50e0 XL |
202 | impl Extend<TokenTree> for TokenStream { |
203 | fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, streams: I) { | |
204 | self.inner.extend(streams) | |
205 | } | |
206 | } | |
207 | ||
b7449926 XL |
208 | impl Extend<TokenStream> for TokenStream { |
209 | fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) { | |
210 | self.inner | |
211 | .extend(streams.into_iter().map(|stream| stream.inner)) | |
212 | } | |
213 | } | |
214 | ||
8faf50e0 | 215 | /// Collects a number of token trees into a single stream. |
83c7162d XL |
216 | impl FromIterator<TokenTree> for TokenStream { |
217 | fn from_iter<I: IntoIterator<Item = TokenTree>>(streams: I) -> Self { | |
218 | TokenStream::_new(streams.into_iter().collect()) | |
0531ce1d XL |
219 | } |
220 | } | |
13cf67c4 XL |
221 | impl FromIterator<TokenStream> for TokenStream { |
222 | fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self { | |
223 | TokenStream::_new(streams.into_iter().map(|i| i.inner).collect()) | |
224 | } | |
225 | } | |
0531ce1d | 226 | |
8faf50e0 XL |
227 | /// Prints the token stream as a string that is supposed to be losslessly |
228 | /// convertible back into the same token stream (modulo spans), except for | |
229 | /// possibly `TokenTree::Group`s with `Delimiter::None` delimiters and negative | |
230 | /// numeric literals. | |
83c7162d XL |
231 | impl fmt::Display for TokenStream { |
232 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
233 | self.inner.fmt(f) | |
0531ce1d XL |
234 | } |
235 | } | |
236 | ||
8faf50e0 | 237 | /// Prints token in a form convenient for debugging. |
83c7162d XL |
238 | impl fmt::Debug for TokenStream { |
239 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
240 | self.inner.fmt(f) | |
0531ce1d XL |
241 | } |
242 | } | |
243 | ||
83c7162d XL |
244 | impl fmt::Debug for LexError { |
245 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
246 | self.inner.fmt(f) | |
0531ce1d XL |
247 | } |
248 | } | |
249 | ||
8faf50e0 XL |
250 | /// The source file of a given `Span`. |
251 | /// | |
252 | /// This type is semver exempt and not exposed by default. | |
0531ce1d XL |
253 | #[cfg(procmacro2_semver_exempt)] |
254 | #[derive(Clone, PartialEq, Eq)] | |
13cf67c4 XL |
255 | pub struct SourceFile { |
256 | inner: imp::SourceFile, | |
257 | _marker: marker::PhantomData<Rc<()>>, | |
258 | } | |
0531ce1d XL |
259 | |
260 | #[cfg(procmacro2_semver_exempt)] | |
261 | impl SourceFile { | |
13cf67c4 XL |
262 | fn _new(inner: imp::SourceFile) -> Self { |
263 | SourceFile { | |
264 | inner: inner, | |
265 | _marker: marker::PhantomData, | |
266 | } | |
267 | } | |
268 | ||
8faf50e0 XL |
269 | /// Get the path to this source file. |
270 | /// | |
271 | /// ### Note | |
272 | /// | |
273 | /// If the code span associated with this `SourceFile` was generated by an | |
274 | /// external macro, this may not be an actual path on the filesystem. Use | |
275 | /// [`is_real`] to check. | |
276 | /// | |
277 | /// Also note that even if `is_real` returns `true`, if | |
278 | /// `--remap-path-prefix` was passed on the command line, the path as given | |
279 | /// may not actually be valid. | |
280 | /// | |
281 | /// [`is_real`]: #method.is_real | |
13cf67c4 XL |
282 | pub fn path(&self) -> PathBuf { |
283 | self.inner.path() | |
0531ce1d XL |
284 | } |
285 | ||
8faf50e0 XL |
286 | /// Returns `true` if this source file is a real source file, and not |
287 | /// generated by an external macro's expansion. | |
0531ce1d | 288 | pub fn is_real(&self) -> bool { |
13cf67c4 | 289 | self.inner.is_real() |
0531ce1d XL |
290 | } |
291 | } | |
292 | ||
293 | #[cfg(procmacro2_semver_exempt)] | |
294 | impl fmt::Debug for SourceFile { | |
295 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
13cf67c4 | 296 | self.inner.fmt(f) |
0531ce1d XL |
297 | } |
298 | } | |
299 | ||
8faf50e0 XL |
300 | /// A line-column pair representing the start or end of a `Span`. |
301 | /// | |
302 | /// This type is semver exempt and not exposed by default. | |
dc9dc135 XL |
303 | #[cfg(span_locations)] |
304 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] | |
0531ce1d | 305 | pub struct LineColumn { |
8faf50e0 XL |
306 | /// The 1-indexed line in the source file on which the span starts or ends |
307 | /// (inclusive). | |
0531ce1d | 308 | pub line: usize, |
8faf50e0 XL |
309 | /// The 0-indexed column (in UTF-8 characters) in the source file on which |
310 | /// the span starts or ends (inclusive). | |
0531ce1d XL |
311 | pub column: usize, |
312 | } | |
313 | ||
8faf50e0 | 314 | /// A region of source code, along with macro expansion information. |
0531ce1d | 315 | #[derive(Copy, Clone)] |
83c7162d XL |
316 | pub struct Span { |
317 | inner: imp::Span, | |
318 | _marker: marker::PhantomData<Rc<()>>, | |
319 | } | |
0531ce1d XL |
320 | |
321 | impl Span { | |
83c7162d XL |
322 | fn _new(inner: imp::Span) -> Span { |
323 | Span { | |
324 | inner: inner, | |
325 | _marker: marker::PhantomData, | |
326 | } | |
327 | } | |
328 | ||
dc9dc135 | 329 | fn _new_stable(inner: fallback::Span) -> Span { |
8faf50e0 XL |
330 | Span { |
331 | inner: inner.into(), | |
332 | _marker: marker::PhantomData, | |
333 | } | |
334 | } | |
335 | ||
336 | /// The span of the invocation of the current procedural macro. | |
337 | /// | |
338 | /// Identifiers created with this span will be resolved as if they were | |
339 | /// written directly at the macro call location (call-site hygiene) and | |
340 | /// other code at the macro call site will be able to refer to them as well. | |
0531ce1d | 341 | pub fn call_site() -> Span { |
83c7162d | 342 | Span::_new(imp::Span::call_site()) |
0531ce1d XL |
343 | } |
344 | ||
8faf50e0 XL |
345 | /// A span that resolves at the macro definition site. |
346 | /// | |
347 | /// This method is semver exempt and not exposed by default. | |
83c7162d | 348 | #[cfg(procmacro2_semver_exempt)] |
0531ce1d | 349 | pub fn def_site() -> Span { |
83c7162d | 350 | Span::_new(imp::Span::def_site()) |
0531ce1d XL |
351 | } |
352 | ||
353 | /// Creates a new span with the same line/column information as `self` but | |
354 | /// that resolves symbols as though it were at `other`. | |
8faf50e0 XL |
355 | /// |
356 | /// This method is semver exempt and not exposed by default. | |
83c7162d | 357 | #[cfg(procmacro2_semver_exempt)] |
0531ce1d | 358 | pub fn resolved_at(&self, other: Span) -> Span { |
83c7162d | 359 | Span::_new(self.inner.resolved_at(other.inner)) |
0531ce1d XL |
360 | } |
361 | ||
362 | /// Creates a new span with the same name resolution behavior as `self` but | |
363 | /// with the line/column information of `other`. | |
8faf50e0 XL |
364 | /// |
365 | /// This method is semver exempt and not exposed by default. | |
83c7162d | 366 | #[cfg(procmacro2_semver_exempt)] |
0531ce1d | 367 | pub fn located_at(&self, other: Span) -> Span { |
83c7162d | 368 | Span::_new(self.inner.located_at(other.inner)) |
0531ce1d XL |
369 | } |
370 | ||
dc9dc135 XL |
371 | /// Convert `proc_macro2::Span` to `proc_macro::Span`. |
372 | /// | |
373 | /// This method is available when building with a nightly compiler, or when | |
374 | /// building with rustc 1.29+ *without* semver exempt features. | |
375 | /// | |
376 | /// # Panics | |
377 | /// | |
378 | /// Panics if called from outside of a procedural macro. Unlike | |
379 | /// `proc_macro2::Span`, the `proc_macro::Span` type can only exist within | |
380 | /// the context of a procedural macro invocation. | |
381 | #[cfg(wrap_proc_macro)] | |
382 | pub fn unwrap(self) -> proc_macro::Span { | |
383 | self.inner.unwrap() | |
384 | } | |
385 | ||
386 | // Soft deprecated. Please use Span::unwrap. | |
387 | #[cfg(wrap_proc_macro)] | |
13cf67c4 | 388 | #[doc(hidden)] |
0531ce1d | 389 | pub fn unstable(self) -> proc_macro::Span { |
dc9dc135 | 390 | self.unwrap() |
0531ce1d XL |
391 | } |
392 | ||
8faf50e0 XL |
393 | /// The original source file into which this span points. |
394 | /// | |
395 | /// This method is semver exempt and not exposed by default. | |
0531ce1d XL |
396 | #[cfg(procmacro2_semver_exempt)] |
397 | pub fn source_file(&self) -> SourceFile { | |
13cf67c4 | 398 | SourceFile::_new(self.inner.source_file()) |
0531ce1d XL |
399 | } |
400 | ||
8faf50e0 XL |
401 | /// Get the starting line/column in the source file for this span. |
402 | /// | |
dc9dc135 XL |
403 | /// This method requires the `"span-locations"` feature to be enabled. |
404 | #[cfg(span_locations)] | |
0531ce1d | 405 | pub fn start(&self) -> LineColumn { |
83c7162d XL |
406 | let imp::LineColumn { line, column } = self.inner.start(); |
407 | LineColumn { | |
408 | line: line, | |
409 | column: column, | |
410 | } | |
0531ce1d XL |
411 | } |
412 | ||
8faf50e0 XL |
413 | /// Get the ending line/column in the source file for this span. |
414 | /// | |
dc9dc135 XL |
415 | /// This method requires the `"span-locations"` feature to be enabled. |
416 | #[cfg(span_locations)] | |
0531ce1d | 417 | pub fn end(&self) -> LineColumn { |
83c7162d XL |
418 | let imp::LineColumn { line, column } = self.inner.end(); |
419 | LineColumn { | |
420 | line: line, | |
421 | column: column, | |
422 | } | |
0531ce1d XL |
423 | } |
424 | ||
8faf50e0 XL |
425 | /// Create a new span encompassing `self` and `other`. |
426 | /// | |
427 | /// Returns `None` if `self` and `other` are from different files. | |
428 | /// | |
429 | /// This method is semver exempt and not exposed by default. | |
0531ce1d XL |
430 | #[cfg(procmacro2_semver_exempt)] |
431 | pub fn join(&self, other: Span) -> Option<Span> { | |
83c7162d XL |
432 | self.inner.join(other.inner).map(Span::_new) |
433 | } | |
434 | ||
8faf50e0 XL |
435 | /// Compares to spans to see if they're equal. |
436 | /// | |
437 | /// This method is semver exempt and not exposed by default. | |
83c7162d XL |
438 | #[cfg(procmacro2_semver_exempt)] |
439 | pub fn eq(&self, other: &Span) -> bool { | |
440 | self.inner.eq(&other.inner) | |
441 | } | |
442 | } | |
443 | ||
8faf50e0 | 444 | /// Prints a span in a form convenient for debugging. |
83c7162d XL |
445 | impl fmt::Debug for Span { |
446 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
447 | self.inner.fmt(f) | |
0531ce1d XL |
448 | } |
449 | } | |
450 | ||
8faf50e0 XL |
451 | /// A single token or a delimited sequence of token trees (e.g. `[1, (), ..]`). |
452 | #[derive(Clone)] | |
83c7162d | 453 | pub enum TokenTree { |
8faf50e0 | 454 | /// A token stream surrounded by bracket delimiters. |
83c7162d | 455 | Group(Group), |
8faf50e0 XL |
456 | /// An identifier. |
457 | Ident(Ident), | |
458 | /// A single punctuation character (`+`, `,`, `$`, etc.). | |
459 | Punct(Punct), | |
460 | /// A literal character (`'a'`), string (`"hello"`), number (`2.3`), etc. | |
83c7162d XL |
461 | Literal(Literal), |
462 | } | |
463 | ||
464 | impl TokenTree { | |
8faf50e0 XL |
465 | /// Returns the span of this tree, delegating to the `span` method of |
466 | /// the contained token or a delimited stream. | |
83c7162d XL |
467 | pub fn span(&self) -> Span { |
468 | match *self { | |
469 | TokenTree::Group(ref t) => t.span(), | |
8faf50e0 XL |
470 | TokenTree::Ident(ref t) => t.span(), |
471 | TokenTree::Punct(ref t) => t.span(), | |
83c7162d XL |
472 | TokenTree::Literal(ref t) => t.span(), |
473 | } | |
474 | } | |
475 | ||
8faf50e0 XL |
476 | /// Configures the span for *only this token*. |
477 | /// | |
478 | /// Note that if this token is a `Group` then this method will not configure | |
479 | /// the span of each of the internal tokens, this will simply delegate to | |
480 | /// the `set_span` method of each variant. | |
83c7162d XL |
481 | pub fn set_span(&mut self, span: Span) { |
482 | match *self { | |
483 | TokenTree::Group(ref mut t) => t.set_span(span), | |
8faf50e0 XL |
484 | TokenTree::Ident(ref mut t) => t.set_span(span), |
485 | TokenTree::Punct(ref mut t) => t.set_span(span), | |
83c7162d XL |
486 | TokenTree::Literal(ref mut t) => t.set_span(span), |
487 | } | |
488 | } | |
489 | } | |
490 | ||
491 | impl From<Group> for TokenTree { | |
492 | fn from(g: Group) -> TokenTree { | |
493 | TokenTree::Group(g) | |
494 | } | |
495 | } | |
496 | ||
8faf50e0 XL |
497 | impl From<Ident> for TokenTree { |
498 | fn from(g: Ident) -> TokenTree { | |
499 | TokenTree::Ident(g) | |
83c7162d | 500 | } |
0531ce1d XL |
501 | } |
502 | ||
8faf50e0 XL |
503 | impl From<Punct> for TokenTree { |
504 | fn from(g: Punct) -> TokenTree { | |
505 | TokenTree::Punct(g) | |
83c7162d XL |
506 | } |
507 | } | |
508 | ||
509 | impl From<Literal> for TokenTree { | |
510 | fn from(g: Literal) -> TokenTree { | |
511 | TokenTree::Literal(g) | |
0531ce1d XL |
512 | } |
513 | } | |
514 | ||
8faf50e0 XL |
515 | /// Prints the token tree as a string that is supposed to be losslessly |
516 | /// convertible back into the same token tree (modulo spans), except for | |
517 | /// possibly `TokenTree::Group`s with `Delimiter::None` delimiters and negative | |
518 | /// numeric literals. | |
0531ce1d XL |
519 | impl fmt::Display for TokenTree { |
520 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
83c7162d XL |
521 | match *self { |
522 | TokenTree::Group(ref t) => t.fmt(f), | |
8faf50e0 XL |
523 | TokenTree::Ident(ref t) => t.fmt(f), |
524 | TokenTree::Punct(ref t) => t.fmt(f), | |
525 | TokenTree::Literal(ref t) => t.fmt(f), | |
526 | } | |
527 | } | |
528 | } | |
529 | ||
530 | /// Prints token tree in a form convenient for debugging. | |
531 | impl fmt::Debug for TokenTree { | |
532 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
533 | // Each of these has the name in the struct type in the derived debug, | |
534 | // so don't bother with an extra layer of indirection | |
535 | match *self { | |
536 | TokenTree::Group(ref t) => t.fmt(f), | |
537 | TokenTree::Ident(ref t) => { | |
538 | let mut debug = f.debug_struct("Ident"); | |
539 | debug.field("sym", &format_args!("{}", t)); | |
dc9dc135 | 540 | imp::debug_span_field_if_nontrivial(&mut debug, t.span().inner); |
8faf50e0 XL |
541 | debug.finish() |
542 | } | |
543 | TokenTree::Punct(ref t) => t.fmt(f), | |
83c7162d XL |
544 | TokenTree::Literal(ref t) => t.fmt(f), |
545 | } | |
0531ce1d XL |
546 | } |
547 | } | |
548 | ||
8faf50e0 XL |
549 | /// A delimited token stream. |
550 | /// | |
551 | /// A `Group` internally contains a `TokenStream` which is surrounded by | |
552 | /// `Delimiter`s. | |
553 | #[derive(Clone)] | |
83c7162d | 554 | pub struct Group { |
13cf67c4 | 555 | inner: imp::Group, |
0531ce1d XL |
556 | } |
557 | ||
8faf50e0 | 558 | /// Describes how a sequence of token trees is delimited. |
0531ce1d XL |
559 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] |
560 | pub enum Delimiter { | |
8faf50e0 | 561 | /// `( ... )` |
0531ce1d | 562 | Parenthesis, |
8faf50e0 | 563 | /// `{ ... }` |
0531ce1d | 564 | Brace, |
8faf50e0 | 565 | /// `[ ... ]` |
0531ce1d | 566 | Bracket, |
8faf50e0 XL |
567 | /// `Ø ... Ø` |
568 | /// | |
569 | /// An implicit delimiter, that may, for example, appear around tokens | |
570 | /// coming from a "macro variable" `$var`. It is important to preserve | |
571 | /// operator priorities in cases like `$var * 3` where `$var` is `1 + 2`. | |
572 | /// Implicit delimiters may not survive roundtrip of a token stream through | |
573 | /// a string. | |
0531ce1d XL |
574 | None, |
575 | } | |
576 | ||
83c7162d | 577 | impl Group { |
13cf67c4 | 578 | fn _new(inner: imp::Group) -> Self { |
dc9dc135 | 579 | Group { inner: inner } |
13cf67c4 XL |
580 | } |
581 | ||
dc9dc135 | 582 | fn _new_stable(inner: fallback::Group) -> Self { |
13cf67c4 XL |
583 | Group { |
584 | inner: inner.into(), | |
585 | } | |
586 | } | |
587 | ||
8faf50e0 XL |
588 | /// Creates a new `Group` with the given delimiter and token stream. |
589 | /// | |
590 | /// This constructor will set the span for this group to | |
591 | /// `Span::call_site()`. To change the span you can use the `set_span` | |
592 | /// method below. | |
83c7162d XL |
593 | pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group { |
594 | Group { | |
13cf67c4 | 595 | inner: imp::Group::new(delimiter, stream.inner), |
83c7162d XL |
596 | } |
597 | } | |
0531ce1d | 598 | |
8faf50e0 | 599 | /// Returns the delimiter of this `Group` |
83c7162d | 600 | pub fn delimiter(&self) -> Delimiter { |
13cf67c4 | 601 | self.inner.delimiter() |
0531ce1d XL |
602 | } |
603 | ||
8faf50e0 XL |
604 | /// Returns the `TokenStream` of tokens that are delimited in this `Group`. |
605 | /// | |
606 | /// Note that the returned token stream does not include the delimiter | |
607 | /// returned above. | |
83c7162d | 608 | pub fn stream(&self) -> TokenStream { |
13cf67c4 | 609 | TokenStream::_new(self.inner.stream()) |
83c7162d XL |
610 | } |
611 | ||
8faf50e0 XL |
612 | /// Returns the span for the delimiters of this token stream, spanning the |
613 | /// entire `Group`. | |
13cf67c4 XL |
614 | /// |
615 | /// ```text | |
616 | /// pub fn span(&self) -> Span { | |
617 | /// ^^^^^^^ | |
618 | /// ``` | |
83c7162d | 619 | pub fn span(&self) -> Span { |
13cf67c4 XL |
620 | Span::_new(self.inner.span()) |
621 | } | |
622 | ||
623 | /// Returns the span pointing to the opening delimiter of this group. | |
624 | /// | |
625 | /// ```text | |
626 | /// pub fn span_open(&self) -> Span { | |
627 | /// ^ | |
628 | /// ``` | |
629 | #[cfg(procmacro2_semver_exempt)] | |
630 | pub fn span_open(&self) -> Span { | |
631 | Span::_new(self.inner.span_open()) | |
632 | } | |
633 | ||
634 | /// Returns the span pointing to the closing delimiter of this group. | |
635 | /// | |
636 | /// ```text | |
637 | /// pub fn span_close(&self) -> Span { | |
638 | /// ^ | |
639 | /// ``` | |
640 | #[cfg(procmacro2_semver_exempt)] | |
641 | pub fn span_close(&self) -> Span { | |
642 | Span::_new(self.inner.span_close()) | |
83c7162d XL |
643 | } |
644 | ||
8faf50e0 XL |
645 | /// Configures the span for this `Group`'s delimiters, but not its internal |
646 | /// tokens. | |
647 | /// | |
648 | /// This method will **not** set the span of all the internal tokens spanned | |
649 | /// by this group, but rather it will only set the span of the delimiter | |
650 | /// tokens at the level of the `Group`. | |
83c7162d | 651 | pub fn set_span(&mut self, span: Span) { |
13cf67c4 | 652 | self.inner.set_span(span.inner) |
0531ce1d XL |
653 | } |
654 | } | |
655 | ||
8faf50e0 XL |
656 | /// Prints the group as a string that should be losslessly convertible back |
657 | /// into the same group (modulo spans), except for possibly `TokenTree::Group`s | |
658 | /// with `Delimiter::None` delimiters. | |
83c7162d | 659 | impl fmt::Display for Group { |
13cf67c4 XL |
660 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
661 | fmt::Display::fmt(&self.inner, formatter) | |
8faf50e0 XL |
662 | } |
663 | } | |
664 | ||
665 | impl fmt::Debug for Group { | |
13cf67c4 XL |
666 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { |
667 | fmt::Debug::fmt(&self.inner, formatter) | |
83c7162d XL |
668 | } |
669 | } | |
670 | ||
8faf50e0 XL |
671 | /// An `Punct` is an single punctuation character like `+`, `-` or `#`. |
672 | /// | |
673 | /// Multicharacter operators like `+=` are represented as two instances of | |
674 | /// `Punct` with different forms of `Spacing` returned. | |
675 | #[derive(Clone)] | |
676 | pub struct Punct { | |
83c7162d XL |
677 | op: char, |
678 | spacing: Spacing, | |
679 | span: Span, | |
680 | } | |
681 | ||
8faf50e0 XL |
682 | /// Whether an `Punct` is followed immediately by another `Punct` or followed by |
683 | /// another token or whitespace. | |
0531ce1d XL |
684 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] |
685 | pub enum Spacing { | |
8faf50e0 | 686 | /// E.g. `+` is `Alone` in `+ =`, `+ident` or `+()`. |
0531ce1d | 687 | Alone, |
8faf50e0 XL |
688 | /// E.g. `+` is `Joint` in `+=` or `'#`. |
689 | /// | |
690 | /// Additionally, single quote `'` can join with identifiers to form | |
691 | /// lifetimes `'ident`. | |
0531ce1d XL |
692 | Joint, |
693 | } | |
694 | ||
8faf50e0 XL |
695 | impl Punct { |
696 | /// Creates a new `Punct` from the given character and spacing. | |
697 | /// | |
698 | /// The `ch` argument must be a valid punctuation character permitted by the | |
699 | /// language, otherwise the function will panic. | |
700 | /// | |
701 | /// The returned `Punct` will have the default span of `Span::call_site()` | |
702 | /// which can be further configured with the `set_span` method below. | |
703 | pub fn new(op: char, spacing: Spacing) -> Punct { | |
704 | Punct { | |
83c7162d XL |
705 | op: op, |
706 | spacing: spacing, | |
707 | span: Span::call_site(), | |
708 | } | |
709 | } | |
710 | ||
8faf50e0 XL |
711 | /// Returns the value of this punctuation character as `char`. |
712 | pub fn as_char(&self) -> char { | |
83c7162d XL |
713 | self.op |
714 | } | |
715 | ||
8faf50e0 XL |
716 | /// Returns the spacing of this punctuation character, indicating whether |
717 | /// it's immediately followed by another `Punct` in the token stream, so | |
718 | /// they can potentially be combined into a multicharacter operator | |
719 | /// (`Joint`), or it's followed by some other token or whitespace (`Alone`) | |
720 | /// so the operator has certainly ended. | |
83c7162d XL |
721 | pub fn spacing(&self) -> Spacing { |
722 | self.spacing | |
723 | } | |
724 | ||
8faf50e0 | 725 | /// Returns the span for this punctuation character. |
83c7162d XL |
726 | pub fn span(&self) -> Span { |
727 | self.span | |
728 | } | |
729 | ||
8faf50e0 | 730 | /// Configure the span for this punctuation character. |
83c7162d XL |
731 | pub fn set_span(&mut self, span: Span) { |
732 | self.span = span; | |
733 | } | |
734 | } | |
735 | ||
8faf50e0 XL |
736 | /// Prints the punctuation character as a string that should be losslessly |
737 | /// convertible back into the same character. | |
738 | impl fmt::Display for Punct { | |
83c7162d XL |
739 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
740 | self.op.fmt(f) | |
741 | } | |
742 | } | |
743 | ||
8faf50e0 XL |
744 | impl fmt::Debug for Punct { |
745 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | |
746 | let mut debug = fmt.debug_struct("Punct"); | |
747 | debug.field("op", &self.op); | |
748 | debug.field("spacing", &self.spacing); | |
dc9dc135 | 749 | imp::debug_span_field_if_nontrivial(&mut debug, self.span.inner); |
8faf50e0 XL |
750 | debug.finish() |
751 | } | |
752 | } | |
753 | ||
754 | /// A word of Rust code, which may be a keyword or legal variable name. | |
755 | /// | |
756 | /// An identifier consists of at least one Unicode code point, the first of | |
757 | /// which has the XID_Start property and the rest of which have the XID_Continue | |
758 | /// property. | |
759 | /// | |
760 | /// - The empty string is not an identifier. Use `Option<Ident>`. | |
761 | /// - A lifetime is not an identifier. Use `syn::Lifetime` instead. | |
762 | /// | |
763 | /// An identifier constructed with `Ident::new` is permitted to be a Rust | |
13cf67c4 XL |
764 | /// keyword, though parsing one through its [`Parse`] implementation rejects |
765 | /// Rust keywords. Use `input.call(Ident::parse_any)` when parsing to match the | |
8faf50e0 XL |
766 | /// behaviour of `Ident::new`. |
767 | /// | |
13cf67c4 | 768 | /// [`Parse`]: https://docs.rs/syn/0.15/syn/parse/trait.Parse.html |
8faf50e0 XL |
769 | /// |
770 | /// # Examples | |
771 | /// | |
772 | /// A new ident can be created from a string using the `Ident::new` function. | |
773 | /// A span must be provided explicitly which governs the name resolution | |
774 | /// behavior of the resulting identifier. | |
775 | /// | |
dc9dc135 | 776 | /// ```edition2018 |
8faf50e0 XL |
777 | /// use proc_macro2::{Ident, Span}; |
778 | /// | |
779 | /// fn main() { | |
780 | /// let call_ident = Ident::new("calligraphy", Span::call_site()); | |
781 | /// | |
782 | /// println!("{}", call_ident); | |
783 | /// } | |
784 | /// ``` | |
785 | /// | |
786 | /// An ident can be interpolated into a token stream using the `quote!` macro. | |
787 | /// | |
dc9dc135 | 788 | /// ```edition2018 |
8faf50e0 | 789 | /// use proc_macro2::{Ident, Span}; |
dc9dc135 | 790 | /// use quote::quote; |
8faf50e0 XL |
791 | /// |
792 | /// fn main() { | |
793 | /// let ident = Ident::new("demo", Span::call_site()); | |
794 | /// | |
795 | /// // Create a variable binding whose name is this ident. | |
796 | /// let expanded = quote! { let #ident = 10; }; | |
797 | /// | |
798 | /// // Create a variable binding with a slightly different name. | |
799 | /// let temp_ident = Ident::new(&format!("new_{}", ident), Span::call_site()); | |
800 | /// let expanded = quote! { let #temp_ident = 10; }; | |
801 | /// } | |
802 | /// ``` | |
803 | /// | |
804 | /// A string representation of the ident is available through the `to_string()` | |
805 | /// method. | |
806 | /// | |
dc9dc135 | 807 | /// ```edition2018 |
8faf50e0 XL |
808 | /// # use proc_macro2::{Ident, Span}; |
809 | /// # | |
810 | /// # let ident = Ident::new("another_identifier", Span::call_site()); | |
811 | /// # | |
812 | /// // Examine the ident as a string. | |
813 | /// let ident_string = ident.to_string(); | |
814 | /// if ident_string.len() > 60 { | |
815 | /// println!("Very long identifier: {}", ident_string) | |
816 | /// } | |
817 | /// ``` | |
818 | #[derive(Clone)] | |
819 | pub struct Ident { | |
820 | inner: imp::Ident, | |
83c7162d XL |
821 | _marker: marker::PhantomData<Rc<()>>, |
822 | } | |
823 | ||
8faf50e0 XL |
824 | impl Ident { |
825 | fn _new(inner: imp::Ident) -> Ident { | |
826 | Ident { | |
83c7162d XL |
827 | inner: inner, |
828 | _marker: marker::PhantomData, | |
829 | } | |
830 | } | |
831 | ||
8faf50e0 XL |
832 | /// Creates a new `Ident` with the given `string` as well as the specified |
833 | /// `span`. | |
834 | /// | |
835 | /// The `string` argument must be a valid identifier permitted by the | |
836 | /// language, otherwise the function will panic. | |
837 | /// | |
838 | /// Note that `span`, currently in rustc, configures the hygiene information | |
839 | /// for this identifier. | |
840 | /// | |
841 | /// As of this time `Span::call_site()` explicitly opts-in to "call-site" | |
842 | /// hygiene meaning that identifiers created with this span will be resolved | |
843 | /// as if they were written directly at the location of the macro call, and | |
844 | /// other code at the macro call site will be able to refer to them as well. | |
845 | /// | |
846 | /// Later spans like `Span::def_site()` will allow to opt-in to | |
847 | /// "definition-site" hygiene meaning that identifiers created with this | |
848 | /// span will be resolved at the location of the macro definition and other | |
849 | /// code at the macro call site will not be able to refer to them. | |
850 | /// | |
851 | /// Due to the current importance of hygiene this constructor, unlike other | |
852 | /// tokens, requires a `Span` to be specified at construction. | |
853 | /// | |
854 | /// # Panics | |
855 | /// | |
856 | /// Panics if the input string is neither a keyword nor a legal variable | |
dc9dc135 XL |
857 | /// name. If you are not sure whether the string contains an identifier and |
858 | /// need to handle an error case, use | |
859 | /// <a href="https://docs.rs/syn/0.15/syn/fn.parse_str.html"><code | |
860 | /// style="padding-right:0;">syn::parse_str</code></a><code | |
861 | /// style="padding-left:0;">::<Ident></code> | |
862 | /// rather than `Ident::new`. | |
8faf50e0 XL |
863 | pub fn new(string: &str, span: Span) -> Ident { |
864 | Ident::_new(imp::Ident::new(string, span.inner)) | |
865 | } | |
866 | ||
867 | /// Same as `Ident::new`, but creates a raw identifier (`r#ident`). | |
868 | /// | |
869 | /// This method is semver exempt and not exposed by default. | |
870 | #[cfg(procmacro2_semver_exempt)] | |
871 | pub fn new_raw(string: &str, span: Span) -> Ident { | |
872 | Ident::_new_raw(string, span) | |
83c7162d XL |
873 | } |
874 | ||
8faf50e0 XL |
875 | fn _new_raw(string: &str, span: Span) -> Ident { |
876 | Ident::_new(imp::Ident::new_raw(string, span.inner)) | |
83c7162d XL |
877 | } |
878 | ||
8faf50e0 | 879 | /// Returns the span of this `Ident`. |
83c7162d XL |
880 | pub fn span(&self) -> Span { |
881 | Span::_new(self.inner.span()) | |
882 | } | |
883 | ||
8faf50e0 XL |
884 | /// Configures the span of this `Ident`, possibly changing its hygiene |
885 | /// context. | |
83c7162d XL |
886 | pub fn set_span(&mut self, span: Span) { |
887 | self.inner.set_span(span.inner); | |
888 | } | |
889 | } | |
890 | ||
8faf50e0 XL |
891 | impl PartialEq for Ident { |
892 | fn eq(&self, other: &Ident) -> bool { | |
13cf67c4 | 893 | self.inner == other.inner |
8faf50e0 XL |
894 | } |
895 | } | |
896 | ||
897 | impl<T> PartialEq<T> for Ident | |
898 | where | |
899 | T: ?Sized + AsRef<str>, | |
900 | { | |
901 | fn eq(&self, other: &T) -> bool { | |
13cf67c4 | 902 | self.inner == other |
8faf50e0 XL |
903 | } |
904 | } | |
905 | ||
906 | impl Eq for Ident {} | |
907 | ||
908 | impl PartialOrd for Ident { | |
909 | fn partial_cmp(&self, other: &Ident) -> Option<Ordering> { | |
910 | Some(self.cmp(other)) | |
911 | } | |
912 | } | |
913 | ||
914 | impl Ord for Ident { | |
915 | fn cmp(&self, other: &Ident) -> Ordering { | |
916 | self.to_string().cmp(&other.to_string()) | |
917 | } | |
918 | } | |
919 | ||
920 | impl Hash for Ident { | |
921 | fn hash<H: Hasher>(&self, hasher: &mut H) { | |
922 | self.to_string().hash(hasher) | |
923 | } | |
924 | } | |
925 | ||
926 | /// Prints the identifier as a string that should be losslessly convertible back | |
927 | /// into the same identifier. | |
928 | impl fmt::Display for Ident { | |
83c7162d | 929 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
8faf50e0 | 930 | self.inner.fmt(f) |
83c7162d XL |
931 | } |
932 | } | |
933 | ||
8faf50e0 | 934 | impl fmt::Debug for Ident { |
83c7162d XL |
935 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
936 | self.inner.fmt(f) | |
937 | } | |
938 | } | |
939 | ||
8faf50e0 XL |
940 | /// A literal string (`"hello"`), byte string (`b"hello"`), character (`'a'`), |
941 | /// byte character (`b'a'`), an integer or floating point number with or without | |
942 | /// a suffix (`1`, `1u8`, `2.3`, `2.3f32`). | |
943 | /// | |
944 | /// Boolean literals like `true` and `false` do not belong here, they are | |
945 | /// `Ident`s. | |
0531ce1d | 946 | #[derive(Clone)] |
83c7162d XL |
947 | pub struct Literal { |
948 | inner: imp::Literal, | |
949 | _marker: marker::PhantomData<Rc<()>>, | |
950 | } | |
0531ce1d | 951 | |
8faf50e0 XL |
952 | macro_rules! suffixed_int_literals { |
953 | ($($name:ident => $kind:ident,)*) => ($( | |
954 | /// Creates a new suffixed integer literal with the specified value. | |
955 | /// | |
956 | /// This function will create an integer like `1u32` where the integer | |
957 | /// value specified is the first part of the token and the integral is | |
958 | /// also suffixed at the end. Literals created from negative numbers may | |
959 | /// not survive rountrips through `TokenStream` or strings and may be | |
960 | /// broken into two tokens (`-` and positive literal). | |
961 | /// | |
962 | /// Literals created through this method have the `Span::call_site()` | |
963 | /// span by default, which can be configured with the `set_span` method | |
964 | /// below. | |
965 | pub fn $name(n: $kind) -> Literal { | |
966 | Literal::_new(imp::Literal::$name(n)) | |
967 | } | |
968 | )*) | |
969 | } | |
970 | ||
971 | macro_rules! unsuffixed_int_literals { | |
83c7162d | 972 | ($($name:ident => $kind:ident,)*) => ($( |
8faf50e0 XL |
973 | /// Creates a new unsuffixed integer literal with the specified value. |
974 | /// | |
975 | /// This function will create an integer like `1` where the integer | |
976 | /// value specified is the first part of the token. No suffix is | |
977 | /// specified on this token, meaning that invocations like | |
978 | /// `Literal::i8_unsuffixed(1)` are equivalent to | |
979 | /// `Literal::u32_unsuffixed(1)`. Literals created from negative numbers | |
980 | /// may not survive rountrips through `TokenStream` or strings and may | |
981 | /// be broken into two tokens (`-` and positive literal). | |
982 | /// | |
983 | /// Literals created through this method have the `Span::call_site()` | |
984 | /// span by default, which can be configured with the `set_span` method | |
985 | /// below. | |
83c7162d XL |
986 | pub fn $name(n: $kind) -> Literal { |
987 | Literal::_new(imp::Literal::$name(n)) | |
0531ce1d XL |
988 | } |
989 | )*) | |
990 | } | |
991 | ||
992 | impl Literal { | |
83c7162d XL |
993 | fn _new(inner: imp::Literal) -> Literal { |
994 | Literal { | |
995 | inner: inner, | |
996 | _marker: marker::PhantomData, | |
997 | } | |
0531ce1d XL |
998 | } |
999 | ||
dc9dc135 | 1000 | fn _new_stable(inner: fallback::Literal) -> Literal { |
8faf50e0 XL |
1001 | Literal { |
1002 | inner: inner.into(), | |
1003 | _marker: marker::PhantomData, | |
1004 | } | |
1005 | } | |
1006 | ||
1007 | suffixed_int_literals! { | |
83c7162d XL |
1008 | u8_suffixed => u8, |
1009 | u16_suffixed => u16, | |
1010 | u32_suffixed => u32, | |
1011 | u64_suffixed => u64, | |
1012 | usize_suffixed => usize, | |
1013 | i8_suffixed => i8, | |
1014 | i16_suffixed => i16, | |
1015 | i32_suffixed => i32, | |
1016 | i64_suffixed => i64, | |
1017 | isize_suffixed => isize, | |
8faf50e0 | 1018 | } |
83c7162d | 1019 | |
13cf67c4 XL |
1020 | #[cfg(u128)] |
1021 | suffixed_int_literals! { | |
1022 | u128_suffixed => u128, | |
1023 | i128_suffixed => i128, | |
1024 | } | |
1025 | ||
8faf50e0 | 1026 | unsuffixed_int_literals! { |
83c7162d XL |
1027 | u8_unsuffixed => u8, |
1028 | u16_unsuffixed => u16, | |
1029 | u32_unsuffixed => u32, | |
1030 | u64_unsuffixed => u64, | |
1031 | usize_unsuffixed => usize, | |
1032 | i8_unsuffixed => i8, | |
1033 | i16_unsuffixed => i16, | |
1034 | i32_unsuffixed => i32, | |
1035 | i64_unsuffixed => i64, | |
1036 | isize_unsuffixed => isize, | |
1037 | } | |
1038 | ||
13cf67c4 XL |
1039 | #[cfg(u128)] |
1040 | unsuffixed_int_literals! { | |
1041 | u128_unsuffixed => u128, | |
1042 | i128_unsuffixed => i128, | |
1043 | } | |
1044 | ||
83c7162d XL |
1045 | pub fn f64_unsuffixed(f: f64) -> Literal { |
1046 | assert!(f.is_finite()); | |
1047 | Literal::_new(imp::Literal::f64_unsuffixed(f)) | |
0531ce1d XL |
1048 | } |
1049 | ||
83c7162d XL |
1050 | pub fn f64_suffixed(f: f64) -> Literal { |
1051 | assert!(f.is_finite()); | |
1052 | Literal::_new(imp::Literal::f64_suffixed(f)) | |
0531ce1d XL |
1053 | } |
1054 | ||
8faf50e0 XL |
1055 | /// Creates a new unsuffixed floating-point literal. |
1056 | /// | |
1057 | /// This constructor is similar to those like `Literal::i8_unsuffixed` where | |
1058 | /// the float's value is emitted directly into the token but no suffix is | |
1059 | /// used, so it may be inferred to be a `f64` later in the compiler. | |
1060 | /// Literals created from negative numbers may not survive rountrips through | |
1061 | /// `TokenStream` or strings and may be broken into two tokens (`-` and | |
1062 | /// positive literal). | |
1063 | /// | |
1064 | /// # Panics | |
1065 | /// | |
1066 | /// This function requires that the specified float is finite, for example | |
1067 | /// if it is infinity or NaN this function will panic. | |
83c7162d XL |
1068 | pub fn f32_unsuffixed(f: f32) -> Literal { |
1069 | assert!(f.is_finite()); | |
1070 | Literal::_new(imp::Literal::f32_unsuffixed(f)) | |
0531ce1d XL |
1071 | } |
1072 | ||
83c7162d XL |
1073 | pub fn f32_suffixed(f: f32) -> Literal { |
1074 | assert!(f.is_finite()); | |
1075 | Literal::_new(imp::Literal::f32_suffixed(f)) | |
0531ce1d XL |
1076 | } |
1077 | ||
1078 | pub fn string(string: &str) -> Literal { | |
83c7162d | 1079 | Literal::_new(imp::Literal::string(string)) |
0531ce1d XL |
1080 | } |
1081 | ||
1082 | pub fn character(ch: char) -> Literal { | |
83c7162d | 1083 | Literal::_new(imp::Literal::character(ch)) |
0531ce1d XL |
1084 | } |
1085 | ||
1086 | pub fn byte_string(s: &[u8]) -> Literal { | |
83c7162d | 1087 | Literal::_new(imp::Literal::byte_string(s)) |
0531ce1d XL |
1088 | } |
1089 | ||
83c7162d XL |
1090 | pub fn span(&self) -> Span { |
1091 | Span::_new(self.inner.span()) | |
0531ce1d XL |
1092 | } |
1093 | ||
83c7162d XL |
1094 | pub fn set_span(&mut self, span: Span) { |
1095 | self.inner.set_span(span.inner); | |
0531ce1d | 1096 | } |
83c7162d | 1097 | } |
0531ce1d | 1098 | |
83c7162d XL |
1099 | impl fmt::Debug for Literal { |
1100 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
1101 | self.inner.fmt(f) | |
0531ce1d | 1102 | } |
83c7162d | 1103 | } |
0531ce1d | 1104 | |
83c7162d XL |
1105 | impl fmt::Display for Literal { |
1106 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
1107 | self.inner.fmt(f) | |
0531ce1d XL |
1108 | } |
1109 | } | |
1110 | ||
8faf50e0 | 1111 | /// Public implementation details for the `TokenStream` type, such as iterators. |
83c7162d XL |
1112 | pub mod token_stream { |
1113 | use std::fmt; | |
1114 | use std::marker; | |
1115 | use std::rc::Rc; | |
0531ce1d | 1116 | |
8faf50e0 | 1117 | use imp; |
83c7162d XL |
1118 | pub use TokenStream; |
1119 | use TokenTree; | |
0531ce1d | 1120 | |
8faf50e0 XL |
1121 | /// An iterator over `TokenStream`'s `TokenTree`s. |
1122 | /// | |
1123 | /// The iteration is "shallow", e.g. the iterator doesn't recurse into | |
1124 | /// delimited groups, and returns whole groups as token trees. | |
dc9dc135 | 1125 | #[derive(Clone)] |
83c7162d XL |
1126 | pub struct IntoIter { |
1127 | inner: imp::TokenTreeIter, | |
1128 | _marker: marker::PhantomData<Rc<()>>, | |
0531ce1d | 1129 | } |
0531ce1d | 1130 | |
83c7162d XL |
1131 | impl Iterator for IntoIter { |
1132 | type Item = TokenTree; | |
1133 | ||
1134 | fn next(&mut self) -> Option<TokenTree> { | |
1135 | self.inner.next() | |
1136 | } | |
1137 | } | |
1138 | ||
1139 | impl fmt::Debug for IntoIter { | |
1140 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
1141 | self.inner.fmt(f) | |
1142 | } | |
1143 | } | |
1144 | ||
1145 | impl IntoIterator for TokenStream { | |
1146 | type Item = TokenTree; | |
1147 | type IntoIter = IntoIter; | |
1148 | ||
1149 | fn into_iter(self) -> IntoIter { | |
1150 | IntoIter { | |
1151 | inner: self.inner.into_iter(), | |
1152 | _marker: marker::PhantomData, | |
1153 | } | |
1154 | } | |
1155 | } | |
1156 | } |