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