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 #![cfg_attr(not(stage0), feature(nll))]
35 #![feature(rustc_private)]
36 #![feature(staged_api)]
37 #![feature(lang_items)]
38 #![feature(optin_builtin_traits)]
40 #![recursion_limit="256"]
43 extern crate syntax_pos;
44 extern crate rustc_errors;
45 extern crate rustc_data_structures;
47 #[unstable(feature = "proc_macro_internals", issue = "27812")]
53 #[unstable(feature = "proc_macro_diagnostic", issue = "38356")]
54 pub use diagnostic::{Diagnostic, Level};
56 use std::{ascii, fmt, iter};
57 use std::path::PathBuf;
58 use rustc_data_structures::sync::Lrc;
59 use std::str::FromStr;
61 use syntax::errors::DiagnosticBuilder;
62 use syntax::parse::{self, token};
63 use syntax::symbol::Symbol;
64 use syntax::tokenstream;
65 use syntax_pos::{FileMap, Pos, FileName};
67 /// The main type provided by this crate, representing an abstract stream of
68 /// tokens, or, more specifically, a sequence of token trees.
69 /// The type provide interfaces for iterating over those token trees and, conversely,
70 /// collecting a number of token trees into one stream.
72 /// This is both the input and output of `#[proc_macro]`, `#[proc_macro_attribute]`
73 /// and `#[proc_macro_derive]` definitions.
75 /// The API of this type is intentionally bare-bones, but it'll be expanded over
77 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
79 pub struct TokenStream(tokenstream::TokenStream);
81 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
82 impl !Send for TokenStream {}
83 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
84 impl !Sync for TokenStream {}
86 /// Error returned from `TokenStream::from_str`.
87 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
93 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
94 impl !Send for LexError {}
95 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
96 impl !Sync for LexError {}
99 /// Returns an empty `TokenStream` containing no token trees.
100 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
101 pub fn new() -> TokenStream {
102 TokenStream(tokenstream::TokenStream::empty())
105 /// Checks if this `TokenStream` is empty.
106 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
107 pub fn is_empty(&self) -> bool {
112 /// Attempts to break the string into tokens and parse those tokens into a token stream.
113 /// May fail for a number of reasons, for example, if the string contains unbalanced delimiters
114 /// or characters not existing in the language.
115 /// All tokens in the parsed stream get `Span::call_site()` spans.
117 /// NOTE: Some errors may cause panics instead of returning `LexError`. We reserve the right to
118 /// change these errors into `LexError`s later.
119 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
120 impl FromStr for TokenStream {
123 fn from_str(src: &str) -> Result<TokenStream, LexError> {
124 __internal::with_sess(|sess, data| {
125 Ok(__internal::token_stream_wrap(parse::parse_stream_from_source_str(
126 FileName::ProcMacroSourceCode, src.to_string(), sess, Some(data.call_site.0)
132 /// Prints the token stream as a string that is supposed to be losslessly convertible back
133 /// into the same token stream (modulo spans), except for possibly `TokenTree::Group`s
134 /// with `Delimiter::None` delimiters and negative numeric literals.
135 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
136 impl fmt::Display for TokenStream {
137 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
142 /// Prints token in a form convenient for debugging.
143 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
144 impl fmt::Debug for TokenStream {
145 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
146 f.write_str("TokenStream ")?;
147 f.debug_list().entries(self.clone()).finish()
151 #[unstable(feature = "proc_macro_quote", issue = "38356")]
152 pub use quote::{quote, quote_span};
154 /// Creates a token stream containing a single token tree.
155 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
156 impl From<TokenTree> for TokenStream {
157 fn from(tree: TokenTree) -> TokenStream {
158 TokenStream(tree.to_internal())
162 /// Collects a number of token trees into a single stream.
163 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
164 impl iter::FromIterator<TokenTree> for TokenStream {
165 fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
166 trees.into_iter().map(TokenStream::from).collect()
170 /// A "flattening" operation on token streams, collects token trees
171 /// from multiple token streams into a single stream.
172 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
173 impl iter::FromIterator<TokenStream> for TokenStream {
174 fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
175 let mut builder = tokenstream::TokenStreamBuilder::new();
176 for stream in streams {
177 builder.push(stream.0);
179 TokenStream(builder.build())
183 /// Public implementation details for the `TokenStream` type, such as iterators.
184 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
185 pub mod token_stream {
186 use syntax::tokenstream;
187 use {TokenTree, TokenStream, Delimiter};
189 /// An iterator over `TokenStream`'s `TokenTree`s.
190 /// The iteration is "shallow", e.g. the iterator doesn't recurse into delimited groups,
191 /// and returns whole groups as token trees.
193 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
194 pub struct IntoIter {
195 cursor: tokenstream::Cursor,
196 stack: Vec<TokenTree>,
199 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
200 impl Iterator for IntoIter {
201 type Item = TokenTree;
203 fn next(&mut self) -> Option<TokenTree> {
205 let tree = self.stack.pop().or_else(|| {
206 let next = self.cursor.next_as_stream()?;
207 Some(TokenTree::from_internal(next, &mut self.stack))
209 // HACK: The condition "dummy span + group with empty delimiter" represents an AST
210 // fragment approximately converted into a token stream. This may happen, for
211 // example, with inputs to proc macro attributes, including derives. Such "groups"
212 // need to flattened during iteration over stream's token trees.
213 // Eventually this needs to be removed in favor of keeping original token trees
214 // and not doing the roundtrip through AST.
215 if tree.span().0.is_dummy() {
216 if let TokenTree::Group(ref group) = tree {
217 if group.delimiter() == Delimiter::None {
218 self.cursor.insert(group.stream.clone().0);
228 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
229 impl IntoIterator for TokenStream {
230 type Item = TokenTree;
231 type IntoIter = IntoIter;
233 fn into_iter(self) -> IntoIter {
234 IntoIter { cursor: self.0.trees(), stack: Vec::new() }
239 /// `quote!(..)` accepts arbitrary tokens and expands into a `TokenStream` describing the input.
240 /// For example, `quote!(a + b)` will produce a expression, that, when evaluated, constructs
241 /// the `TokenStream` `[Ident("a"), Punct('+', Alone), Ident("b")]`.
243 /// Unquoting is done with `$`, and works by taking the single next ident as the unquoted term.
244 /// To quote `$` itself, use `$$`.
246 /// This is a dummy macro, the actual implementation is in `quote::quote`.`
247 #[unstable(feature = "proc_macro_quote", issue = "38356")]
249 macro_rules! quote { () => {} }
251 #[unstable(feature = "proc_macro_internals", issue = "27812")]
255 /// A region of source code, along with macro expansion information.
256 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
257 #[derive(Copy, Clone)]
258 pub struct Span(syntax_pos::Span);
260 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
261 impl !Send for Span {}
262 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
263 impl !Sync for Span {}
265 macro_rules! diagnostic_method {
266 ($name:ident, $level:expr) => (
267 /// Create a new `Diagnostic` with the given `message` at the span
269 #[unstable(feature = "proc_macro_diagnostic", issue = "38356")]
270 pub fn $name<T: Into<String>>(self, message: T) -> Diagnostic {
271 Diagnostic::spanned(self, $level, message)
277 /// A span that resolves at the macro definition site.
278 #[unstable(feature = "proc_macro_span", issue = "38356")]
279 pub fn def_site() -> Span {
280 ::__internal::with_sess(|_, data| data.def_site)
283 /// The span of the invocation of the current procedural macro.
284 /// Identifiers created with this span will be resolved as if they were written
285 /// directly at the macro call location (call-site hygiene) and other code
286 /// at the macro call site will be able to refer to them as well.
287 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
288 pub fn call_site() -> Span {
289 ::__internal::with_sess(|_, data| data.call_site)
292 /// The original source file into which this span points.
293 #[unstable(feature = "proc_macro_span", issue = "38356")]
294 pub fn source_file(&self) -> SourceFile {
296 filemap: __internal::lookup_char_pos(self.0.lo()).file,
300 /// The `Span` for the tokens in the previous macro expansion from which
301 /// `self` was generated from, if any.
302 #[unstable(feature = "proc_macro_span", issue = "38356")]
303 pub fn parent(&self) -> Option<Span> {
304 self.0.parent().map(Span)
307 /// The span for the origin source code that `self` was generated from. If
308 /// this `Span` wasn't generated from other macro expansions then the return
309 /// value is the same as `*self`.
310 #[unstable(feature = "proc_macro_span", issue = "38356")]
311 pub fn source(&self) -> Span {
312 Span(self.0.source_callsite())
315 /// Get the starting line/column in the source file for this span.
316 #[unstable(feature = "proc_macro_span", issue = "38356")]
317 pub fn start(&self) -> LineColumn {
318 let loc = __internal::lookup_char_pos(self.0.lo());
321 column: loc.col.to_usize()
325 /// Get the ending line/column in the source file for this span.
326 #[unstable(feature = "proc_macro_span", issue = "38356")]
327 pub fn end(&self) -> LineColumn {
328 let loc = __internal::lookup_char_pos(self.0.hi());
331 column: loc.col.to_usize()
335 /// Create a new span encompassing `self` and `other`.
337 /// Returns `None` if `self` and `other` are from different files.
338 #[unstable(feature = "proc_macro_span", issue = "38356")]
339 pub fn join(&self, other: Span) -> Option<Span> {
340 let self_loc = __internal::lookup_char_pos(self.0.lo());
341 let other_loc = __internal::lookup_char_pos(other.0.lo());
343 if self_loc.file.name != other_loc.file.name { return None }
345 Some(Span(self.0.to(other.0)))
348 /// Creates a new span with the same line/column information as `self` but
349 /// that resolves symbols as though it were at `other`.
350 #[unstable(feature = "proc_macro_span", issue = "38356")]
351 pub fn resolved_at(&self, other: Span) -> Span {
352 Span(self.0.with_ctxt(other.0.ctxt()))
355 /// Creates a new span with the same name resolution behavior as `self` but
356 /// with the line/column information of `other`.
357 #[unstable(feature = "proc_macro_span", issue = "38356")]
358 pub fn located_at(&self, other: Span) -> Span {
359 other.resolved_at(*self)
362 /// Compares to spans to see if they're equal.
363 #[unstable(feature = "proc_macro_span", issue = "38356")]
364 pub fn eq(&self, other: &Span) -> bool {
368 diagnostic_method!(error, Level::Error);
369 diagnostic_method!(warning, Level::Warning);
370 diagnostic_method!(note, Level::Note);
371 diagnostic_method!(help, Level::Help);
374 /// Prints a span in a form convenient for debugging.
375 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
376 impl fmt::Debug for Span {
377 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
378 write!(f, "{:?} bytes({}..{})",
385 /// A line-column pair representing the start or end of a `Span`.
386 #[unstable(feature = "proc_macro_span", issue = "38356")]
387 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
388 pub struct LineColumn {
389 /// The 1-indexed line in the source file on which the span starts or ends (inclusive).
390 #[unstable(feature = "proc_macro_span", issue = "38356")]
392 /// The 0-indexed column (in UTF-8 characters) in the source file on which
393 /// the span starts or ends (inclusive).
394 #[unstable(feature = "proc_macro_span", issue = "38356")]
398 #[unstable(feature = "proc_macro_span", issue = "38356")]
399 impl !Send for LineColumn {}
400 #[unstable(feature = "proc_macro_span", issue = "38356")]
401 impl !Sync for LineColumn {}
403 /// The source file of a given `Span`.
404 #[unstable(feature = "proc_macro_span", issue = "38356")]
406 pub struct SourceFile {
407 filemap: Lrc<FileMap>,
410 #[unstable(feature = "proc_macro_span", issue = "38356")]
411 impl !Send for SourceFile {}
412 #[unstable(feature = "proc_macro_span", issue = "38356")]
413 impl !Sync for SourceFile {}
416 /// Get the path to this source file.
419 /// If the code span associated with this `SourceFile` was generated by an external macro, this
420 /// may not be an actual path on the filesystem. Use [`is_real`] to check.
422 /// Also note that even if `is_real` returns `true`, if `--remap-path-prefix` was passed on
423 /// the command line, the path as given may not actually be valid.
425 /// [`is_real`]: #method.is_real
426 #[unstable(feature = "proc_macro_span", issue = "38356")]
427 pub fn path(&self) -> PathBuf {
428 match self.filemap.name {
429 FileName::Real(ref path) => path.clone(),
430 _ => PathBuf::from(self.filemap.name.to_string())
434 /// Returns `true` if this source file is a real source file, and not generated by an external
435 /// macro's expansion.
436 #[unstable(feature = "proc_macro_span", issue = "38356")]
437 pub fn is_real(&self) -> bool {
438 // This is a hack until intercrate spans are implemented and we can have real source files
439 // for spans generated in external macros.
440 // https://github.com/rust-lang/rust/pull/43604#issuecomment-333334368
441 self.filemap.is_real_file()
446 #[unstable(feature = "proc_macro_span", issue = "38356")]
447 impl fmt::Debug for SourceFile {
448 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
449 f.debug_struct("SourceFile")
450 .field("path", &self.path())
451 .field("is_real", &self.is_real())
456 #[unstable(feature = "proc_macro_span", issue = "38356")]
457 impl PartialEq for SourceFile {
458 fn eq(&self, other: &Self) -> bool {
459 Lrc::ptr_eq(&self.filemap, &other.filemap)
463 #[unstable(feature = "proc_macro_span", issue = "38356")]
464 impl Eq for SourceFile {}
466 /// A single token or a delimited sequence of token trees (e.g. `[1, (), ..]`).
467 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
470 /// A token stream surrounded by bracket delimiters.
471 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
473 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
477 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
479 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
482 /// A single punctuation character (`+`, `,`, `$`, etc.).
483 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
485 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
488 /// A literal character (`'a'`), string (`"hello"`), number (`2.3`), etc.
489 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
491 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
496 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
497 impl !Send for TokenTree {}
498 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
499 impl !Sync for TokenTree {}
502 /// Returns the span of this tree, delegating to the `span` method of
503 /// the contained token or a delimited stream.
504 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
505 pub fn span(&self) -> Span {
507 TokenTree::Group(ref t) => t.span(),
508 TokenTree::Ident(ref t) => t.span(),
509 TokenTree::Punct(ref t) => t.span(),
510 TokenTree::Literal(ref t) => t.span(),
514 /// Configures the span for *only this token*.
516 /// Note that if this token is a `Group` then this method will not configure
517 /// the span of each of the internal tokens, this will simply delegate to
518 /// the `set_span` method of each variant.
519 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
520 pub fn set_span(&mut self, span: Span) {
522 TokenTree::Group(ref mut t) => t.set_span(span),
523 TokenTree::Ident(ref mut t) => t.set_span(span),
524 TokenTree::Punct(ref mut t) => t.set_span(span),
525 TokenTree::Literal(ref mut t) => t.set_span(span),
530 /// Prints token treee in a form convenient for debugging.
531 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
532 impl fmt::Debug for TokenTree {
533 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
534 // Each of these has the name in the struct type in the derived debug,
535 // so don't bother with an extra layer of indirection
537 TokenTree::Group(ref tt) => tt.fmt(f),
538 TokenTree::Ident(ref tt) => tt.fmt(f),
539 TokenTree::Punct(ref tt) => tt.fmt(f),
540 TokenTree::Literal(ref tt) => tt.fmt(f),
545 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
546 impl From<Group> for TokenTree {
547 fn from(g: Group) -> TokenTree {
552 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
553 impl From<Ident> for TokenTree {
554 fn from(g: Ident) -> TokenTree {
559 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
560 impl From<Punct> for TokenTree {
561 fn from(g: Punct) -> TokenTree {
566 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
567 impl From<Literal> for TokenTree {
568 fn from(g: Literal) -> TokenTree {
569 TokenTree::Literal(g)
573 /// Prints the token tree as a string that is supposed to be losslessly convertible back
574 /// into the same token tree (modulo spans), except for possibly `TokenTree::Group`s
575 /// with `Delimiter::None` delimiters and negative numeric literals.
576 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
577 impl fmt::Display for TokenTree {
578 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
580 TokenTree::Group(ref t) => t.fmt(f),
581 TokenTree::Ident(ref t) => t.fmt(f),
582 TokenTree::Punct(ref t) => t.fmt(f),
583 TokenTree::Literal(ref t) => t.fmt(f),
588 /// A delimited token stream.
590 /// A `Group` internally contains a `TokenStream` which is surrounded by `Delimiter`s.
592 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
594 delimiter: Delimiter,
599 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
600 impl !Send for Group {}
601 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
602 impl !Sync for Group {}
604 /// Describes how a sequence of token trees is delimited.
605 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
606 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
609 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
612 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
615 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
618 /// An implicit delimiter, that may, for example, appear around tokens coming from a
619 /// "macro variable" `$var`. It is important to preserve operator priorities in cases like
620 /// `$var * 3` where `$var` is `1 + 2`.
621 /// Implicit delimiters may not survive roundtrip of a token stream through a string.
622 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
627 /// Creates a new `Group` with the given delimiter and token stream.
629 /// This constructor will set the span for this group to
630 /// `Span::call_site()`. To change the span you can use the `set_span`
632 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
633 pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
635 delimiter: delimiter,
637 span: Span::call_site(),
641 /// Returns the delimiter of this `Group`
642 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
643 pub fn delimiter(&self) -> Delimiter {
647 /// Returns the `TokenStream` of tokens that are delimited in this `Group`.
649 /// Note that the returned token stream does not include the delimiter
651 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
652 pub fn stream(&self) -> TokenStream {
656 /// Returns the span for the delimiters of this token stream, spanning the
658 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
659 pub fn span(&self) -> Span {
663 /// Configures the span for this `Group`'s delimiters, but not its internal
666 /// This method will **not** set the span of all the internal tokens spanned
667 /// by this group, but rather it will only set the span of the delimiter
668 /// tokens at the level of the `Group`.
669 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
670 pub fn set_span(&mut self, span: Span) {
675 /// Prints the group as a string that should be losslessly convertible back
676 /// into the same group (modulo spans), except for possibly `TokenTree::Group`s
677 /// with `Delimiter::None` delimiters.
678 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
679 impl fmt::Display for Group {
680 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
681 TokenStream::from(TokenTree::from(self.clone())).fmt(f)
685 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
686 impl fmt::Debug for Group {
687 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
688 f.debug_struct("Group")
689 .field("delimiter", &self.delimiter())
690 .field("stream", &self.stream())
691 .field("span", &self.span())
696 /// An `Punct` is an single punctuation character like `+`, `-` or `#`.
698 /// Multicharacter operators like `+=` are represented as two instances of `Punct` with different
699 /// forms of `Spacing` returned.
700 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
708 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
709 impl !Send for Punct {}
710 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
711 impl !Sync for Punct {}
713 /// Whether an `Punct` is followed immediately by another `Punct` or
714 /// followed by another token or whitespace.
715 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
716 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
718 /// E.g. `+` is `Alone` in `+ =`, `+ident` or `+()`.
719 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
721 /// E.g. `+` is `Joint` in `+=` or `'#`.
722 /// Additionally, single quote `'` can join with identifiers to form lifetimes `'ident`.
723 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
728 /// Creates a new `Punct` from the given character and spacing.
729 /// The `ch` argument must be a valid punctuation character permitted by the language,
730 /// otherwise the function will panic.
732 /// The returned `Punct` will have the default span of `Span::call_site()`
733 /// which can be further configured with the `set_span` method below.
734 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
735 pub fn new(ch: char, spacing: Spacing) -> Punct {
736 const LEGAL_CHARS: &[char] = &['=', '<', '>', '!', '~', '+', '-', '*', '/', '%', '^',
737 '&', '|', '@', '.', ',', ';', ':', '#', '$', '?', '\''];
738 if !LEGAL_CHARS.contains(&ch) {
739 panic!("unsupported character `{:?}`", ch)
744 span: Span::call_site(),
748 /// Returns the value of this punctuation character as `char`.
749 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
750 pub fn as_char(&self) -> char {
754 /// Returns the spacing of this punctuation character, indicating whether it's immediately
755 /// followed by another `Punct` in the token stream, so they can potentially be combined into
756 /// a multicharacter operator (`Joint`), or it's followed by some other token or whitespace
757 /// (`Alone`) so the operator has certainly ended.
758 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
759 pub fn spacing(&self) -> Spacing {
763 /// Returns the span for this punctuation character.
764 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
765 pub fn span(&self) -> Span {
769 /// Configure the span for this punctuation character.
770 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
771 pub fn set_span(&mut self, span: Span) {
776 /// Prints the punctuation character as a string that should be losslessly convertible
777 /// back into the same character.
778 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
779 impl fmt::Display for Punct {
780 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
781 TokenStream::from(TokenTree::from(self.clone())).fmt(f)
785 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
786 impl fmt::Debug for Punct {
787 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
788 f.debug_struct("Punct")
789 .field("ch", &self.as_char())
790 .field("spacing", &self.spacing())
791 .field("span", &self.span())
796 /// An identifier (`ident`).
798 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
805 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
806 impl !Send for Ident {}
807 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
808 impl !Sync for Ident {}
811 fn is_valid(string: &str) -> bool {
812 let mut chars = string.chars();
813 if let Some(start) = chars.next() {
814 (start == '_' || start.is_xid_start())
815 && chars.all(|cont| cont == '_' || cont.is_xid_continue())
821 /// Creates a new `Ident` with the given `string` as well as the specified
823 /// The `string` argument must be a valid identifier permitted by the
824 /// language, otherwise the function will panic.
826 /// Note that `span`, currently in rustc, configures the hygiene information
827 /// for this identifier.
829 /// As of this time `Span::call_site()` explicitly opts-in to "call-site" hygiene
830 /// meaning that identifiers created with this span will be resolved as if they were written
831 /// directly at the location of the macro call, and other code at the macro call site will be
832 /// able to refer to them as well.
834 /// Later spans like `Span::def_site()` will allow to opt-in to "definition-site" hygiene
835 /// meaning that identifiers created with this span will be resolved at the location of the
836 /// macro definition and other code at the macro call site will not be able to refer to them.
838 /// Due to the current importance of hygiene this constructor, unlike other
839 /// tokens, requires a `Span` to be specified at construction.
840 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
841 pub fn new(string: &str, span: Span) -> Ident {
842 if !Ident::is_valid(string) {
843 panic!("`{:?}` is not a valid identifier", string)
845 Ident::new_maybe_raw(string, span, false)
848 /// Same as `Ident::new`, but creates a raw identifier (`r#ident`).
849 #[unstable(feature = "proc_macro_raw_ident", issue = "38356")]
850 pub fn new_raw(string: &str, span: Span) -> Ident {
851 if !Ident::is_valid(string) {
852 panic!("`{:?}` is not a valid identifier", string)
854 Ident::new_maybe_raw(string, span, true)
857 /// Returns the span of this `Ident`, encompassing the entire string returned
859 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
860 pub fn span(&self) -> Span {
864 /// Configures the span of this `Ident`, possibly changing its hygiene context.
865 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
866 pub fn set_span(&mut self, span: Span) {
871 /// Prints the identifier as a string that should be losslessly convertible
872 /// back into the same identifier.
873 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
874 impl fmt::Display for Ident {
875 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
876 TokenStream::from(TokenTree::from(self.clone())).fmt(f)
880 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
881 impl fmt::Debug for Ident {
882 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
883 f.debug_struct("Ident")
884 .field("ident", &self.to_string())
885 .field("span", &self.span())
890 /// A literal string (`"hello"`), byte string (`b"hello"`),
891 /// character (`'a'`), byte character (`b'a'`), an integer or floating point number
892 /// with or without a suffix (`1`, `1u8`, `2.3`, `2.3f32`).
893 /// Boolean literals like `true` and `false` do not belong here, they are `Ident`s.
894 // FIXME(eddyb) `Literal` should not expose internal `Debug` impls.
895 #[derive(Clone, Debug)]
896 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
899 suffix: Option<Symbol>,
903 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
904 impl !Send for Literal {}
905 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
906 impl !Sync for Literal {}
908 macro_rules! suffixed_int_literals {
909 ($($name:ident => $kind:ident,)*) => ($(
910 /// Creates a new suffixed integer literal with the specified value.
912 /// This function will create an integer like `1u32` where the integer
913 /// value specified is the first part of the token and the integral is
914 /// also suffixed at the end.
915 /// Literals created from negative numbers may not survive rountrips through
916 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
918 /// Literals created through this method have the `Span::call_site()`
919 /// span by default, which can be configured with the `set_span` method
921 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
922 pub fn $name(n: $kind) -> Literal {
924 lit: token::Lit::Integer(Symbol::intern(&n.to_string())),
925 suffix: Some(Symbol::intern(stringify!($kind))),
926 span: Span::call_site(),
932 macro_rules! unsuffixed_int_literals {
933 ($($name:ident => $kind:ident,)*) => ($(
934 /// Creates a new unsuffixed integer literal with the specified value.
936 /// This function will create an integer like `1` where the integer
937 /// value specified is the first part of the token. No suffix is
938 /// specified on this token, meaning that invocations like
939 /// `Literal::i8_unsuffixed(1)` are equivalent to
940 /// `Literal::u32_unsuffixed(1)`.
941 /// Literals created from negative numbers may not survive rountrips through
942 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
944 /// Literals created through this method have the `Span::call_site()`
945 /// span by default, which can be configured with the `set_span` method
947 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
948 pub fn $name(n: $kind) -> Literal {
950 lit: token::Lit::Integer(Symbol::intern(&n.to_string())),
952 span: Span::call_site(),
959 suffixed_int_literals! {
964 u128_suffixed => u128,
965 usize_suffixed => usize,
970 i128_suffixed => i128,
971 isize_suffixed => isize,
974 unsuffixed_int_literals! {
976 u16_unsuffixed => u16,
977 u32_unsuffixed => u32,
978 u64_unsuffixed => u64,
979 u128_unsuffixed => u128,
980 usize_unsuffixed => usize,
982 i16_unsuffixed => i16,
983 i32_unsuffixed => i32,
984 i64_unsuffixed => i64,
985 i128_unsuffixed => i128,
986 isize_unsuffixed => isize,
989 /// Creates a new unsuffixed floating-point literal.
991 /// This constructor is similar to those like `Literal::i8_unsuffixed` where
992 /// the float's value is emitted directly into the token but no suffix is
993 /// used, so it may be inferred to be a `f64` later in the compiler.
994 /// Literals created from negative numbers may not survive rountrips through
995 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
999 /// This function requires that the specified float is finite, for
1000 /// example if it is infinity or NaN this function will panic.
1001 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1002 pub fn f32_unsuffixed(n: f32) -> Literal {
1004 panic!("Invalid float literal {}", n);
1007 lit: token::Lit::Float(Symbol::intern(&n.to_string())),
1009 span: Span::call_site(),
1013 /// Creates a new suffixed floating-point literal.
1015 /// This consturctor will create a literal like `1.0f32` where the value
1016 /// specified is the preceding part of the token and `f32` is the suffix of
1017 /// the token. This token will always be inferred to be an `f32` in the
1019 /// Literals created from negative numbers may not survive rountrips through
1020 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
1024 /// This function requires that the specified float is finite, for
1025 /// example if it is infinity or NaN this function will panic.
1026 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1027 pub fn f32_suffixed(n: f32) -> Literal {
1029 panic!("Invalid float literal {}", n);
1032 lit: token::Lit::Float(Symbol::intern(&n.to_string())),
1033 suffix: Some(Symbol::intern("f32")),
1034 span: Span::call_site(),
1038 /// Creates a new unsuffixed floating-point literal.
1040 /// This constructor is similar to those like `Literal::i8_unsuffixed` where
1041 /// the float's value is emitted directly into the token but no suffix is
1042 /// used, so it may be inferred to be a `f64` later in the compiler.
1043 /// Literals created from negative numbers may not survive rountrips through
1044 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
1048 /// This function requires that the specified float is finite, for
1049 /// example if it is infinity or NaN this function will panic.
1050 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1051 pub fn f64_unsuffixed(n: f64) -> Literal {
1053 panic!("Invalid float literal {}", n);
1056 lit: token::Lit::Float(Symbol::intern(&n.to_string())),
1058 span: Span::call_site(),
1062 /// Creates a new suffixed floating-point literal.
1064 /// This consturctor will create a literal like `1.0f64` where the value
1065 /// specified is the preceding part of the token and `f64` is the suffix of
1066 /// the token. This token will always be inferred to be an `f64` in the
1068 /// Literals created from negative numbers may not survive rountrips through
1069 /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
1073 /// This function requires that the specified float is finite, for
1074 /// example if it is infinity or NaN this function will panic.
1075 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1076 pub fn f64_suffixed(n: f64) -> Literal {
1078 panic!("Invalid float literal {}", n);
1081 lit: token::Lit::Float(Symbol::intern(&n.to_string())),
1082 suffix: Some(Symbol::intern("f64")),
1083 span: Span::call_site(),
1088 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1089 pub fn string(string: &str) -> Literal {
1090 let mut escaped = String::new();
1091 for ch in string.chars() {
1092 escaped.extend(ch.escape_debug());
1095 lit: token::Lit::Str_(Symbol::intern(&escaped)),
1097 span: Span::call_site(),
1101 /// Character literal.
1102 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1103 pub fn character(ch: char) -> Literal {
1104 let mut escaped = String::new();
1105 escaped.extend(ch.escape_unicode());
1107 lit: token::Lit::Char(Symbol::intern(&escaped)),
1109 span: Span::call_site(),
1113 /// Byte string literal.
1114 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1115 pub fn byte_string(bytes: &[u8]) -> Literal {
1116 let string = bytes.iter().cloned().flat_map(ascii::escape_default)
1117 .map(Into::<char>::into).collect::<String>();
1119 lit: token::Lit::ByteStr(Symbol::intern(&string)),
1121 span: Span::call_site(),
1125 /// Returns the span encompassing this literal.
1126 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1127 pub fn span(&self) -> Span {
1131 /// Configures the span associated for this literal.
1132 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1133 pub fn set_span(&mut self, span: Span) {
1138 /// Prints the literal as a string that should be losslessly convertible
1139 /// back into the same literal (except for possible rounding for floating point literals).
1140 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1141 impl fmt::Display for Literal {
1142 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1143 TokenStream::from(TokenTree::from(self.clone())).fmt(f)
1147 /// Permanently unstable internal implementation details of this crate. This
1148 /// should not be used.
1150 /// These methods are used by the rest of the compiler to generate instances of
1151 /// `TokenStream` to hand to macro definitions, as well as consume the output.
1153 /// Note that this module is also intentionally separate from the rest of the
1154 /// crate. This allows the `#[unstable]` directive below to naturally apply to
1155 /// all of the contents.
1156 #[unstable(feature = "proc_macro_internals", issue = "27812")]
1158 pub mod __internal {
1159 use std::cell::Cell;
1163 use syntax::ext::base::ExtCtxt;
1165 use syntax::parse::{self, ParseSess};
1166 use syntax::parse::token::{self, Token};
1167 use syntax::tokenstream;
1168 use syntax_pos::{BytePos, Loc, DUMMY_SP};
1169 use syntax_pos::hygiene::{SyntaxContext, Transparency};
1171 use super::{TokenStream, LexError, Span};
1173 pub fn lookup_char_pos(pos: BytePos) -> Loc {
1174 with_sess(|sess, _| sess.codemap().lookup_char_pos(pos))
1177 pub fn new_token_stream(item: P<ast::Item>) -> TokenStream {
1178 let token = Token::interpolated(token::NtItem(item));
1179 TokenStream(tokenstream::TokenTree::Token(DUMMY_SP, token).into())
1182 pub fn token_stream_wrap(inner: tokenstream::TokenStream) -> TokenStream {
1186 pub fn token_stream_parse_items(stream: TokenStream) -> Result<Vec<P<ast::Item>>, LexError> {
1187 with_sess(move |sess, _| {
1188 let mut parser = parse::stream_to_parser(sess, stream.0);
1189 let mut items = Vec::new();
1191 while let Some(item) = try!(parser.parse_item().map_err(super::parse_to_lex_err)) {
1199 pub fn token_stream_inner(stream: TokenStream) -> tokenstream::TokenStream {
1203 pub trait Registry {
1204 fn register_custom_derive(&mut self,
1206 expand: fn(TokenStream) -> TokenStream,
1207 attributes: &[&'static str]);
1209 fn register_attr_proc_macro(&mut self,
1211 expand: fn(TokenStream, TokenStream) -> TokenStream);
1213 fn register_bang_proc_macro(&mut self,
1215 expand: fn(TokenStream) -> TokenStream);
1218 #[derive(Clone, Copy)]
1219 pub struct ProcMacroData {
1221 pub call_site: Span,
1224 #[derive(Clone, Copy)]
1225 struct ProcMacroSess {
1226 parse_sess: *const ParseSess,
1227 data: ProcMacroData,
1230 // Emulate scoped_thread_local!() here essentially
1232 static CURRENT_SESS: Cell<ProcMacroSess> = Cell::new(ProcMacroSess {
1233 parse_sess: ptr::null(),
1234 data: ProcMacroData { def_site: Span(DUMMY_SP), call_site: Span(DUMMY_SP) },
1238 pub fn set_sess<F, R>(cx: &ExtCtxt, f: F) -> R
1239 where F: FnOnce() -> R
1241 struct Reset { prev: ProcMacroSess }
1243 impl Drop for Reset {
1244 fn drop(&mut self) {
1245 CURRENT_SESS.with(|p| p.set(self.prev));
1249 CURRENT_SESS.with(|p| {
1250 let _reset = Reset { prev: p.get() };
1252 // No way to determine def location for a proc macro right now, so use call location.
1253 let location = cx.current_expansion.mark.expn_info().unwrap().call_site;
1254 let to_span = |transparency| Span(location.with_ctxt(
1255 SyntaxContext::empty().apply_mark_with_transparency(cx.current_expansion.mark,
1258 p.set(ProcMacroSess {
1259 parse_sess: cx.parse_sess,
1260 data: ProcMacroData {
1261 def_site: to_span(Transparency::Opaque),
1262 call_site: to_span(Transparency::Transparent),
1269 pub fn in_sess() -> bool
1271 !CURRENT_SESS.with(|sess| sess.get()).parse_sess.is_null()
1274 pub fn with_sess<F, R>(f: F) -> R
1275 where F: FnOnce(&ParseSess, &ProcMacroData) -> R
1277 let sess = CURRENT_SESS.with(|sess| sess.get());
1278 if sess.parse_sess.is_null() {
1279 panic!("procedural macro API is used outside of a procedural macro");
1281 f(unsafe { &*sess.parse_sess }, &sess.data)
1285 fn parse_to_lex_err(mut err: DiagnosticBuilder) -> LexError {
1287 LexError { _inner: () }