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.
15 //! Currently the primary use of this crate is to provide the ability to define
16 //! new custom derive modes through `#[proc_macro_derive]`.
18 //! Note that this crate is intentionally very bare-bones currently. The main
19 //! type, `TokenStream`, only supports `fmt::Display` and `FromStr`
20 //! implementations, indicating that it can only go to and come from a string.
21 //! This functionality is intended to be expanded over time as more surface
22 //! area for macro authors is stabilized.
24 //! See [the book](../book/first-edition/procedural-macros.html) for more.
26 #![stable(feature = "proc_macro_lib", since = "1.15.0")]
27 #![deny(missing_docs)]
28 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
29 html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
30 html_root_url = "https://doc.rust-lang.org/nightly/",
31 html_playground_url = "https://play.rust-lang.org/",
32 issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
33 test(no_crate_inject, attr(deny(warnings))),
34 test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]
36 #![feature(rustc_private)]
37 #![feature(staged_api)]
38 #![feature(lang_items)]
39 #![feature(optin_builtin_traits)]
42 extern crate syntax_pos;
43 extern crate rustc_errors;
44 extern crate rustc_data_structures;
48 #[unstable(feature = "proc_macro", issue = "38356")]
49 pub use diagnostic::{Diagnostic, Level};
51 use std::{ascii, fmt, iter};
52 use rustc_data_structures::sync::Lrc;
53 use std::str::FromStr;
56 use syntax::errors::DiagnosticBuilder;
57 use syntax::parse::{self, token};
58 use syntax::symbol::Symbol;
59 use syntax::tokenstream;
60 use syntax::parse::lexer::comments;
61 use syntax_pos::{FileMap, Pos, SyntaxContext, FileName};
62 use syntax_pos::hygiene::Mark;
64 /// The main type provided by this crate, representing an abstract stream of
67 /// This is both the input and output of `#[proc_macro_derive]` definitions.
68 /// Currently it's required to be a list of valid Rust items, but this
69 /// restriction may be lifted in the future.
71 /// The API of this type is intentionally bare-bones, but it'll be expanded over
73 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
75 pub struct TokenStream(tokenstream::TokenStream);
77 #[unstable(feature = "proc_macro", issue = "38356")]
78 impl !Send for TokenStream {}
79 #[unstable(feature = "proc_macro", issue = "38356")]
80 impl !Sync for TokenStream {}
82 /// Error returned from `TokenStream::from_str`.
83 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
89 #[unstable(feature = "proc_macro", issue = "38356")]
90 impl !Send for LexError {}
91 #[unstable(feature = "proc_macro", issue = "38356")]
92 impl !Sync for LexError {}
95 /// Returns an empty `TokenStream`.
96 #[unstable(feature = "proc_macro", issue = "38356")]
97 pub fn empty() -> TokenStream {
98 TokenStream(tokenstream::TokenStream::empty())
101 /// Checks if this `TokenStream` is empty.
102 #[unstable(feature = "proc_macro", issue = "38356")]
103 pub fn is_empty(&self) -> bool {
108 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
109 impl FromStr for TokenStream {
112 fn from_str(src: &str) -> Result<TokenStream, LexError> {
113 __internal::with_sess(|(sess, mark)| {
114 let src = src.to_string();
115 let name = FileName::ProcMacroSourceCode;
116 let expn_info = mark.expn_info().unwrap();
117 let call_site = expn_info.call_site;
118 // notify the expansion info that it is unhygienic
119 let mark = Mark::fresh(mark);
120 mark.set_expn_info(expn_info);
121 let span = call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark));
122 let stream = parse::parse_stream_from_source_str(name, src, sess, Some(span));
123 Ok(__internal::token_stream_wrap(stream))
128 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
129 impl fmt::Display for TokenStream {
130 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
135 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
136 impl fmt::Debug for TokenStream {
137 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
138 f.write_str("TokenStream ")?;
139 f.debug_list().entries(self.clone()).finish()
143 #[unstable(feature = "proc_macro", issue = "38356")]
144 impl From<TokenTree> for TokenStream {
145 fn from(tree: TokenTree) -> TokenStream {
146 TokenStream(tree.to_internal())
150 #[unstable(feature = "proc_macro", issue = "38356")]
151 impl iter::FromIterator<TokenTree> for TokenStream {
152 fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
153 trees.into_iter().map(TokenStream::from).collect()
157 #[unstable(feature = "proc_macro", issue = "38356")]
158 impl iter::FromIterator<TokenStream> for TokenStream {
159 fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
160 let mut builder = tokenstream::TokenStreamBuilder::new();
161 for stream in streams {
162 builder.push(stream.0);
164 TokenStream(builder.build())
168 /// Implementation details for the `TokenTree` type, such as iterators.
169 #[unstable(feature = "proc_macro", issue = "38356")]
170 pub mod token_stream {
171 use syntax::tokenstream;
172 use syntax_pos::DUMMY_SP;
174 use {TokenTree, TokenStream, Delimiter};
176 /// An iterator over `TokenTree`s.
178 #[unstable(feature = "proc_macro", issue = "38356")]
179 pub struct IntoIter {
180 cursor: tokenstream::Cursor,
181 stack: Vec<TokenTree>,
184 #[unstable(feature = "proc_macro", issue = "38356")]
185 impl Iterator for IntoIter {
186 type Item = TokenTree;
188 fn next(&mut self) -> Option<TokenTree> {
190 let tree = self.stack.pop().or_else(|| {
191 let next = self.cursor.next_as_stream()?;
192 Some(TokenTree::from_internal(next, &mut self.stack))
194 if tree.span().0 == DUMMY_SP {
195 if let TokenTree::Group(ref group) = tree {
196 if group.delimiter() == Delimiter::None {
197 self.cursor.insert(group.stream.clone().0);
207 #[unstable(feature = "proc_macro", issue = "38356")]
208 impl IntoIterator for TokenStream {
209 type Item = TokenTree;
210 type IntoIter = IntoIter;
212 fn into_iter(self) -> IntoIter {
213 IntoIter { cursor: self.0.trees(), stack: Vec::new() }
218 /// `quote!(..)` accepts arbitrary tokens and expands into a `TokenStream` describing the input.
219 /// For example, `quote!(a + b)` will produce a expression, that, when evaluated, constructs
220 /// the `TokenStream` `[Word("a"), Op('+', Alone), Word("b")]`.
222 /// Unquoting is done with `$`, and works by taking the single next ident as the unquoted term.
223 /// To quote `$` itself, use `$$`.
224 #[unstable(feature = "proc_macro", issue = "38356")]
226 macro_rules! quote { () => {} }
228 #[unstable(feature = "proc_macro_internals", issue = "27812")]
232 /// Quote a `Span` into a `TokenStream`.
233 /// This is needed to implement a custom quoter.
234 #[unstable(feature = "proc_macro", issue = "38356")]
235 pub fn quote_span(span: Span) -> TokenStream {
236 quote::Quote::quote(span)
239 /// A region of source code, along with macro expansion information.
240 #[unstable(feature = "proc_macro", issue = "38356")]
241 #[derive(Copy, Clone)]
242 pub struct Span(syntax_pos::Span);
244 #[unstable(feature = "proc_macro", issue = "38356")]
245 impl !Send for Span {}
246 #[unstable(feature = "proc_macro", issue = "38356")]
247 impl !Sync for Span {}
249 macro_rules! diagnostic_method {
250 ($name:ident, $level:expr) => (
251 /// Create a new `Diagnostic` with the given `message` at the span
253 #[unstable(feature = "proc_macro", issue = "38356")]
254 pub fn $name<T: Into<String>>(self, message: T) -> Diagnostic {
255 Diagnostic::spanned(self, $level, message)
261 /// A span that resolves at the macro definition site.
262 #[unstable(feature = "proc_macro", issue = "38356")]
263 pub fn def_site() -> Span {
264 ::__internal::with_sess(|(_, mark)| {
265 let call_site = mark.expn_info().unwrap().call_site;
266 Span(call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark)))
270 /// The span of the invocation of the current procedural macro.
271 #[unstable(feature = "proc_macro", issue = "38356")]
272 pub fn call_site() -> Span {
273 ::__internal::with_sess(|(_, mark)| Span(mark.expn_info().unwrap().call_site))
276 /// The original source file into which this span points.
277 #[unstable(feature = "proc_macro", issue = "38356")]
278 pub fn source_file(&self) -> SourceFile {
280 filemap: __internal::lookup_char_pos(self.0.lo()).file,
284 /// The `Span` for the tokens in the previous macro expansion from which
285 /// `self` was generated from, if any.
286 #[unstable(feature = "proc_macro", issue = "38356")]
287 pub fn parent(&self) -> Option<Span> {
288 self.0.parent().map(Span)
291 /// The span for the origin source code that `self` was generated from. If
292 /// this `Span` wasn't generated from other macro expansions then the return
293 /// value is the same as `*self`.
294 #[unstable(feature = "proc_macro", issue = "38356")]
295 pub fn source(&self) -> Span {
296 Span(self.0.source_callsite())
299 /// Get the starting line/column in the source file for this span.
300 #[unstable(feature = "proc_macro", issue = "38356")]
301 pub fn start(&self) -> LineColumn {
302 let loc = __internal::lookup_char_pos(self.0.lo());
305 column: loc.col.to_usize()
309 /// Get the ending line/column in the source file for this span.
310 #[unstable(feature = "proc_macro", issue = "38356")]
311 pub fn end(&self) -> LineColumn {
312 let loc = __internal::lookup_char_pos(self.0.hi());
315 column: loc.col.to_usize()
319 /// Create a new span encompassing `self` and `other`.
321 /// Returns `None` if `self` and `other` are from different files.
322 #[unstable(feature = "proc_macro", issue = "38356")]
323 pub fn join(&self, other: Span) -> Option<Span> {
324 let self_loc = __internal::lookup_char_pos(self.0.lo());
325 let other_loc = __internal::lookup_char_pos(other.0.lo());
327 if self_loc.file.name != other_loc.file.name { return None }
329 Some(Span(self.0.to(other.0)))
332 /// Creates a new span with the same line/column information as `self` but
333 /// that resolves symbols as though it were at `other`.
334 #[unstable(feature = "proc_macro", issue = "38356")]
335 pub fn resolved_at(&self, other: Span) -> Span {
336 Span(self.0.with_ctxt(other.0.ctxt()))
339 /// Creates a new span with the same name resolution behavior as `self` but
340 /// with the line/column information of `other`.
341 #[unstable(feature = "proc_macro", issue = "38356")]
342 pub fn located_at(&self, other: Span) -> Span {
343 other.resolved_at(*self)
346 /// Compares to spans to see if they're equal.
347 #[unstable(feature = "proc_macro", issue = "38356")]
348 pub fn eq(&self, other: &Span) -> bool {
352 diagnostic_method!(error, Level::Error);
353 diagnostic_method!(warning, Level::Warning);
354 diagnostic_method!(note, Level::Note);
355 diagnostic_method!(help, Level::Help);
358 #[unstable(feature = "proc_macro", issue = "38356")]
359 impl fmt::Debug for Span {
360 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
361 write!(f, "{:?} bytes({}..{})",
368 /// A line-column pair representing the start or end of a `Span`.
369 #[unstable(feature = "proc_macro", issue = "38356")]
370 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
371 pub struct LineColumn {
372 /// The 1-indexed line in the source file on which the span starts or ends (inclusive).
373 #[unstable(feature = "proc_macro", issue = "38356")]
375 /// The 0-indexed column (in UTF-8 characters) in the source file on which
376 /// the span starts or ends (inclusive).
377 #[unstable(feature = "proc_macro", issue = "38356")]
381 #[unstable(feature = "proc_macro", issue = "38356")]
382 impl !Send for LineColumn {}
383 #[unstable(feature = "proc_macro", issue = "38356")]
384 impl !Sync for LineColumn {}
386 /// The source file of a given `Span`.
387 #[unstable(feature = "proc_macro", issue = "38356")]
389 pub struct SourceFile {
390 filemap: Lrc<FileMap>,
393 #[unstable(feature = "proc_macro", issue = "38356")]
394 impl !Send for SourceFile {}
395 #[unstable(feature = "proc_macro", issue = "38356")]
396 impl !Sync for SourceFile {}
399 /// Get the path to this source file.
402 /// If the code span associated with this `SourceFile` was generated by an external macro, this
403 /// may not be an actual path on the filesystem. Use [`is_real`] to check.
405 /// Also note that even if `is_real` returns `true`, if `--remap-path-prefix` was passed on
406 /// the command line, the path as given may not actually be valid.
408 /// [`is_real`]: #method.is_real
409 # [unstable(feature = "proc_macro", issue = "38356")]
410 pub fn path(&self) -> &FileName {
414 /// Returns `true` if this source file is a real source file, and not generated by an external
415 /// macro's expansion.
416 #[unstable(feature = "proc_macro", issue = "38356")]
417 pub fn is_real(&self) -> bool {
418 // This is a hack until intercrate spans are implemented and we can have real source files
419 // for spans generated in external macros.
420 // https://github.com/rust-lang/rust/pull/43604#issuecomment-333334368
421 self.filemap.is_real_file()
425 #[unstable(feature = "proc_macro", issue = "38356")]
426 impl AsRef<FileName> for SourceFile {
427 fn as_ref(&self) -> &FileName {
432 #[unstable(feature = "proc_macro", issue = "38356")]
433 impl fmt::Debug for SourceFile {
434 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
435 f.debug_struct("SourceFile")
436 .field("path", self.path())
437 .field("is_real", &self.is_real())
442 #[unstable(feature = "proc_macro", issue = "38356")]
443 impl PartialEq for SourceFile {
444 fn eq(&self, other: &Self) -> bool {
445 Lrc::ptr_eq(&self.filemap, &other.filemap)
449 #[unstable(feature = "proc_macro", issue = "38356")]
450 impl Eq for SourceFile {}
452 #[unstable(feature = "proc_macro", issue = "38356")]
453 impl PartialEq<FileName> for SourceFile {
454 fn eq(&self, other: &FileName) -> bool {
455 self.as_ref() == other
459 /// A single token or a delimited sequence of token trees (e.g. `[1, (), ..]`).
460 #[unstable(feature = "proc_macro", issue = "38356")]
463 /// A delimited tokenstream
465 /// A unicode identifier
467 /// A punctuation character (`+`, `,`, `$`, etc.).
469 /// A literal character (`'a'`), string (`"hello"`), number (`2.3`), etc.
473 #[unstable(feature = "proc_macro", issue = "38356")]
474 impl !Send for TokenTree {}
475 #[unstable(feature = "proc_macro", issue = "38356")]
476 impl !Sync for TokenTree {}
479 /// Returns the span of this token, accessing the `span` method of each of
480 /// the internal tokens.
481 #[unstable(feature = "proc_macro", issue = "38356")]
482 pub fn span(&self) -> Span {
484 TokenTree::Group(ref t) => t.span(),
485 TokenTree::Term(ref t) => t.span(),
486 TokenTree::Op(ref t) => t.span(),
487 TokenTree::Literal(ref t) => t.span(),
491 /// Configures the span for *only this token*.
493 /// Note that if this token is a `Group` then this method will not configure
494 /// the span of each of the internal tokens, this will simply delegate to
495 /// the `set_span` method of each variant.
496 #[unstable(feature = "proc_macro", issue = "38356")]
497 pub fn set_span(&mut self, span: Span) {
499 TokenTree::Group(ref mut t) => t.set_span(span),
500 TokenTree::Term(ref mut t) => t.set_span(span),
501 TokenTree::Op(ref mut t) => t.set_span(span),
502 TokenTree::Literal(ref mut t) => t.set_span(span),
507 #[unstable(feature = "proc_macro", issue = "38356")]
508 impl fmt::Debug for TokenTree {
509 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
510 // Each of these has the name in the struct type in the derived debug,
511 // so don't bother with an extra layer of indirection
513 TokenTree::Group(ref tt) => tt.fmt(f),
514 TokenTree::Term(ref tt) => tt.fmt(f),
515 TokenTree::Op(ref tt) => tt.fmt(f),
516 TokenTree::Literal(ref tt) => tt.fmt(f),
521 #[unstable(feature = "proc_macro", issue = "38356")]
522 impl From<Group> for TokenTree {
523 fn from(g: Group) -> TokenTree {
528 #[unstable(feature = "proc_macro", issue = "38356")]
529 impl From<Term> for TokenTree {
530 fn from(g: Term) -> TokenTree {
535 #[unstable(feature = "proc_macro", issue = "38356")]
536 impl From<Op> for TokenTree {
537 fn from(g: Op) -> TokenTree {
542 #[unstable(feature = "proc_macro", issue = "38356")]
543 impl From<Literal> for TokenTree {
544 fn from(g: Literal) -> TokenTree {
545 TokenTree::Literal(g)
549 #[unstable(feature = "proc_macro", issue = "38356")]
550 impl fmt::Display for TokenTree {
551 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
553 TokenTree::Group(ref t) => t.fmt(f),
554 TokenTree::Term(ref t) => t.fmt(f),
555 TokenTree::Op(ref t) => t.fmt(f),
556 TokenTree::Literal(ref t) => t.fmt(f),
561 /// A delimited token stream
563 /// A `Group` internally contains a `TokenStream` which is delimited by a
564 /// `Delimiter`. Groups represent multiple tokens internally and have a `Span`
565 /// for the entire stream.
566 #[derive(Clone, Debug)]
567 #[unstable(feature = "proc_macro", issue = "38356")]
569 delimiter: Delimiter,
574 #[unstable(feature = "proc_macro", issue = "38356")]
575 impl !Send for Group {}
576 #[unstable(feature = "proc_macro", issue = "38356")]
577 impl !Sync for Group {}
579 /// Describes how a sequence of token trees is delimited.
580 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
581 #[unstable(feature = "proc_macro", issue = "38356")]
589 /// An implicit delimiter, e.g. `$var`, where $var is `...`.
594 /// Creates a new `group` with the given delimiter and token stream.
596 /// This constructor will set the span for this group to
597 /// `Span::call_site()`. To change the span you can use the `set_span`
599 #[unstable(feature = "proc_macro", issue = "38356")]
600 pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
602 delimiter: delimiter,
604 span: Span::call_site(),
608 /// Returns the delimiter of this `Group`
609 #[unstable(feature = "proc_macro", issue = "38356")]
610 pub fn delimiter(&self) -> Delimiter {
614 /// Returns the `TokenStream` of tokens that are delimited in this `Group`.
616 /// Note that the returned token stream does not include the delimiter
618 #[unstable(feature = "proc_macro", issue = "38356")]
619 pub fn stream(&self) -> TokenStream {
623 /// Returns the span for the delimiters of this token stream, spanning the
625 #[unstable(feature = "proc_macro", issue = "38356")]
626 pub fn span(&self) -> Span {
630 /// Configures the span for this `Group`'s delimiters, but not its internal
633 /// This method will **not** set the span of all the internal tokens spanned
634 /// by this group, but rather it will only set the span of the delimiter
635 /// tokens at the level of the `Group`.
636 #[unstable(feature = "proc_macro", issue = "38356")]
637 pub fn set_span(&mut self, span: Span) {
642 #[unstable(feature = "proc_macro", issue = "38356")]
643 impl fmt::Display for Group {
644 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
645 TokenStream::from(TokenTree::from(self.clone())).fmt(f)
649 /// An `Op` is an operator like `+` or `-`, and only represents one character.
651 /// Operators like `+=` are represented as two instance of `Op` with different
652 /// forms of `Spacing` returned.
653 #[unstable(feature = "proc_macro", issue = "38356")]
654 #[derive(Copy, Clone, Debug)]
661 #[unstable(feature = "proc_macro", issue = "38356")]
663 #[unstable(feature = "proc_macro", issue = "38356")]
666 /// Whether an `Op` is either followed immediately by another `Op` or followed by whitespace.
667 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
668 #[unstable(feature = "proc_macro", issue = "38356")]
670 /// e.g. `+` is `Alone` in `+ =`.
672 /// e.g. `+` is `Joint` in `+=`.
677 /// Creates a new `Op` from the given character and spacing.
679 /// The returned `Op` will have the default span of `Span::call_site()`
680 /// which can be further configured with the `set_span` method below.
681 #[unstable(feature = "proc_macro", issue = "38356")]
682 pub fn new(op: char, spacing: Spacing) -> Op {
686 span: Span::call_site(),
690 /// Returns the character this operation represents, for example `'+'`
691 #[unstable(feature = "proc_macro", issue = "38356")]
692 pub fn op(&self) -> char {
696 /// Returns the spacing of this operator, indicating whether it's a joint
697 /// operator with more operators coming next in the token stream or an
698 /// `Alone` meaning that the operator has ended.
699 #[unstable(feature = "proc_macro", issue = "38356")]
700 pub fn spacing(&self) -> Spacing {
704 /// Returns the span for this operator character
705 #[unstable(feature = "proc_macro", issue = "38356")]
706 pub fn span(&self) -> Span {
710 /// Configure the span for this operator's character
711 #[unstable(feature = "proc_macro", issue = "38356")]
712 pub fn set_span(&mut self, span: Span) {
717 #[unstable(feature = "proc_macro", issue = "38356")]
718 impl fmt::Display for Op {
719 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
720 TokenStream::from(TokenTree::from(self.clone())).fmt(f)
724 /// An interned string.
725 #[derive(Copy, Clone, Debug)]
726 #[unstable(feature = "proc_macro", issue = "38356")]
732 #[unstable(feature = "proc_macro", issue = "38356")]
733 impl !Send for Term {}
734 #[unstable(feature = "proc_macro", issue = "38356")]
735 impl !Sync for Term {}
738 /// Creates a new `Term` with the given `string` as well as the specified
741 /// Note that `span`, currently in rustc, configures the hygiene information
742 /// for this identifier. As of this time `Span::call_site()` explicitly
743 /// opts-in to **non-hygienic** information (aka copy/pasted code) while
744 /// spans like `Span::def_site()` will opt-in to hygienic information,
745 /// meaning that code at the call site of the macro can't access this
748 /// Due to the current importance of hygiene this constructor, unlike other
749 /// tokens, requires a `Span` to be specified at construction.
750 #[unstable(feature = "proc_macro", issue = "38356")]
751 pub fn new(string: &str, span: Span) -> Term {
753 sym: Symbol::intern(string),
758 /// Get a reference to the interned string.
759 #[unstable(feature = "proc_macro", issue = "38356")]
760 pub fn as_str(&self) -> &str {
761 unsafe { &*(&*self.sym.as_str() as *const str) }
764 /// Returns the span of this `Term`, encompassing the entire string returned
766 #[unstable(feature = "proc_macro", issue = "38356")]
767 pub fn span(&self) -> Span {
771 /// Configures the span of this `Term`, possibly changing hygiene
773 #[unstable(feature = "proc_macro", issue = "38356")]
774 pub fn set_span(&mut self, span: Span) {
779 #[unstable(feature = "proc_macro", issue = "38356")]
780 impl fmt::Display for Term {
781 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
786 /// A literal character (`'a'`), string (`"hello"`), a number (`2.3`), etc.
787 #[derive(Clone, Debug)]
788 #[unstable(feature = "proc_macro", issue = "38356")]
791 suffix: Option<ast::Name>,
795 #[unstable(feature = "proc_macro", issue = "38356")]
796 impl !Send for Literal {}
797 #[unstable(feature = "proc_macro", issue = "38356")]
798 impl !Sync for Literal {}
800 macro_rules! suffixed_int_literals {
801 ($($name:ident => $kind:ident,)*) => ($(
802 /// Creates a new suffixed integer literal with the specified value.
804 /// This function will create an integer like `1u32` where the integer
805 /// value specified is the first part of the token and the integral is
806 /// also suffixed at the end.
808 /// Literals created through this method have the `Span::call_site()`
809 /// span by default, which can be configured with the `set_span` method
811 #[unstable(feature = "proc_macro", issue = "38356")]
812 pub fn $name(n: $kind) -> Literal {
814 lit: token::Lit::Integer(Symbol::intern(&n.to_string())),
815 suffix: Some(Symbol::intern(stringify!($kind))),
816 span: Span::call_site(),
822 macro_rules! unsuffixed_int_literals {
823 ($($name:ident => $kind:ident,)*) => ($(
824 /// Creates a new unsuffixed integer literal with the specified value.
826 /// This function will create an integer like `1` where the integer
827 /// value specified is the first part of the token. No suffix is
828 /// specified on this token, meaning that invocations like
829 /// `Literal::i8_unsuffixed(1)` are equivalent to
830 /// `Literal::u32_unsuffixed(1)`.
832 /// Literals created through this method have the `Span::call_site()`
833 /// span by default, which can be configured with the `set_span` method
835 #[unstable(feature = "proc_macro", issue = "38356")]
836 pub fn $name(n: $kind) -> Literal {
838 lit: token::Lit::Integer(Symbol::intern(&n.to_string())),
840 span: Span::call_site(),
847 suffixed_int_literals! {
852 u128_suffixed => u128,
853 usize_suffixed => usize,
858 i128_suffixed => i128,
859 isize_suffixed => isize,
862 unsuffixed_int_literals! {
864 u16_unsuffixed => u16,
865 u32_unsuffixed => u32,
866 u64_unsuffixed => u64,
867 u128_unsuffixed => u128,
868 usize_unsuffixed => usize,
870 i16_unsuffixed => i16,
871 i32_unsuffixed => i32,
872 i64_unsuffixed => i64,
873 i128_unsuffixed => i128,
874 isize_unsuffixed => isize,
877 /// Creates a new unsuffixed floating-point literal.
879 /// This constructor is similar to those like `Literal::i8_unsuffixed` where
880 /// the float's value is emitted directly into the token but no suffix is
881 /// used, so it may be inferred to be a `f64` later in the compiler.
885 /// This function requires that the specified float is finite, for
886 /// example if it is infinity or NaN this function will panic.
887 #[unstable(feature = "proc_macro", issue = "38356")]
888 pub fn f32_unsuffixed(n: f32) -> Literal {
890 panic!("Invalid float literal {}", n);
893 lit: token::Lit::Float(Symbol::intern(&n.to_string())),
895 span: Span::call_site(),
899 /// Creates a new suffixed floating-point literal.
901 /// This consturctor will create a literal like `1.0f32` where the value
902 /// specified is the preceding part of the token and `f32` is the suffix of
903 /// the token. This token will always be inferred to be an `f32` in the
908 /// This function requires that the specified float is finite, for
909 /// example if it is infinity or NaN this function will panic.
910 #[unstable(feature = "proc_macro", issue = "38356")]
911 pub fn f32_suffixed(n: f32) -> Literal {
913 panic!("Invalid float literal {}", n);
916 lit: token::Lit::Float(Symbol::intern(&n.to_string())),
917 suffix: Some(Symbol::intern("f32")),
918 span: Span::call_site(),
922 /// Creates a new unsuffixed floating-point literal.
924 /// This constructor is similar to those like `Literal::i8_unsuffixed` where
925 /// the float's value is emitted directly into the token but no suffix is
926 /// used, so it may be inferred to be a `f64` later in the compiler.
930 /// This function requires that the specified float is finite, for
931 /// example if it is infinity or NaN this function will panic.
932 #[unstable(feature = "proc_macro", issue = "38356")]
933 pub fn f64_unsuffixed(n: f64) -> Literal {
935 panic!("Invalid float literal {}", n);
938 lit: token::Lit::Float(Symbol::intern(&n.to_string())),
940 span: Span::call_site(),
944 /// Creates a new suffixed floating-point literal.
946 /// This consturctor will create a literal like `1.0f64` where the value
947 /// specified is the preceding part of the token and `f64` is the suffix of
948 /// the token. This token will always be inferred to be an `f64` in the
953 /// This function requires that the specified float is finite, for
954 /// example if it is infinity or NaN this function will panic.
955 #[unstable(feature = "proc_macro", issue = "38356")]
956 pub fn f64_suffixed(n: f64) -> Literal {
958 panic!("Invalid float literal {}", n);
961 lit: token::Lit::Float(Symbol::intern(&n.to_string())),
962 suffix: Some(Symbol::intern("f64")),
963 span: Span::call_site(),
968 #[unstable(feature = "proc_macro", issue = "38356")]
969 pub fn string(string: &str) -> Literal {
970 let mut escaped = String::new();
971 for ch in string.chars() {
972 escaped.extend(ch.escape_debug());
975 lit: token::Lit::Str_(Symbol::intern(&escaped)),
977 span: Span::call_site(),
981 /// Character literal.
982 #[unstable(feature = "proc_macro", issue = "38356")]
983 pub fn character(ch: char) -> Literal {
984 let mut escaped = String::new();
985 escaped.extend(ch.escape_unicode());
987 lit: token::Lit::Char(Symbol::intern(&escaped)),
989 span: Span::call_site(),
993 /// Byte string literal.
994 #[unstable(feature = "proc_macro", issue = "38356")]
995 pub fn byte_string(bytes: &[u8]) -> Literal {
996 let string = bytes.iter().cloned().flat_map(ascii::escape_default)
997 .map(Into::<char>::into).collect::<String>();
999 lit: token::Lit::ByteStr(Symbol::intern(&string)),
1001 span: Span::call_site(),
1005 /// Returns the span encompassing this literal.
1006 #[unstable(feature = "proc_macro", issue = "38356")]
1007 pub fn span(&self) -> Span {
1011 /// Configures the span associated for this literal.
1012 #[unstable(feature = "proc_macro", issue = "38356")]
1013 pub fn set_span(&mut self, span: Span) {
1018 #[unstable(feature = "proc_macro", issue = "38356")]
1019 impl fmt::Display for Literal {
1020 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1021 TokenStream::from(TokenTree::from(self.clone())).fmt(f)
1026 fn from_internal(delim: token::DelimToken) -> Delimiter {
1028 token::Paren => Delimiter::Parenthesis,
1029 token::Brace => Delimiter::Brace,
1030 token::Bracket => Delimiter::Bracket,
1031 token::NoDelim => Delimiter::None,
1035 fn to_internal(self) -> token::DelimToken {
1037 Delimiter::Parenthesis => token::Paren,
1038 Delimiter::Brace => token::Brace,
1039 Delimiter::Bracket => token::Bracket,
1040 Delimiter::None => token::NoDelim,
1046 fn from_internal(stream: tokenstream::TokenStream, stack: &mut Vec<TokenTree>)
1048 use syntax::parse::token::*;
1050 let (tree, is_joint) = stream.as_tree();
1051 let (span, token) = match tree {
1052 tokenstream::TokenTree::Token(span, token) => (span, token),
1053 tokenstream::TokenTree::Delimited(span, delimed) => {
1054 let delimiter = Delimiter::from_internal(delimed.delim);
1055 let mut g = Group::new(delimiter, TokenStream(delimed.tts.into()));
1056 g.set_span(Span(span));
1061 let op_kind = if is_joint { Spacing::Joint } else { Spacing::Alone };
1064 let mut x = TokenTree::from($e);
1065 x.set_span(Span(span));
1070 ($a:expr) => (tt!(Op::new($a, op_kind)));
1071 ($a:expr, $b:expr) => ({
1072 stack.push(tt!(Op::new($b, op_kind)));
1073 tt!(Op::new($a, Spacing::Joint))
1075 ($a:expr, $b:expr, $c:expr) => ({
1076 stack.push(tt!(Op::new($c, op_kind)));
1077 stack.push(tt!(Op::new($b, Spacing::Joint)));
1078 tt!(Op::new($a, Spacing::Joint))
1085 Le => op!('<', '='),
1086 EqEq => op!('=', '='),
1087 Ne => op!('!', '='),
1088 Ge => op!('>', '='),
1090 AndAnd => op!('&', '&'),
1091 OrOr => op!('|', '|'),
1094 BinOp(Plus) => op!('+'),
1095 BinOp(Minus) => op!('-'),
1096 BinOp(Star) => op!('*'),
1097 BinOp(Slash) => op!('/'),
1098 BinOp(Percent) => op!('%'),
1099 BinOp(Caret) => op!('^'),
1100 BinOp(And) => op!('&'),
1101 BinOp(Or) => op!('|'),
1102 BinOp(Shl) => op!('<', '<'),
1103 BinOp(Shr) => op!('>', '>'),
1104 BinOpEq(Plus) => op!('+', '='),
1105 BinOpEq(Minus) => op!('-', '='),
1106 BinOpEq(Star) => op!('*', '='),
1107 BinOpEq(Slash) => op!('/', '='),
1108 BinOpEq(Percent) => op!('%', '='),
1109 BinOpEq(Caret) => op!('^', '='),
1110 BinOpEq(And) => op!('&', '='),
1111 BinOpEq(Or) => op!('|', '='),
1112 BinOpEq(Shl) => op!('<', '<', '='),
1113 BinOpEq(Shr) => op!('>', '>', '='),
1116 DotDot => op!('.', '.'),
1117 DotDotDot => op!('.', '.', '.'),
1118 DotDotEq => op!('.', '.', '='),
1122 ModSep => op!(':', ':'),
1123 RArrow => op!('-', '>'),
1124 LArrow => op!('<', '-'),
1125 FatArrow => op!('=', '>'),
1128 Question => op!('?'),
1130 Ident(ident, false) | Lifetime(ident) => {
1131 tt!(Term::new(&ident.name.as_str(), Span(span)))
1133 Ident(ident, true) => {
1134 tt!(Term::new(&format!("r#{}", ident), Span(span)))
1136 Literal(lit, suffix) => tt!(self::Literal { lit, suffix, span: Span(span) }),
1138 let style = comments::doc_comment_style(&c.as_str());
1139 let stripped = comments::strip_doc_comment_decoration(&c.as_str());
1141 tt!(Term::new("doc", Span(span))),
1142 tt!(Op::new('=', Spacing::Alone)),
1143 tt!(self::Literal::string(&stripped)),
1144 ].into_iter().collect();
1145 stack.push(tt!(Group::new(Delimiter::Bracket, stream)));
1146 if style == ast::AttrStyle::Inner {
1147 stack.push(tt!(Op::new('!', Spacing::Alone)));
1149 tt!(Op::new('#', Spacing::Alone))
1152 Interpolated(_) => {
1153 __internal::with_sess(|(sess, _)| {
1154 let tts = token.interpolated_to_tokenstream(sess, span);
1155 tt!(Group::new(Delimiter::None, TokenStream(tts)))
1159 DotEq => op!('.', '='),
1160 OpenDelim(..) | CloseDelim(..) => unreachable!(),
1161 Whitespace | Comment | Shebang(..) | Eof => unreachable!(),
1165 fn to_internal(self) -> tokenstream::TokenStream {
1166 use syntax::parse::token::*;
1167 use syntax::tokenstream::{TokenTree, Delimited};
1169 let (op, kind, span) = match self {
1170 self::TokenTree::Op(tt) => (tt.op(), tt.spacing(), tt.span()),
1171 self::TokenTree::Group(tt) => {
1172 return TokenTree::Delimited(tt.span.0, Delimited {
1173 delim: tt.delimiter.to_internal(),
1174 tts: tt.stream.0.into(),
1177 self::TokenTree::Term(tt) => {
1178 let ident = ast::Ident::new(tt.sym, tt.span.0);
1179 let sym_str = tt.sym.as_str();
1180 let token = if sym_str.starts_with("'") {
1182 } else if sym_str.starts_with("r#") {
1183 let name = Symbol::intern(&sym_str[2..]);
1184 let ident = ast::Ident::new(name, ident.span);
1189 return TokenTree::Token(tt.span.0, token).into();
1191 self::TokenTree::Literal(self::Literal {
1192 lit: Lit::Integer(ref a),
1196 if a.as_str().starts_with("-") =>
1198 let minus = BinOp(BinOpToken::Minus);
1199 let integer = Symbol::intern(&a.as_str()[1..]);
1200 let integer = Literal(Lit::Integer(integer), suffix);
1201 let a = TokenTree::Token(span.0, minus);
1202 let b = TokenTree::Token(span.0, integer);
1203 return vec![a, b].into_iter().collect()
1205 self::TokenTree::Literal(self::Literal {
1206 lit: Lit::Float(ref a),
1210 if a.as_str().starts_with("-") =>
1212 let minus = BinOp(BinOpToken::Minus);
1213 let float = Symbol::intern(&a.as_str()[1..]);
1214 let float = Literal(Lit::Float(float), suffix);
1215 let a = TokenTree::Token(span.0, minus);
1216 let b = TokenTree::Token(span.0, float);
1217 return vec![a, b].into_iter().collect()
1219 self::TokenTree::Literal(tt) => {
1220 let token = Literal(tt.lit, tt.suffix);
1221 return TokenTree::Token(tt.span.0, token).into()
1225 let token = match op {
1232 '-' => BinOp(Minus),
1234 '/' => BinOp(Slash),
1235 '%' => BinOp(Percent),
1236 '^' => BinOp(Caret),
1247 _ => panic!("unsupported character {}", op),
1250 let tree = TokenTree::Token(span.0, token);
1252 Spacing::Alone => tree.into(),
1253 Spacing::Joint => tree.joint(),
1258 /// Permanently unstable internal implementation details of this crate. This
1259 /// should not be used.
1261 /// These methods are used by the rest of the compiler to generate instances of
1262 /// `TokenStream` to hand to macro definitions, as well as consume the output.
1264 /// Note that this module is also intentionally separate from the rest of the
1265 /// crate. This allows the `#[unstable]` directive below to naturally apply to
1266 /// all of the contents.
1267 #[unstable(feature = "proc_macro_internals", issue = "27812")]
1269 pub mod __internal {
1270 pub use quote::{LiteralKind, Quoter, unquote};
1272 use std::cell::Cell;
1275 use syntax::ext::base::ExtCtxt;
1276 use syntax::ext::hygiene::Mark;
1278 use syntax::parse::{self, ParseSess};
1279 use syntax::parse::token::{self, Token};
1280 use syntax::tokenstream;
1281 use syntax_pos::{BytePos, Loc, DUMMY_SP};
1283 use super::{TokenStream, LexError};
1285 pub fn lookup_char_pos(pos: BytePos) -> Loc {
1286 with_sess(|(sess, _)| sess.codemap().lookup_char_pos(pos))
1289 pub fn new_token_stream(item: P<ast::Item>) -> TokenStream {
1290 let token = Token::interpolated(token::NtItem(item));
1291 TokenStream(tokenstream::TokenTree::Token(DUMMY_SP, token).into())
1294 pub fn token_stream_wrap(inner: tokenstream::TokenStream) -> TokenStream {
1298 pub fn token_stream_parse_items(stream: TokenStream) -> Result<Vec<P<ast::Item>>, LexError> {
1299 with_sess(move |(sess, _)| {
1300 let mut parser = parse::stream_to_parser(sess, stream.0);
1301 let mut items = Vec::new();
1303 while let Some(item) = try!(parser.parse_item().map_err(super::parse_to_lex_err)) {
1311 pub fn token_stream_inner(stream: TokenStream) -> tokenstream::TokenStream {
1315 pub trait Registry {
1316 fn register_custom_derive(&mut self,
1318 expand: fn(TokenStream) -> TokenStream,
1319 attributes: &[&'static str]);
1321 fn register_attr_proc_macro(&mut self,
1323 expand: fn(TokenStream, TokenStream) -> TokenStream);
1325 fn register_bang_proc_macro(&mut self,
1327 expand: fn(TokenStream) -> TokenStream);
1330 // Emulate scoped_thread_local!() here essentially
1332 static CURRENT_SESS: Cell<(*const ParseSess, Mark)> =
1333 Cell::new((0 as *const _, Mark::root()));
1336 pub fn set_sess<F, R>(cx: &ExtCtxt, f: F) -> R
1337 where F: FnOnce() -> R
1339 struct Reset { prev: (*const ParseSess, Mark) }
1341 impl Drop for Reset {
1342 fn drop(&mut self) {
1343 CURRENT_SESS.with(|p| p.set(self.prev));
1347 CURRENT_SESS.with(|p| {
1348 let _reset = Reset { prev: p.get() };
1349 p.set((cx.parse_sess, cx.current_expansion.mark));
1354 pub fn in_sess() -> bool
1356 let p = CURRENT_SESS.with(|p| p.get());
1360 pub fn with_sess<F, R>(f: F) -> R
1361 where F: FnOnce((&ParseSess, Mark)) -> R
1363 let p = CURRENT_SESS.with(|p| p.get());
1364 assert!(!p.0.is_null(), "proc_macro::__internal::with_sess() called \
1365 before set_parse_sess()!");
1366 f(unsafe { (&*p.0, p.1) })
1370 fn parse_to_lex_err(mut err: DiagnosticBuilder) -> LexError {
1372 LexError { _inner: () }