1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! A support library for macro authors when defining new macros.
13 //! This library, provided by the standard distribution, provides the types
14 //! consumed in the interfaces of procedurally defined macro definitions such as
15 //! function-like macros `#[proc_macro]`, macro attribures `#[proc_macro_attribute]` and
16 //! custom derive attributes`#[proc_macro_derive]`.
18 //! Note that this crate is intentionally bare-bones currently.
19 //! This functionality is intended to be expanded over time as more surface
20 //! area for macro authors is stabilized.
22 //! See [the book](../book/first-edition/procedural-macros.html) for more.
24 #![stable(feature = "proc_macro_lib", since = "1.15.0")]
25 #![deny(missing_docs)]
26 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
27 html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
28 html_root_url = "https://doc.rust-lang.org/nightly/",
29 html_playground_url = "https://play.rust-lang.org/",
30 issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
31 test(no_crate_inject, attr(deny(warnings))),
32 test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]
34 #![feature(rustc_private)]
35 #![feature(staged_api)]
36 #![feature(lang_items)]
37 #![feature(optin_builtin_traits)]
39 #![recursion_limit="256"]
42 extern crate syntax_pos;
43 extern crate rustc_errors;
44 extern crate rustc_data_structures;
46 #[unstable(feature = "proc_macro_internals", issue = "27812")]
52 #[unstable(feature = "proc_macro_diagnostic", issue = "38356")]
53 pub use diagnostic::{Diagnostic, Level};
55 use std::{ascii, fmt, iter};
56 use std::path::PathBuf;
57 use rustc_data_structures::sync::Lrc;
58 use std::str::FromStr;
60 use syntax::errors::DiagnosticBuilder;
61 use syntax::parse::{self, token};
62 use syntax::symbol::Symbol;
63 use syntax::tokenstream;
64 use syntax_pos::{FileMap, Pos, FileName};
66 /// The main type provided by this crate, representing an abstract stream of
67 /// tokens, or, more specifically, a sequence of token trees.
68 /// The type provide interfaces for iterating over those token trees and, conversely,
69 /// collecting a number of token trees into one stream.
71 /// This is both the input and output of `#[proc_macro]`, `#[proc_macro_attribute]`
72 /// and `#[proc_macro_derive]` definitions.
74 /// The API of this type is intentionally bare-bones, but it'll be expanded over
76 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
78 pub struct TokenStream(tokenstream::TokenStream);
80 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
81 impl !Send for TokenStream {}
82 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
83 impl !Sync for TokenStream {}
85 /// Error returned from `TokenStream::from_str`.
86 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
92 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
93 impl !Send for LexError {}
94 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
95 impl !Sync for LexError {}
98 /// Returns an empty `TokenStream` containing no token trees.
99 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
100 pub fn new() -> TokenStream {
101 TokenStream(tokenstream::TokenStream::empty())
104 /// Checks if this `TokenStream` is empty.
105 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
106 pub fn is_empty(&self) -> bool {
111 /// Attempts to break the string into tokens and parse those tokens into a token stream.
112 /// May fail for a number of reasons, for example, if the string contains unbalanced delimiters
113 /// or characters not existing in the language.
114 /// All tokens in the parsed stream get `Span::call_site()` spans.
116 /// NOTE: Some errors may cause panics instead of returning `LexError`. We reserve the right to
117 /// change these errors into `LexError`s later.
118 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
119 impl FromStr for TokenStream {
122 fn from_str(src: &str) -> Result<TokenStream, LexError> {
123 __internal::with_sess(|sess, data| {
124 Ok(__internal::token_stream_wrap(parse::parse_stream_from_source_str(
125 FileName::ProcMacroSourceCode, src.to_string(), sess, Some(data.call_site.0)
131 /// Prints the token stream as a string that is supposed to be losslessly convertible back
132 /// into the same token stream (modulo spans), except for possibly `TokenTree::Group`s
133 /// with `Delimiter::None` delimiters and negative numeric literals.
134 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
135 impl fmt::Display for TokenStream {
136 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
141 /// Prints token in a form convenient for debugging.
142 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
143 impl fmt::Debug for TokenStream {
144 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
145 f.write_str("TokenStream ")?;
146 f.debug_list().entries(self.clone()).finish()
150 #[unstable(feature = "proc_macro_quote", issue = "38356")]
151 pub use quote::{quote, quote_span};
153 /// Creates a token stream containing a single token tree.
154 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
155 impl From<TokenTree> for TokenStream {
156 fn from(tree: TokenTree) -> TokenStream {
157 TokenStream(tree.to_internal())
161 /// Collects a number of token trees into a single stream.
162 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
163 impl iter::FromIterator<TokenTree> for TokenStream {
164 fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
165 trees.into_iter().map(TokenStream::from).collect()
169 /// A "flattening" operation on token streams, collects token trees
170 /// from multiple token streams into a single stream.
171 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
172 impl iter::FromIterator<TokenStream> for TokenStream {
173 fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
174 let mut builder = tokenstream::TokenStreamBuilder::new();
175 for stream in streams {
176 builder.push(stream.0);
178 TokenStream(builder.build())
182 /// Public implementation details for the `TokenStream` type, such as iterators.
183 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
184 pub mod token_stream {
185 use syntax::tokenstream;
186 use {TokenTree, TokenStream, Delimiter};
188 /// An iterator over `TokenStream`'s `TokenTree`s.
189 /// The iteration is "shallow", e.g. the iterator doesn't recurse into delimited groups,
190 /// and returns whole groups as token trees.
192 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
193 pub struct IntoIter {
194 cursor: tokenstream::Cursor,
195 stack: Vec<TokenTree>,
198 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
199 impl Iterator for IntoIter {
200 type Item = TokenTree;
202 fn next(&mut self) -> Option<TokenTree> {
204 let tree = self.stack.pop().or_else(|| {
205 let next = self.cursor.next_as_stream()?;
206 Some(TokenTree::from_internal(next, &mut self.stack))
208 // HACK: The condition "dummy span + group with empty delimiter" represents an AST
209 // fragment approximately converted into a token stream. This may happen, for
210 // example, with inputs to proc macro attributes, including derives. Such "groups"
211 // need to flattened during iteration over stream's token trees.
212 // Eventually this needs to be removed in favor of keeping original token trees
213 // and not doing the roundtrip through AST.
214 if tree.span().0.is_dummy() {
215 if let TokenTree::Group(ref group) = tree {
216 if group.delimiter() == Delimiter::None {
217 self.cursor.insert(group.stream.clone().0);
227 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
228 impl IntoIterator for TokenStream {
229 type Item = TokenTree;
230 type IntoIter = IntoIter;
232 fn into_iter(self) -> IntoIter {
233 IntoIter { cursor: self.0.trees(), stack: Vec::new() }
238 /// `quote!(..)` accepts arbitrary tokens and expands into a `TokenStream` describing the input.
239 /// For example, `quote!(a + b)` will produce a expression, that, when evaluated, constructs
240 /// the `TokenStream` `[Ident("a"), Punct('+', Alone), Ident("b")]`.
242 /// Unquoting is done with `$`, and works by taking the single next ident as the unquoted term.
243 /// To quote `$` itself, use `$$`.
245 /// This is a dummy macro, the actual implementation is in `quote::quote`.`
246 #[unstable(feature = "proc_macro_quote", issue = "38356")]
248 macro_rules! quote { () => {} }
250 #[unstable(feature = "proc_macro_internals", issue = "27812")]
254 /// A region of source code, along with macro expansion information.
255 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
256 #[derive(Copy, Clone)]
257 pub struct Span(syntax_pos::Span);
259 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
260 impl !Send for Span {}
261 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
262 impl !Sync for Span {}
264 macro_rules! diagnostic_method {
265 ($name:ident, $level:expr) => (
266 /// Create a new `Diagnostic` with the given `message` at the span
268 #[unstable(feature = "proc_macro_diagnostic", issue = "38356")]
269 pub fn $name<T: Into<String>>(self, message: T) -> Diagnostic {
270 Diagnostic::spanned(self, $level, message)
276 /// A span that resolves at the macro definition site.
277 #[unstable(feature = "proc_macro_span", issue = "38356")]
278 pub fn def_site() -> Span {
279 ::__internal::with_sess(|_, data| data.def_site)
282 /// The span of the invocation of the current procedural macro.
283 /// Identifiers created with this span will be resolved as if they were written
284 /// directly at the macro call location (call-site hygiene) and other code
285 /// at the macro call site will be able to refer to them as well.
286 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
287 pub fn call_site() -> Span {
288 ::__internal::with_sess(|_, data| data.call_site)
291 /// The original source file into which this span points.
292 #[unstable(feature = "proc_macro_span", issue = "38356")]
293 pub fn source_file(&self) -> SourceFile {
295 filemap: __internal::lookup_char_pos(self.0.lo()).file,
299 /// The `Span` for the tokens in the previous macro expansion from which
300 /// `self` was generated from, if any.
301 #[unstable(feature = "proc_macro_span", issue = "38356")]
302 pub fn parent(&self) -> Option<Span> {
303 self.0.parent().map(Span)
306 /// The span for the origin source code that `self` was generated from. If
307 /// this `Span` wasn't generated from other macro expansions then the return
308 /// value is the same as `*self`.
309 #[unstable(feature = "proc_macro_span", issue = "38356")]
310 pub fn source(&self) -> Span {
311 Span(self.0.source_callsite())
314 /// Get the starting line/column in the source file for this span.
315 #[unstable(feature = "proc_macro_span", issue = "38356")]
316 pub fn start(&self) -> LineColumn {
317 let loc = __internal::lookup_char_pos(self.0.lo());
320 column: loc.col.to_usize()
324 /// Get the ending line/column in the source file for this span.
325 #[unstable(feature = "proc_macro_span", issue = "38356")]
326 pub fn end(&self) -> LineColumn {
327 let loc = __internal::lookup_char_pos(self.0.hi());
330 column: loc.col.to_usize()
334 /// Create a new span encompassing `self` and `other`.
336 /// Returns `None` if `self` and `other` are from different files.
337 #[unstable(feature = "proc_macro_span", issue = "38356")]
338 pub fn join(&self, other: Span) -> Option<Span> {
339 let self_loc = __internal::lookup_char_pos(self.0.lo());
340 let other_loc = __internal::lookup_char_pos(other.0.lo());
342 if self_loc.file.name != other_loc.file.name { return None }
344 Some(Span(self.0.to(other.0)))
347 /// Creates a new span with the same line/column information as `self` but
348 /// that resolves symbols as though it were at `other`.
349 #[unstable(feature = "proc_macro_span", issue = "38356")]
350 pub fn resolved_at(&self, other: Span) -> Span {
351 Span(self.0.with_ctxt(other.0.ctxt()))
354 /// Creates a new span with the same name resolution behavior as `self` but
355 /// with the line/column information of `other`.
356 #[unstable(feature = "proc_macro_span", issue = "38356")]
357 pub fn located_at(&self, other: Span) -> Span {
358 other.resolved_at(*self)
361 /// Compares to spans to see if they're equal.
362 #[unstable(feature = "proc_macro_span", issue = "38356")]
363 pub fn eq(&self, other: &Span) -> bool {
367 diagnostic_method!(error, Level::Error);
368 diagnostic_method!(warning, Level::Warning);
369 diagnostic_method!(note, Level::Note);
370 diagnostic_method!(help, Level::Help);
373 /// Prints a span in a form convenient for debugging.
374 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
375 impl fmt::Debug for Span {
376 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
377 write!(f, "{:?} bytes({}..{})",
384 /// A line-column pair representing the start or end of a `Span`.
385 #[unstable(feature = "proc_macro_span", issue = "38356")]
386 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
387 pub struct LineColumn {
388 /// The 1-indexed line in the source file on which the span starts or ends (inclusive).
389 #[unstable(feature = "proc_macro_span", issue = "38356")]
391 /// The 0-indexed column (in UTF-8 characters) in the source file on which
392 /// the span starts or ends (inclusive).
393 #[unstable(feature = "proc_macro_span", issue = "38356")]
397 #[unstable(feature = "proc_macro_span", issue = "38356")]
398 impl !Send for LineColumn {}
399 #[unstable(feature = "proc_macro_span", issue = "38356")]
400 impl !Sync for LineColumn {}
402 /// The source file of a given `Span`.
403 #[unstable(feature = "proc_macro_span", issue = "38356")]
405 pub struct SourceFile {
406 filemap: Lrc<FileMap>,
409 #[unstable(feature = "proc_macro_span", issue = "38356")]
410 impl !Send for SourceFile {}
411 #[unstable(feature = "proc_macro_span", issue = "38356")]
412 impl !Sync for SourceFile {}
415 /// Get the path to this source file.
418 /// If the code span associated with this `SourceFile` was generated by an external macro, this
419 /// may not be an actual path on the filesystem. Use [`is_real`] to check.
421 /// Also note that even if `is_real` returns `true`, if `--remap-path-prefix` was passed on
422 /// the command line, the path as given may not actually be valid.
424 /// [`is_real`]: #method.is_real
425 #[unstable(feature = "proc_macro_span", issue = "38356")]
426 pub fn path(&self) -> PathBuf {
427 match self.filemap.name {
428 FileName::Real(ref path) => path.clone(),
429 _ => PathBuf::from(self.filemap.name.to_string())
433 /// Returns `true` if this source file is a real source file, and not generated by an external
434 /// macro's expansion.
435 #[unstable(feature = "proc_macro_span", issue = "38356")]
436 pub fn is_real(&self) -> bool {
437 // This is a hack until intercrate spans are implemented and we can have real source files
438 // for spans generated in external macros.
439 // https://github.com/rust-lang/rust/pull/43604#issuecomment-333334368
440 self.filemap.is_real_file()
445 #[unstable(feature = "proc_macro_span", issue = "38356")]
446 impl fmt::Debug for SourceFile {
447 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
448 f.debug_struct("SourceFile")
449 .field("path", &self.path())
450 .field("is_real", &self.is_real())
455 #[unstable(feature = "proc_macro_span", issue = "38356")]
456 impl PartialEq for SourceFile {
457 fn eq(&self, other: &Self) -> bool {
458 Lrc::ptr_eq(&self.filemap, &other.filemap)
462 #[unstable(feature = "proc_macro_span", issue = "38356")]
463 impl Eq for SourceFile {}
465 /// A single token or a delimited sequence of token trees (e.g. `[1, (), ..]`).
466 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
469 /// A token stream surrounded by bracket delimiters.
470 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
472 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
476 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
478 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
481 /// A single punctuation character (`+`, `,`, `$`, etc.).
482 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
484 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
487 /// A literal character (`'a'`), string (`"hello"`), number (`2.3`), etc.
488 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
490 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
495 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
496 impl !Send for TokenTree {}
497 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
498 impl !Sync for TokenTree {}
501 /// Returns the span of this tree, delegating to the `span` method of
502 /// the contained token or a delimited stream.
503 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
504 pub fn span(&self) -> Span {
506 TokenTree::Group(ref t) => t.span(),
507 TokenTree::Ident(ref t) => t.span(),
508 TokenTree::Punct(ref t) => t.span(),
509 TokenTree::Literal(ref t) => t.span(),
513 /// Configures the span for *only this token*.
515 /// Note that if this token is a `Group` then this method will not configure
516 /// the span of each of the internal tokens, this will simply delegate to
517 /// the `set_span` method of each variant.
518 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
519 pub fn set_span(&mut self, span: Span) {
521 TokenTree::Group(ref mut t) => t.set_span(span),
522 TokenTree::Ident(ref mut t) => t.set_span(span),
523 TokenTree::Punct(ref mut t) => t.set_span(span),
524 TokenTree::Literal(ref mut t) => t.set_span(span),
529 /// Prints token treee in a form convenient for debugging.
530 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
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
536 TokenTree::Group(ref tt) => tt.fmt(f),
537 TokenTree::Ident(ref tt) => tt.fmt(f),
538 TokenTree::Punct(ref tt) => tt.fmt(f),
539 TokenTree::Literal(ref tt) => tt.fmt(f),
544 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
545 impl From<Group> for TokenTree {
546 fn from(g: Group) -> TokenTree {
551 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
552 impl From<Ident> for TokenTree {
553 fn from(g: Ident) -> TokenTree {
558 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
559 impl From<Punct> for TokenTree {
560 fn from(g: Punct) -> TokenTree {
565 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
566 impl From<Literal> for TokenTree {
567 fn from(g: Literal) -> TokenTree {
568 TokenTree::Literal(g)
572 /// Prints the token tree as a string that is supposed to be losslessly convertible back
573 /// into the same token tree (modulo spans), except for possibly `TokenTree::Group`s
574 /// with `Delimiter::None` delimiters and negative numeric literals.
575 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
576 impl fmt::Display for TokenTree {
577 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
579 TokenTree::Group(ref t) => t.fmt(f),
580 TokenTree::Ident(ref t) => t.fmt(f),
581 TokenTree::Punct(ref t) => t.fmt(f),
582 TokenTree::Literal(ref t) => t.fmt(f),
587 /// A delimited token stream.
589 /// A `Group` internally contains a `TokenStream` which is surrounded by `Delimiter`s.
591 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
593 delimiter: Delimiter,
598 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
599 impl !Send for Group {}
600 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
601 impl !Sync for Group {}
603 /// Describes how a sequence of token trees is delimited.
604 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
605 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
608 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
611 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
614 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
617 /// An implicit delimiter, that may, for example, appear around tokens coming from a
618 /// "macro variable" `$var`. It is important to preserve operator priorities in cases like
619 /// `$var * 3` where `$var` is `1 + 2`.
620 /// Implicit delimiters may not survive roundtrip of a token stream through a string.
621 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
626 /// Creates a new `Group` with the given delimiter and token stream.
628 /// This constructor will set the span for this group to
629 /// `Span::call_site()`. To change the span you can use the `set_span`
631 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
632 pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
634 delimiter: delimiter,
636 span: Span::call_site(),
640 /// Returns the delimiter of this `Group`
641 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
642 pub fn delimiter(&self) -> Delimiter {
646 /// Returns the `TokenStream` of tokens that are delimited in this `Group`.
648 /// Note that the returned token stream does not include the delimiter
650 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
651 pub fn stream(&self) -> TokenStream {
655 /// Returns the span for the delimiters of this token stream, spanning the
657 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
658 pub fn span(&self) -> Span {
662 /// Configures the span for this `Group`'s delimiters, but not its internal
665 /// This method will **not** set the span of all the internal tokens spanned
666 /// by this group, but rather it will only set the span of the delimiter
667 /// tokens at the level of the `Group`.
668 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
669 pub fn set_span(&mut self, span: Span) {
674 /// Prints the group as a string that should be losslessly convertible back
675 /// into the same group (modulo spans), except for possibly `TokenTree::Group`s
676 /// with `Delimiter::None` delimiters.
677 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
678 impl fmt::Display for Group {
679 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
680 TokenStream::from(TokenTree::from(self.clone())).fmt(f)
684 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
685 impl fmt::Debug for Group {
686 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
687 f.debug_struct("Group")
688 .field("delimiter", &self.delimiter())
689 .field("stream", &self.stream())
690 .field("span", &self.span())
695 /// An `Punct` is an single punctuation character like `+`, `-` or `#`.
697 /// Multicharacter operators like `+=` are represented as two instances of `Punct` with different
698 /// forms of `Spacing` returned.
699 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
707 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
708 impl !Send for Punct {}
709 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
710 impl !Sync for Punct {}
712 /// Whether an `Punct` is followed immediately by another `Punct` or
713 /// followed by another token or whitespace.
714 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
715 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
717 /// E.g. `+` is `Alone` in `+ =`, `+ident` or `+()`.
718 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
720 /// E.g. `+` is `Joint` in `+=` or `'#`.
721 /// Additionally, single quote `'` can join with identifiers to form lifetimes `'ident`.
722 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
727 /// Creates a new `Punct` from the given character and spacing.
728 /// The `ch` argument must be a valid punctuation character permitted by the language,
729 /// otherwise the function will panic.
731 /// The returned `Punct` will have the default span of `Span::call_site()`
732 /// which can be further configured with the `set_span` method below.
733 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
734 pub fn new(ch: char, spacing: Spacing) -> Punct {
735 const LEGAL_CHARS: &[char] = &['=', '<', '>', '!', '~', '+', '-', '*', '/', '%', '^',
736 '&', '|', '@', '.', ',', ';', ':', '#', '$', '?', '\''];
737 if !LEGAL_CHARS.contains(&ch) {
738 panic!("unsupported character `{:?}`", ch)
743 span: Span::call_site(),
747 /// Returns the value of this punctuation character as `char`.
748 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
749 pub fn as_char(&self) -> char {
753 /// Returns the spacing of this punctuation character, indicating whether it's immediately
754 /// followed by another `Punct` in the token stream, so they can potentially be combined into
755 /// a multicharacter operator (`Joint`), or it's followed by some other token or whitespace
756 /// (`Alone`) so the operator has certainly ended.
757 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
758 pub fn spacing(&self) -> Spacing {
762 /// Returns the span for this punctuation character.
763 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
764 pub fn span(&self) -> Span {
768 /// Configure the span for this punctuation character.
769 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
770 pub fn set_span(&mut self, span: Span) {
775 /// Prints the punctuation character as a string that should be losslessly convertible
776 /// back into the same character.
777 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
778 impl fmt::Display for Punct {
779 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
780 TokenStream::from(TokenTree::from(self.clone())).fmt(f)
784 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
785 impl fmt::Debug for Punct {
786 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
787 f.debug_struct("Punct")
788 .field("ch", &self.as_char())
789 .field("spacing", &self.spacing())
790 .field("span", &self.span())
795 /// An identifier (`ident`).
797 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
804 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
805 impl !Send for Ident {}
806 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
807 impl !Sync for Ident {}
810 fn is_valid(string: &str) -> bool {
811 let mut chars = string.chars();
812 if let Some(start) = chars.next() {
813 (start == '_' || start.is_xid_start())
814 && chars.all(|cont| cont == '_' || cont.is_xid_continue())
820 /// Creates a new `Ident` with the given `string` as well as the specified
822 /// The `string` argument must be a valid identifier permitted by the
823 /// language, otherwise the function will panic.
825 /// Note that `span`, currently in rustc, configures the hygiene information
826 /// for this identifier.
828 /// As of this time `Span::call_site()` explicitly opts-in to "call-site" hygiene
829 /// meaning that identifiers created with this span will be resolved as if they were written
830 /// directly at the location of the macro call, and other code at the macro call site will be
831 /// able to refer to them as well.
833 /// Later spans like `Span::def_site()` will allow to opt-in to "definition-site" hygiene
834 /// meaning that identifiers created with this span will be resolved at the location of the
835 /// macro definition and other code at the macro call site will not be able to refer to them.
837 /// Due to the current importance of hygiene this constructor, unlike other
838 /// tokens, requires a `Span` to be specified at construction.
839 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
840 pub fn new(string: &str, span: Span) -> Ident {
841 if !Ident::is_valid(string) {
842 panic!("`{:?}` is not a valid identifier", string)
844 Ident::new_maybe_raw(string, span, false)
847 /// Same as `Ident::new`, but creates a raw identifier (`r#ident`).
848 #[unstable(feature = "proc_macro_raw_ident", issue = "38356")]
849 pub fn new_raw(string: &str, span: Span) -> Ident {
850 if !Ident::is_valid(string) {
851 panic!("`{:?}` is not a valid identifier", string)
853 Ident::new_maybe_raw(string, span, true)
856 /// Returns the span of this `Ident`, encompassing the entire string returned
858 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
859 pub fn span(&self) -> Span {
863 /// Configures the span of this `Ident`, possibly changing its hygiene context.
864 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
865 pub fn set_span(&mut self, span: Span) {
870 /// Prints the identifier as a string that should be losslessly convertible
871 /// back into the same identifier.
872 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
873 impl fmt::Display for Ident {
874 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
875 TokenStream::from(TokenTree::from(self.clone())).fmt(f)
879 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
880 impl fmt::Debug for Ident {
881 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
882 f.debug_struct("Ident")
883 .field("ident", &self.to_string())
884 .field("span", &self.span())
889 /// A literal string (`"hello"`), byte string (`b"hello"`),
890 /// character (`'a'`), byte character (`b'a'`), an integer or floating point number
891 /// with or without a suffix (`1`, `1u8`, `2.3`, `2.3f32`).
892 /// Boolean literals like `true` and `false` do not belong here, they are `Ident`s.
893 // FIXME(eddyb) `Literal` should not expose internal `Debug` impls.
894 #[derive(Clone, Debug)]
895 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
898 suffix: Option<Symbol>,
902 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
903 impl !Send for Literal {}
904 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
905 impl !Sync for Literal {}
907 macro_rules! suffixed_int_literals {
908 ($($name:ident => $kind:ident,)*) => ($(
909 /// Creates a new suffixed integer literal with the specified value.
911 /// This function will create an integer like `1u32` where the integer
912 /// value specified is the first part of the token and the integral is
913 /// also suffixed at the end.
914 /// Literals created from negative numbers may not survive rountrips through
915 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
917 /// Literals created through this method have the `Span::call_site()`
918 /// span by default, which can be configured with the `set_span` method
920 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
921 pub fn $name(n: $kind) -> Literal {
923 lit: token::Lit::Integer(Symbol::intern(&n.to_string())),
924 suffix: Some(Symbol::intern(stringify!($kind))),
925 span: Span::call_site(),
931 macro_rules! unsuffixed_int_literals {
932 ($($name:ident => $kind:ident,)*) => ($(
933 /// Creates a new unsuffixed integer literal with the specified value.
935 /// This function will create an integer like `1` where the integer
936 /// value specified is the first part of the token. No suffix is
937 /// specified on this token, meaning that invocations like
938 /// `Literal::i8_unsuffixed(1)` are equivalent to
939 /// `Literal::u32_unsuffixed(1)`.
940 /// Literals created from negative numbers may not survive rountrips through
941 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
943 /// Literals created through this method have the `Span::call_site()`
944 /// span by default, which can be configured with the `set_span` method
946 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
947 pub fn $name(n: $kind) -> Literal {
949 lit: token::Lit::Integer(Symbol::intern(&n.to_string())),
951 span: Span::call_site(),
958 suffixed_int_literals! {
963 u128_suffixed => u128,
964 usize_suffixed => usize,
969 i128_suffixed => i128,
970 isize_suffixed => isize,
973 unsuffixed_int_literals! {
975 u16_unsuffixed => u16,
976 u32_unsuffixed => u32,
977 u64_unsuffixed => u64,
978 u128_unsuffixed => u128,
979 usize_unsuffixed => usize,
981 i16_unsuffixed => i16,
982 i32_unsuffixed => i32,
983 i64_unsuffixed => i64,
984 i128_unsuffixed => i128,
985 isize_unsuffixed => isize,
988 /// Creates a new unsuffixed floating-point literal.
990 /// This constructor is similar to those like `Literal::i8_unsuffixed` where
991 /// the float's value is emitted directly into the token but no suffix is
992 /// used, so it may be inferred to be a `f64` later in the compiler.
993 /// Literals created from negative numbers may not survive rountrips through
994 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
998 /// This function requires that the specified float is finite, for
999 /// example if it is infinity or NaN this function will panic.
1000 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1001 pub fn f32_unsuffixed(n: f32) -> Literal {
1003 panic!("Invalid float literal {}", n);
1006 lit: token::Lit::Float(Symbol::intern(&n.to_string())),
1008 span: Span::call_site(),
1012 /// Creates a new suffixed floating-point literal.
1014 /// This consturctor will create a literal like `1.0f32` where the value
1015 /// specified is the preceding part of the token and `f32` is the suffix of
1016 /// the token. This token will always be inferred to be an `f32` in the
1018 /// Literals created from negative numbers may not survive rountrips through
1019 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
1023 /// This function requires that the specified float is finite, for
1024 /// example if it is infinity or NaN this function will panic.
1025 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1026 pub fn f32_suffixed(n: f32) -> Literal {
1028 panic!("Invalid float literal {}", n);
1031 lit: token::Lit::Float(Symbol::intern(&n.to_string())),
1032 suffix: Some(Symbol::intern("f32")),
1033 span: Span::call_site(),
1037 /// Creates a new unsuffixed floating-point literal.
1039 /// This constructor is similar to those like `Literal::i8_unsuffixed` where
1040 /// the float's value is emitted directly into the token but no suffix is
1041 /// used, so it may be inferred to be a `f64` later in the compiler.
1042 /// Literals created from negative numbers may not survive rountrips through
1043 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
1047 /// This function requires that the specified float is finite, for
1048 /// example if it is infinity or NaN this function will panic.
1049 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1050 pub fn f64_unsuffixed(n: f64) -> Literal {
1052 panic!("Invalid float literal {}", n);
1055 lit: token::Lit::Float(Symbol::intern(&n.to_string())),
1057 span: Span::call_site(),
1061 /// Creates a new suffixed floating-point literal.
1063 /// This consturctor will create a literal like `1.0f64` where the value
1064 /// specified is the preceding part of the token and `f64` is the suffix of
1065 /// the token. This token will always be inferred to be an `f64` in the
1067 /// Literals created from negative numbers may not survive rountrips through
1068 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
1072 /// This function requires that the specified float is finite, for
1073 /// example if it is infinity or NaN this function will panic.
1074 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1075 pub fn f64_suffixed(n: f64) -> Literal {
1077 panic!("Invalid float literal {}", n);
1080 lit: token::Lit::Float(Symbol::intern(&n.to_string())),
1081 suffix: Some(Symbol::intern("f64")),
1082 span: Span::call_site(),
1087 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1088 pub fn string(string: &str) -> Literal {
1089 let mut escaped = String::new();
1090 for ch in string.chars() {
1091 escaped.extend(ch.escape_debug());
1094 lit: token::Lit::Str_(Symbol::intern(&escaped)),
1096 span: Span::call_site(),
1100 /// Character literal.
1101 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1102 pub fn character(ch: char) -> Literal {
1103 let mut escaped = String::new();
1104 escaped.extend(ch.escape_unicode());
1106 lit: token::Lit::Char(Symbol::intern(&escaped)),
1108 span: Span::call_site(),
1112 /// Byte string literal.
1113 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1114 pub fn byte_string(bytes: &[u8]) -> Literal {
1115 let string = bytes.iter().cloned().flat_map(ascii::escape_default)
1116 .map(Into::<char>::into).collect::<String>();
1118 lit: token::Lit::ByteStr(Symbol::intern(&string)),
1120 span: Span::call_site(),
1124 /// Returns the span encompassing this literal.
1125 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1126 pub fn span(&self) -> Span {
1130 /// Configures the span associated for this literal.
1131 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1132 pub fn set_span(&mut self, span: Span) {
1137 /// Prints the literal as a string that should be losslessly convertible
1138 /// back into the same literal (except for possible rounding for floating point literals).
1139 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1140 impl fmt::Display for Literal {
1141 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1142 TokenStream::from(TokenTree::from(self.clone())).fmt(f)
1146 /// Permanently unstable internal implementation details of this crate. This
1147 /// should not be used.
1149 /// These methods are used by the rest of the compiler to generate instances of
1150 /// `TokenStream` to hand to macro definitions, as well as consume the output.
1152 /// Note that this module is also intentionally separate from the rest of the
1153 /// crate. This allows the `#[unstable]` directive below to naturally apply to
1154 /// all of the contents.
1155 #[unstable(feature = "proc_macro_internals", issue = "27812")]
1157 pub mod __internal {
1158 use std::cell::Cell;
1162 use syntax::ext::base::ExtCtxt;
1164 use syntax::parse::{self, ParseSess};
1165 use syntax::parse::token::{self, Token};
1166 use syntax::tokenstream;
1167 use syntax_pos::{BytePos, Loc, DUMMY_SP};
1168 use syntax_pos::hygiene::{SyntaxContext, Transparency};
1170 use super::{TokenStream, LexError, Span};
1172 pub fn lookup_char_pos(pos: BytePos) -> Loc {
1173 with_sess(|sess, _| sess.codemap().lookup_char_pos(pos))
1176 pub fn new_token_stream(item: P<ast::Item>) -> TokenStream {
1177 let token = Token::interpolated(token::NtItem(item));
1178 TokenStream(tokenstream::TokenTree::Token(DUMMY_SP, token).into())
1181 pub fn token_stream_wrap(inner: tokenstream::TokenStream) -> TokenStream {
1185 pub fn token_stream_parse_items(stream: TokenStream) -> Result<Vec<P<ast::Item>>, LexError> {
1186 with_sess(move |sess, _| {
1187 let mut parser = parse::stream_to_parser(sess, stream.0);
1188 let mut items = Vec::new();
1190 while let Some(item) = try!(parser.parse_item().map_err(super::parse_to_lex_err)) {
1198 pub fn token_stream_inner(stream: TokenStream) -> tokenstream::TokenStream {
1202 pub trait Registry {
1203 fn register_custom_derive(&mut self,
1205 expand: fn(TokenStream) -> TokenStream,
1206 attributes: &[&'static str]);
1208 fn register_attr_proc_macro(&mut self,
1210 expand: fn(TokenStream, TokenStream) -> TokenStream);
1212 fn register_bang_proc_macro(&mut self,
1214 expand: fn(TokenStream) -> TokenStream);
1217 #[derive(Clone, Copy)]
1218 pub struct ProcMacroData {
1220 pub call_site: Span,
1223 #[derive(Clone, Copy)]
1224 struct ProcMacroSess {
1225 parse_sess: *const ParseSess,
1226 data: ProcMacroData,
1229 // Emulate scoped_thread_local!() here essentially
1231 static CURRENT_SESS: Cell<ProcMacroSess> = Cell::new(ProcMacroSess {
1232 parse_sess: ptr::null(),
1233 data: ProcMacroData { def_site: Span(DUMMY_SP), call_site: Span(DUMMY_SP) },
1237 pub fn set_sess<F, R>(cx: &ExtCtxt, f: F) -> R
1238 where F: FnOnce() -> R
1240 struct Reset { prev: ProcMacroSess }
1242 impl Drop for Reset {
1243 fn drop(&mut self) {
1244 CURRENT_SESS.with(|p| p.set(self.prev));
1248 CURRENT_SESS.with(|p| {
1249 let _reset = Reset { prev: p.get() };
1251 // No way to determine def location for a proc macro right now, so use call location.
1252 let location = cx.current_expansion.mark.expn_info().unwrap().call_site;
1253 let to_span = |transparency| Span(location.with_ctxt(
1254 SyntaxContext::empty().apply_mark_with_transparency(cx.current_expansion.mark,
1257 p.set(ProcMacroSess {
1258 parse_sess: cx.parse_sess,
1259 data: ProcMacroData {
1260 def_site: to_span(Transparency::Opaque),
1261 call_site: to_span(Transparency::Transparent),
1268 pub fn in_sess() -> bool
1270 !CURRENT_SESS.with(|sess| sess.get()).parse_sess.is_null()
1273 pub fn with_sess<F, R>(f: F) -> R
1274 where F: FnOnce(&ParseSess, &ProcMacroData) -> R
1276 let sess = CURRENT_SESS.with(|sess| sess.get());
1277 if sess.parse_sess.is_null() {
1278 panic!("procedural macro API is used outside of a procedural macro");
1280 f(unsafe { &*sess.parse_sess }, &sess.data)
1284 fn parse_to_lex_err(mut err: DiagnosticBuilder) -> LexError {
1286 LexError { _inner: () }