]> git.lizzy.rs Git - rust.git/blob - src/libproc_macro/lib.rs
Rollup merge of #52769 - sinkuu:stray_test, r=alexcrichton
[rust.git] / src / libproc_macro / lib.rs
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.
4 //
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.
10
11 //! A support library for macro authors when defining new macros.
12 //!
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]`.
17 //!
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.
21 //!
22 //! See [the book](../book/first-edition/procedural-macros.html) for more.
23
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))))]
33
34 #![feature(rustc_private)]
35 #![feature(staged_api)]
36 #![feature(lang_items)]
37 #![feature(optin_builtin_traits)]
38
39 #![recursion_limit="256"]
40
41 extern crate syntax;
42 extern crate syntax_pos;
43 extern crate rustc_errors;
44 extern crate rustc_data_structures;
45
46 #[unstable(feature = "proc_macro_internals", issue = "27812")]
47 #[doc(hidden)]
48 pub mod rustc;
49
50 mod diagnostic;
51
52 #[unstable(feature = "proc_macro_diagnostic", issue = "38356")]
53 pub use diagnostic::{Diagnostic, Level};
54
55 use std::{ascii, fmt, iter};
56 use std::path::PathBuf;
57 use rustc_data_structures::sync::Lrc;
58 use std::str::FromStr;
59
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};
65
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.
70 ///
71 /// This is both the input and output of `#[proc_macro]`, `#[proc_macro_attribute]`
72 /// and `#[proc_macro_derive]` definitions.
73 ///
74 /// The API of this type is intentionally bare-bones, but it'll be expanded over
75 /// time!
76 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
77 #[derive(Clone)]
78 pub struct TokenStream(tokenstream::TokenStream);
79
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 {}
84
85 /// Error returned from `TokenStream::from_str`.
86 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
87 #[derive(Debug)]
88 pub struct LexError {
89     _inner: (),
90 }
91
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 {}
96
97 impl TokenStream {
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())
102     }
103
104     /// Checks if this `TokenStream` is empty.
105     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
106     pub fn is_empty(&self) -> bool {
107         self.0.is_empty()
108     }
109 }
110
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.
115 ///
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 {
120     type Err = LexError;
121
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)
126             )))
127         })
128     }
129 }
130
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 {
137         self.0.fmt(f)
138     }
139 }
140
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()
147     }
148 }
149
150 #[unstable(feature = "proc_macro_quote", issue = "38356")]
151 pub use quote::{quote, quote_span};
152
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())
158     }
159 }
160
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()
166     }
167 }
168
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);
177         }
178         TokenStream(builder.build())
179     }
180 }
181
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};
187
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.
191     #[derive(Clone)]
192     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
193     pub struct IntoIter {
194         cursor: tokenstream::Cursor,
195         stack: Vec<TokenTree>,
196     }
197
198     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
199     impl Iterator for IntoIter {
200         type Item = TokenTree;
201
202         fn next(&mut self) -> Option<TokenTree> {
203             loop {
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))
207                 })?;
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);
218                             continue
219                         }
220                     }
221                 }
222                 return Some(tree);
223             }
224         }
225     }
226
227     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
228     impl IntoIterator for TokenStream {
229         type Item = TokenTree;
230         type IntoIter = IntoIter;
231
232         fn into_iter(self) -> IntoIter {
233             IntoIter { cursor: self.0.trees(), stack: Vec::new() }
234         }
235     }
236 }
237
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")]`.
241 ///
242 /// Unquoting is done with `$`, and works by taking the single next ident as the unquoted term.
243 /// To quote `$` itself, use `$$`.
244 ///
245 /// This is a dummy macro, the actual implementation is in `quote::quote`.`
246 #[unstable(feature = "proc_macro_quote", issue = "38356")]
247 #[macro_export]
248 macro_rules! quote { () => {} }
249
250 #[unstable(feature = "proc_macro_internals", issue = "27812")]
251 #[doc(hidden)]
252 mod quote;
253
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);
258
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 {}
263
264 macro_rules! diagnostic_method {
265     ($name:ident, $level:expr) => (
266         /// Create a new `Diagnostic` with the given `message` at the span
267         /// `self`.
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)
271         }
272     )
273 }
274
275 impl Span {
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)
280     }
281
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)
289     }
290
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 {
294         SourceFile {
295             filemap: __internal::lookup_char_pos(self.0.lo()).file,
296         }
297     }
298
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)
304     }
305
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())
312     }
313
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());
318         LineColumn {
319             line: loc.line,
320             column: loc.col.to_usize()
321         }
322     }
323
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());
328         LineColumn {
329             line: loc.line,
330             column: loc.col.to_usize()
331         }
332     }
333
334     /// Create a new span encompassing `self` and `other`.
335     ///
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());
341
342         if self_loc.file.name != other_loc.file.name { return None }
343
344         Some(Span(self.0.to(other.0)))
345     }
346
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()))
352     }
353
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)
359     }
360
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 {
364         self.0 == other.0
365     }
366
367     diagnostic_method!(error, Level::Error);
368     diagnostic_method!(warning, Level::Warning);
369     diagnostic_method!(note, Level::Note);
370     diagnostic_method!(help, Level::Help);
371 }
372
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({}..{})",
378                self.0.ctxt(),
379                self.0.lo().0,
380                self.0.hi().0)
381     }
382 }
383
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")]
390     pub line: usize,
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")]
394     pub column: usize
395 }
396
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 {}
401
402 /// The source file of a given `Span`.
403 #[unstable(feature = "proc_macro_span", issue = "38356")]
404 #[derive(Clone)]
405 pub struct SourceFile {
406     filemap: Lrc<FileMap>,
407 }
408
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 {}
413
414 impl SourceFile {
415     /// Get the path to this source file.
416     ///
417     /// ### Note
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.
420     ///
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.
423     ///
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())
430         }
431     }
432
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()
441     }
442 }
443
444
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())
451             .finish()
452     }
453 }
454
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)
459     }
460 }
461
462 #[unstable(feature = "proc_macro_span", issue = "38356")]
463 impl Eq for SourceFile {}
464
465 /// A single token or a delimited sequence of token trees (e.g. `[1, (), ..]`).
466 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
467 #[derive(Clone)]
468 pub enum TokenTree {
469     /// A token stream surrounded by bracket delimiters.
470     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
471     Group(
472         #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
473         Group
474     ),
475     /// An identifier.
476     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
477     Ident(
478         #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
479         Ident
480     ),
481     /// A single punctuation character (`+`, `,`, `$`, etc.).
482     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
483     Punct(
484         #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
485         Punct
486     ),
487     /// A literal character (`'a'`), string (`"hello"`), number (`2.3`), etc.
488     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
489     Literal(
490         #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
491         Literal
492     ),
493 }
494
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 {}
499
500 impl 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 {
505         match *self {
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(),
510         }
511     }
512
513     /// Configures the span for *only this token*.
514     ///
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) {
520         match *self {
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),
525         }
526     }
527 }
528
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
535         match *self {
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),
540         }
541     }
542 }
543
544 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
545 impl From<Group> for TokenTree {
546     fn from(g: Group) -> TokenTree {
547         TokenTree::Group(g)
548     }
549 }
550
551 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
552 impl From<Ident> for TokenTree {
553     fn from(g: Ident) -> TokenTree {
554         TokenTree::Ident(g)
555     }
556 }
557
558 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
559 impl From<Punct> for TokenTree {
560     fn from(g: Punct) -> TokenTree {
561         TokenTree::Punct(g)
562     }
563 }
564
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)
569     }
570 }
571
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 {
578         match *self {
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),
583         }
584     }
585 }
586
587 /// A delimited token stream.
588 ///
589 /// A `Group` internally contains a `TokenStream` which is surrounded by `Delimiter`s.
590 #[derive(Clone)]
591 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
592 pub struct Group {
593     delimiter: Delimiter,
594     stream: TokenStream,
595     span: Span,
596 }
597
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 {}
602
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")]
606 pub enum Delimiter {
607     /// `( ... )`
608     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
609     Parenthesis,
610     /// `{ ... }`
611     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
612     Brace,
613     /// `[ ... ]`
614     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
615     Bracket,
616     /// `Ø ... Ã˜`
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")]
622     None,
623 }
624
625 impl Group {
626     /// Creates a new `Group` with the given delimiter and token stream.
627     ///
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`
630     /// method below.
631     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
632     pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
633         Group {
634             delimiter: delimiter,
635             stream: stream,
636             span: Span::call_site(),
637         }
638     }
639
640     /// Returns the delimiter of this `Group`
641     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
642     pub fn delimiter(&self) -> Delimiter {
643         self.delimiter
644     }
645
646     /// Returns the `TokenStream` of tokens that are delimited in this `Group`.
647     ///
648     /// Note that the returned token stream does not include the delimiter
649     /// returned above.
650     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
651     pub fn stream(&self) -> TokenStream {
652         self.stream.clone()
653     }
654
655     /// Returns the span for the delimiters of this token stream, spanning the
656     /// entire `Group`.
657     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
658     pub fn span(&self) -> Span {
659         self.span
660     }
661
662     /// Configures the span for this `Group`'s delimiters, but not its internal
663     /// tokens.
664     ///
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) {
670         self.span = span;
671     }
672 }
673
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)
681     }
682 }
683
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())
691             .finish()
692     }
693 }
694
695 /// An `Punct` is an single punctuation character like `+`, `-` or `#`.
696 ///
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")]
700 #[derive(Clone)]
701 pub struct Punct {
702     ch: char,
703     spacing: Spacing,
704     span: Span,
705 }
706
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 {}
711
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")]
716 pub enum Spacing {
717     /// E.g. `+` is `Alone` in `+ =`, `+ident` or `+()`.
718     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
719     Alone,
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")]
723     Joint,
724 }
725
726 impl Punct {
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.
730     ///
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)
739         }
740         Punct {
741             ch: ch,
742             spacing: spacing,
743             span: Span::call_site(),
744         }
745     }
746
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 {
750         self.ch
751     }
752
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 {
759         self.spacing
760     }
761
762     /// Returns the span for this punctuation character.
763     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
764     pub fn span(&self) -> Span {
765         self.span
766     }
767
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) {
771         self.span = span;
772     }
773 }
774
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)
781     }
782 }
783
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())
791             .finish()
792     }
793 }
794
795 /// An identifier (`ident`).
796 #[derive(Clone)]
797 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
798 pub struct Ident {
799     sym: Symbol,
800     span: Span,
801     is_raw: bool,
802 }
803
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 {}
808
809 impl 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())
815         } else {
816             false
817         }
818     }
819
820     /// Creates a new `Ident` with the given `string` as well as the specified
821     /// `span`.
822     /// The `string` argument must be a valid identifier permitted by the
823     /// language, otherwise the function will panic.
824     ///
825     /// Note that `span`, currently in rustc, configures the hygiene information
826     /// for this identifier.
827     ///
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.
832     ///
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.
836     ///
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)
843         }
844         Ident::new_maybe_raw(string, span, false)
845     }
846
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)
852         }
853         Ident::new_maybe_raw(string, span, true)
854     }
855
856     /// Returns the span of this `Ident`, encompassing the entire string returned
857     /// by `as_str`.
858     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
859     pub fn span(&self) -> Span {
860         self.span
861     }
862
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) {
866         self.span = span;
867     }
868 }
869
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)
876     }
877 }
878
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())
885             .finish()
886     }
887 }
888
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")]
896 pub struct Literal {
897     lit: token::Lit,
898     suffix: Option<Symbol>,
899     span: Span,
900 }
901
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 {}
906
907 macro_rules! suffixed_int_literals {
908     ($($name:ident => $kind:ident,)*) => ($(
909         /// Creates a new suffixed integer literal with the specified value.
910         ///
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).
916         ///
917         /// Literals created through this method have the `Span::call_site()`
918         /// span by default, which can be configured with the `set_span` method
919         /// below.
920         #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
921         pub fn $name(n: $kind) -> Literal {
922             Literal {
923                 lit: token::Lit::Integer(Symbol::intern(&n.to_string())),
924                 suffix: Some(Symbol::intern(stringify!($kind))),
925                 span: Span::call_site(),
926             }
927         }
928     )*)
929 }
930
931 macro_rules! unsuffixed_int_literals {
932     ($($name:ident => $kind:ident,)*) => ($(
933         /// Creates a new unsuffixed integer literal with the specified value.
934         ///
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).
942         ///
943         /// Literals created through this method have the `Span::call_site()`
944         /// span by default, which can be configured with the `set_span` method
945         /// below.
946         #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
947         pub fn $name(n: $kind) -> Literal {
948             Literal {
949                 lit: token::Lit::Integer(Symbol::intern(&n.to_string())),
950                 suffix: None,
951                 span: Span::call_site(),
952             }
953         }
954     )*)
955 }
956
957 impl Literal {
958     suffixed_int_literals! {
959         u8_suffixed => u8,
960         u16_suffixed => u16,
961         u32_suffixed => u32,
962         u64_suffixed => u64,
963         u128_suffixed => u128,
964         usize_suffixed => usize,
965         i8_suffixed => i8,
966         i16_suffixed => i16,
967         i32_suffixed => i32,
968         i64_suffixed => i64,
969         i128_suffixed => i128,
970         isize_suffixed => isize,
971     }
972
973     unsuffixed_int_literals! {
974         u8_unsuffixed => u8,
975         u16_unsuffixed => u16,
976         u32_unsuffixed => u32,
977         u64_unsuffixed => u64,
978         u128_unsuffixed => u128,
979         usize_unsuffixed => usize,
980         i8_unsuffixed => i8,
981         i16_unsuffixed => i16,
982         i32_unsuffixed => i32,
983         i64_unsuffixed => i64,
984         i128_unsuffixed => i128,
985         isize_unsuffixed => isize,
986     }
987
988     /// Creates a new unsuffixed floating-point literal.
989     ///
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).
995     ///
996     /// # Panics
997     ///
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 {
1002         if !n.is_finite() {
1003             panic!("Invalid float literal {}", n);
1004         }
1005         Literal {
1006             lit: token::Lit::Float(Symbol::intern(&n.to_string())),
1007             suffix: None,
1008             span: Span::call_site(),
1009         }
1010     }
1011
1012     /// Creates a new suffixed floating-point literal.
1013     ///
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
1017     /// compiler.
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).
1020     ///
1021     /// # Panics
1022     ///
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 {
1027         if !n.is_finite() {
1028             panic!("Invalid float literal {}", n);
1029         }
1030         Literal {
1031             lit: token::Lit::Float(Symbol::intern(&n.to_string())),
1032             suffix: Some(Symbol::intern("f32")),
1033             span: Span::call_site(),
1034         }
1035     }
1036
1037     /// Creates a new unsuffixed floating-point literal.
1038     ///
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).
1044     ///
1045     /// # Panics
1046     ///
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 {
1051         if !n.is_finite() {
1052             panic!("Invalid float literal {}", n);
1053         }
1054         Literal {
1055             lit: token::Lit::Float(Symbol::intern(&n.to_string())),
1056             suffix: None,
1057             span: Span::call_site(),
1058         }
1059     }
1060
1061     /// Creates a new suffixed floating-point literal.
1062     ///
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
1066     /// compiler.
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).
1069     ///
1070     /// # Panics
1071     ///
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 {
1076         if !n.is_finite() {
1077             panic!("Invalid float literal {}", n);
1078         }
1079         Literal {
1080             lit: token::Lit::Float(Symbol::intern(&n.to_string())),
1081             suffix: Some(Symbol::intern("f64")),
1082             span: Span::call_site(),
1083         }
1084     }
1085
1086     /// String literal.
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());
1092         }
1093         Literal {
1094             lit: token::Lit::Str_(Symbol::intern(&escaped)),
1095             suffix: None,
1096             span: Span::call_site(),
1097         }
1098     }
1099
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());
1105         Literal {
1106             lit: token::Lit::Char(Symbol::intern(&escaped)),
1107             suffix: None,
1108             span: Span::call_site(),
1109         }
1110     }
1111
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>();
1117         Literal {
1118             lit: token::Lit::ByteStr(Symbol::intern(&string)),
1119             suffix: None,
1120             span: Span::call_site(),
1121         }
1122     }
1123
1124     /// Returns the span encompassing this literal.
1125     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
1126     pub fn span(&self) -> Span {
1127         self.span
1128     }
1129
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) {
1133         self.span = span;
1134     }
1135 }
1136
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)
1143     }
1144 }
1145
1146 /// Permanently unstable internal implementation details of this crate. This
1147 /// should not be used.
1148 ///
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.
1151 ///
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")]
1156 #[doc(hidden)]
1157 pub mod __internal {
1158     use std::cell::Cell;
1159     use std::ptr;
1160
1161     use syntax::ast;
1162     use syntax::ext::base::ExtCtxt;
1163     use syntax::ptr::P;
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};
1169
1170     use super::{TokenStream, LexError, Span};
1171
1172     pub fn lookup_char_pos(pos: BytePos) -> Loc {
1173         with_sess(|sess, _| sess.codemap().lookup_char_pos(pos))
1174     }
1175
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())
1179     }
1180
1181     pub fn token_stream_wrap(inner: tokenstream::TokenStream) -> TokenStream {
1182         TokenStream(inner)
1183     }
1184
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();
1189
1190             while let Some(item) = try!(parser.parse_item().map_err(super::parse_to_lex_err)) {
1191                 items.push(item)
1192             }
1193
1194             Ok(items)
1195         })
1196     }
1197
1198     pub fn token_stream_inner(stream: TokenStream) -> tokenstream::TokenStream {
1199         stream.0
1200     }
1201
1202     pub trait Registry {
1203         fn register_custom_derive(&mut self,
1204                                   trait_name: &str,
1205                                   expand: fn(TokenStream) -> TokenStream,
1206                                   attributes: &[&'static str]);
1207
1208         fn register_attr_proc_macro(&mut self,
1209                                     name: &str,
1210                                     expand: fn(TokenStream, TokenStream) -> TokenStream);
1211
1212         fn register_bang_proc_macro(&mut self,
1213                                     name: &str,
1214                                     expand: fn(TokenStream) -> TokenStream);
1215     }
1216
1217     #[derive(Clone, Copy)]
1218     pub struct ProcMacroData {
1219         pub def_site: Span,
1220         pub call_site: Span,
1221     }
1222
1223     #[derive(Clone, Copy)]
1224     struct ProcMacroSess {
1225         parse_sess: *const ParseSess,
1226         data: ProcMacroData,
1227     }
1228
1229     // Emulate scoped_thread_local!() here essentially
1230     thread_local! {
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) },
1234         });
1235     }
1236
1237     pub fn set_sess<F, R>(cx: &ExtCtxt, f: F) -> R
1238         where F: FnOnce() -> R
1239     {
1240         struct Reset { prev: ProcMacroSess }
1241
1242         impl Drop for Reset {
1243             fn drop(&mut self) {
1244                 CURRENT_SESS.with(|p| p.set(self.prev));
1245             }
1246         }
1247
1248         CURRENT_SESS.with(|p| {
1249             let _reset = Reset { prev: p.get() };
1250
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,
1255                                                                     transparency))
1256             );
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),
1262                 },
1263             });
1264             f()
1265         })
1266     }
1267
1268     pub fn in_sess() -> bool
1269     {
1270         !CURRENT_SESS.with(|sess| sess.get()).parse_sess.is_null()
1271     }
1272
1273     pub fn with_sess<F, R>(f: F) -> R
1274         where F: FnOnce(&ParseSess, &ProcMacroData) -> R
1275     {
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");
1279         }
1280         f(unsafe { &*sess.parse_sess }, &sess.data)
1281     }
1282 }
1283
1284 fn parse_to_lex_err(mut err: DiagnosticBuilder) -> LexError {
1285     err.cancel();
1286     LexError { _inner: () }
1287 }