]> git.lizzy.rs Git - rust.git/blobdiff - src/libproc_macro/lib.rs
Various minor/cosmetic improvements to code
[rust.git] / src / libproc_macro / lib.rs
index 60b6a8bac41d399c59b21b9847333eb154394970..f2b85832dac31759d455051f09a42cefc5f35b39 100644 (file)
        test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]
 
 #![feature(nll)]
-#![feature(rustc_private)]
 #![feature(staged_api)]
-#![feature(lang_items)]
+#![feature(const_fn)]
+#![feature(extern_types)]
+#![feature(in_band_lifetimes)]
 #![feature(optin_builtin_traits)]
 #![feature(non_exhaustive)]
+#![feature(specialization)]
 
 #![recursion_limit="256"]
 
-extern crate syntax;
-extern crate syntax_pos;
-extern crate rustc_errors;
-extern crate rustc_data_structures;
-
 #[unstable(feature = "proc_macro_internals", issue = "27812")]
 #[doc(hidden)]
-pub mod rustc;
+pub mod bridge;
 
 mod diagnostic;
 
 #[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
 pub use diagnostic::{Diagnostic, Level, MultiSpan};
 
-use std::{ascii, fmt, iter};
+use std::{fmt, iter, mem};
+use std::ops::{Bound, RangeBounds};
 use std::path::PathBuf;
-use rustc_data_structures::sync::Lrc;
 use std::str::FromStr;
 
-use syntax::errors::DiagnosticBuilder;
-use syntax::parse::{self, token};
-use syntax::symbol::Symbol;
-use syntax::tokenstream::{self, DelimSpan};
-use syntax_pos::{Pos, FileName};
-
 /// The main type provided by this crate, representing an abstract stream of
 /// tokens, or, more specifically, a sequence of token trees.
 /// The type provide interfaces for iterating over those token trees and, conversely,
@@ -70,7 +61,7 @@
 /// and `#[proc_macro_derive]` definitions.
 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
 #[derive(Clone)]
-pub struct TokenStream(tokenstream::TokenStream);
+pub struct TokenStream(bridge::client::TokenStream);
 
 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
 impl !Send for TokenStream {}
@@ -93,7 +84,7 @@ impl TokenStream {
     /// Returns an empty `TokenStream` containing no token trees.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn new() -> TokenStream {
-        TokenStream(tokenstream::TokenStream::empty())
+        TokenStream(bridge::client::TokenStream::new())
     }
 
     /// Checks if this `TokenStream` is empty.
@@ -115,11 +106,16 @@ impl FromStr for TokenStream {
     type Err = LexError;
 
     fn from_str(src: &str) -> Result<TokenStream, LexError> {
-        __internal::with_sess(|sess, data| {
-            Ok(__internal::token_stream_wrap(parse::parse_stream_from_source_str(
-                FileName::ProcMacroSourceCode, src.to_string(), sess, Some(data.call_site.0)
-            )))
-        })
+        Ok(TokenStream(bridge::client::TokenStream::from_str(src)))
+    }
+}
+
+// N.B., the bridge only provides `to_string`, implement `fmt::Display`
+// based on it (the reverse of the usual relationship between the two).
+#[stable(feature = "proc_macro_lib", since = "1.15.0")]
+impl ToString for TokenStream {
+    fn to_string(&self) -> String {
+        self.0.to_string()
     }
 }
 
@@ -129,7 +125,7 @@ fn from_str(src: &str) -> Result<TokenStream, LexError> {
 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
 impl fmt::Display for TokenStream {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.0.fmt(f)
+        f.write_str(&self.to_string())
     }
 }
 
@@ -149,7 +145,12 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl From<TokenTree> for TokenStream {
     fn from(tree: TokenTree) -> TokenStream {
-        TokenStream(tree.to_internal())
+        TokenStream(bridge::client::TokenStream::from_token_tree(match tree {
+            TokenTree::Group(tt) => bridge::TokenTree::Group(tt.0),
+            TokenTree::Punct(tt) => bridge::TokenTree::Punct(tt.0),
+            TokenTree::Ident(tt) => bridge::TokenTree::Ident(tt.0),
+            TokenTree::Literal(tt) => bridge::TokenTree::Literal(tt.0)
+        }))
     }
 }
 
@@ -166,7 +167,7 @@ fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
 #[stable(feature = "proc_macro_lib", since = "1.15.0")]
 impl iter::FromIterator<TokenStream> for TokenStream {
     fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
-        let mut builder = tokenstream::TokenStreamBuilder::new();
+        let mut builder = bridge::client::TokenStreamBuilder::new();
         for stream in streams {
             builder.push(stream.0);
         }
@@ -184,52 +185,34 @@ fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, trees: I) {
 #[stable(feature = "token_stream_extend", since = "1.30.0")]
 impl Extend<TokenStream> for TokenStream {
     fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
-        self.0.extend(streams.into_iter().map(|stream| stream.0));
+        // FIXME(eddyb) Use an optimized implementation if/when possible.
+        *self = iter::once(mem::replace(self, Self::new())).chain(streams).collect();
     }
 }
 
 /// Public implementation details for the `TokenStream` type, such as iterators.
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 pub mod token_stream {
-    use syntax::tokenstream;
-    use {TokenTree, TokenStream, Delimiter};
+    use {bridge, Group, Ident, Literal, Punct, TokenTree, TokenStream};
 
     /// An iterator over `TokenStream`'s `TokenTree`s.
-    /// The iteration is "shallow", e.g. the iterator doesn't recurse into delimited groups,
+    /// The iteration is "shallow", e.g., the iterator doesn't recurse into delimited groups,
     /// and returns whole groups as token trees.
     #[derive(Clone)]
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-    pub struct IntoIter {
-        cursor: tokenstream::Cursor,
-        stack: Vec<TokenTree>,
-    }
+    pub struct IntoIter(bridge::client::TokenStreamIter);
 
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     impl Iterator for IntoIter {
         type Item = TokenTree;
 
         fn next(&mut self) -> Option<TokenTree> {
-            loop {
-                let tree = self.stack.pop().or_else(|| {
-                    let next = self.cursor.next_as_stream()?;
-                    Some(TokenTree::from_internal(next, &mut self.stack))
-                })?;
-                // HACK: The condition "dummy span + group with empty delimiter" represents an AST
-                // fragment approximately converted into a token stream. This may happen, for
-                // example, with inputs to proc macro attributes, including derives. Such "groups"
-                // need to flattened during iteration over stream's token trees.
-                // Eventually this needs to be removed in favor of keeping original token trees
-                // and not doing the roundtrip through AST.
-                if tree.span().0.is_dummy() {
-                    if let TokenTree::Group(ref group) = tree {
-                        if group.delimiter() == Delimiter::None {
-                            self.cursor.insert(group.stream.clone().0);
-                            continue
-                        }
-                    }
-                }
-                return Some(tree);
-            }
+            self.0.next().map(|tree| match tree {
+                bridge::TokenTree::Group(tt) => TokenTree::Group(Group(tt)),
+                bridge::TokenTree::Punct(tt) => TokenTree::Punct(Punct(tt)),
+                bridge::TokenTree::Ident(tt) => TokenTree::Ident(Ident(tt)),
+                bridge::TokenTree::Literal(tt) => TokenTree::Literal(Literal(tt)),
+            })
         }
     }
 
@@ -239,7 +222,7 @@ impl IntoIterator for TokenStream {
         type IntoIter = IntoIter;
 
         fn into_iter(self) -> IntoIter {
-            IntoIter { cursor: self.0.trees(), stack: Vec::new() }
+            IntoIter(self.0.into_iter())
         }
     }
 }
@@ -263,7 +246,7 @@ macro_rules! quote { () => {} }
 /// A region of source code, along with macro expansion information.
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 #[derive(Copy, Clone)]
-pub struct Span(syntax_pos::Span);
+pub struct Span(bridge::client::Span);
 
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl !Send for Span {}
@@ -285,7 +268,7 @@ impl Span {
     /// A span that resolves at the macro definition site.
     #[unstable(feature = "proc_macro_def_site", issue = "54724")]
     pub fn def_site() -> Span {
-        ::__internal::with_sess(|_, data| data.def_site)
+        Span(bridge::client::Span::def_site())
     }
 
     /// The span of the invocation of the current procedural macro.
@@ -294,15 +277,13 @@ pub fn def_site() -> Span {
     /// at the macro call site will be able to refer to them as well.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn call_site() -> Span {
-        ::__internal::with_sess(|_, data| data.call_site)
+        Span(bridge::client::Span::call_site())
     }
 
     /// The original source file into which this span points.
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn source_file(&self) -> SourceFile {
-        SourceFile {
-            source_file: __internal::lookup_char_pos(self.0.lo()).file,
-        }
+        SourceFile(self.0.source_file())
     }
 
     /// The `Span` for the tokens in the previous macro expansion from which
@@ -317,27 +298,19 @@ pub fn parent(&self) -> Option<Span> {
     /// value is the same as `*self`.
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn source(&self) -> Span {
-        Span(self.0.source_callsite())
+        Span(self.0.source())
     }
 
     /// Get the starting line/column in the source file for this span.
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn start(&self) -> LineColumn {
-        let loc = __internal::lookup_char_pos(self.0.lo());
-        LineColumn {
-            line: loc.line,
-            column: loc.col.to_usize()
-        }
+        self.0.start()
     }
 
     /// Get the ending line/column in the source file for this span.
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn end(&self) -> LineColumn {
-        let loc = __internal::lookup_char_pos(self.0.hi());
-        LineColumn {
-            line: loc.line,
-            column: loc.col.to_usize()
-        }
+        self.0.end()
     }
 
     /// Create a new span encompassing `self` and `other`.
@@ -345,19 +318,14 @@ pub fn end(&self) -> LineColumn {
     /// Returns `None` if `self` and `other` are from different files.
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn join(&self, other: Span) -> Option<Span> {
-        let self_loc = __internal::lookup_char_pos(self.0.lo());
-        let other_loc = __internal::lookup_char_pos(other.0.lo());
-
-        if self_loc.file.name != other_loc.file.name { return None }
-
-        Some(Span(self.0.to(other.0)))
+        self.0.join(other.0).map(Span)
     }
 
     /// Creates a new span with the same line/column information as `self` but
     /// that resolves symbols as though it were at `other`.
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn resolved_at(&self, other: Span) -> Span {
-        Span(self.0.with_ctxt(other.0.ctxt()))
+        Span(self.0.resolved_at(other.0))
     }
 
     /// Creates a new span with the same name resolution behavior as `self` but
@@ -383,10 +351,7 @@ pub fn eq(&self, other: &Span) -> bool {
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl fmt::Debug for Span {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{:?} bytes({}..{})",
-               self.0.ctxt(),
-               self.0.lo().0,
-               self.0.hi().0)
+        self.0.fmt(f)
     }
 }
 
@@ -411,14 +376,7 @@ impl !Sync for LineColumn {}
 /// The source file of a given `Span`.
 #[unstable(feature = "proc_macro_span", issue = "54725")]
 #[derive(Clone)]
-pub struct SourceFile {
-    source_file: Lrc<syntax_pos::SourceFile>,
-}
-
-#[unstable(feature = "proc_macro_span", issue = "54725")]
-impl !Send for SourceFile {}
-#[unstable(feature = "proc_macro_span", issue = "54725")]
-impl !Sync for SourceFile {}
+pub struct SourceFile(bridge::client::SourceFile);
 
 impl SourceFile {
     /// Get the path to this source file.
@@ -433,10 +391,7 @@ impl SourceFile {
     /// [`is_real`]: #method.is_real
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn path(&self) -> PathBuf {
-        match self.source_file.name {
-            FileName::Real(ref path) => path.clone(),
-            _ => PathBuf::from(self.source_file.name.to_string())
-        }
+        PathBuf::from(self.0.path())
     }
 
     /// Returns `true` if this source file is a real source file, and not generated by an external
@@ -446,7 +401,7 @@ pub fn is_real(&self) -> bool {
         // This is a hack until intercrate spans are implemented and we can have real source files
         // for spans generated in external macros.
         // https://github.com/rust-lang/rust/pull/43604#issuecomment-333334368
-        self.source_file.is_real_file()
+        self.0.is_real()
     }
 }
 
@@ -464,14 +419,14 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 #[unstable(feature = "proc_macro_span", issue = "54725")]
 impl PartialEq for SourceFile {
     fn eq(&self, other: &Self) -> bool {
-        Lrc::ptr_eq(&self.source_file, &other.source_file)
+        self.0.eq(&other.0)
     }
 }
 
 #[unstable(feature = "proc_macro_span", issue = "54725")]
 impl Eq for SourceFile {}
 
-/// A single token or a delimited sequence of token trees (e.g. `[1, (), ..]`).
+/// A single token or a delimited sequence of token trees (e.g., `[1, (), ..]`).
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 #[derive(Clone)]
 pub enum TokenTree {
@@ -578,18 +533,27 @@ fn from(g: Literal) -> TokenTree {
     }
 }
 
+// N.B., the bridge only provides `to_string`, implement `fmt::Display`
+// based on it (the reverse of the usual relationship between the two).
+#[stable(feature = "proc_macro_lib", since = "1.15.0")]
+impl ToString for TokenTree {
+    fn to_string(&self) -> String {
+        match *self {
+            TokenTree::Group(ref t) => t.to_string(),
+            TokenTree::Ident(ref t) => t.to_string(),
+            TokenTree::Punct(ref t) => t.to_string(),
+            TokenTree::Literal(ref t) => t.to_string(),
+        }
+    }
+}
+
 /// Prints the token tree as a string that is supposed to be losslessly convertible back
 /// into the same token tree (modulo spans), except for possibly `TokenTree::Group`s
 /// with `Delimiter::None` delimiters and negative numeric literals.
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl fmt::Display for TokenTree {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            TokenTree::Group(ref t) => t.fmt(f),
-            TokenTree::Ident(ref t) => t.fmt(f),
-            TokenTree::Punct(ref t) => t.fmt(f),
-            TokenTree::Literal(ref t) => t.fmt(f),
-        }
+        f.write_str(&self.to_string())
     }
 }
 
@@ -598,11 +562,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 /// A `Group` internally contains a `TokenStream` which is surrounded by `Delimiter`s.
 #[derive(Clone)]
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-pub struct Group {
-    delimiter: Delimiter,
-    stream: TokenStream,
-    span: DelimSpan,
-}
+pub struct Group(bridge::client::Group);
 
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl !Send for Group {}
@@ -639,17 +599,13 @@ impl Group {
     /// method below.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
-        Group {
-            delimiter: delimiter,
-            stream: stream,
-            span: DelimSpan::from_single(Span::call_site().0),
-        }
+        Group(bridge::client::Group::new(delimiter, stream.0))
     }
 
     /// Returns the delimiter of this `Group`
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn delimiter(&self) -> Delimiter {
-        self.delimiter
+        self.0.delimiter()
     }
 
     /// Returns the `TokenStream` of tokens that are delimited in this `Group`.
@@ -658,7 +614,7 @@ pub fn delimiter(&self) -> Delimiter {
     /// returned above.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn stream(&self) -> TokenStream {
-        self.stream.clone()
+        TokenStream(self.0.stream())
     }
 
     /// Returns the span for the delimiters of this token stream, spanning the
@@ -670,7 +626,7 @@ pub fn stream(&self) -> TokenStream {
     /// ```
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn span(&self) -> Span {
-        Span(self.span.entire())
+        Span(self.0.span())
     }
 
     /// Returns the span pointing to the opening delimiter of this group.
@@ -681,7 +637,7 @@ pub fn span(&self) -> Span {
     /// ```
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn span_open(&self) -> Span {
-        Span(self.span.open)
+        Span(self.0.span_open())
     }
 
     /// Returns the span pointing to the closing delimiter of this group.
@@ -692,7 +648,7 @@ pub fn span_open(&self) -> Span {
     /// ```
     #[unstable(feature = "proc_macro_span", issue = "54725")]
     pub fn span_close(&self) -> Span {
-        Span(self.span.close)
+        Span(self.0.span_close())
     }
 
     /// Configures the span for this `Group`'s delimiters, but not its internal
@@ -703,7 +659,16 @@ pub fn span_close(&self) -> Span {
     /// tokens at the level of the `Group`.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn set_span(&mut self, span: Span) {
-        self.span = DelimSpan::from_single(span.0);
+        self.0.set_span(span.0);
+    }
+}
+
+// N.B., the bridge only provides `to_string`, implement `fmt::Display`
+// based on it (the reverse of the usual relationship between the two).
+#[stable(feature = "proc_macro_lib", since = "1.15.0")]
+impl ToString for Group {
+    fn to_string(&self) -> String {
+        TokenStream::from(TokenTree::from(self.clone())).to_string()
     }
 }
 
@@ -713,7 +678,7 @@ pub fn set_span(&mut self, span: Span) {
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl fmt::Display for Group {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        TokenStream::from(TokenTree::from(self.clone())).fmt(f)
+        f.write_str(&self.to_string())
     }
 }
 
@@ -734,11 +699,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 /// forms of `Spacing` returned.
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 #[derive(Clone)]
-pub struct Punct {
-    ch: char,
-    spacing: Spacing,
-    span: Span,
-}
+pub struct Punct(bridge::client::Punct);
 
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl !Send for Punct {}
@@ -750,10 +711,10 @@ impl !Sync for Punct {}
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 pub enum Spacing {
-    /// E.g. `+` is `Alone` in `+ =`, `+ident` or `+()`.
+    /// e.g., `+` is `Alone` in `+ =`, `+ident` or `+()`.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     Alone,
-    /// E.g. `+` is `Joint` in `+=` or `'#`.
+    /// e.g., `+` is `Joint` in `+=` or `'#`.
     /// Additionally, single quote `'` can join with identifiers to form lifetimes `'ident`.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     Joint,
@@ -773,17 +734,13 @@ pub fn new(ch: char, spacing: Spacing) -> Punct {
         if !LEGAL_CHARS.contains(&ch) {
             panic!("unsupported character `{:?}`", ch)
         }
-        Punct {
-            ch: ch,
-            spacing: spacing,
-            span: Span::call_site(),
-        }
+        Punct(bridge::client::Punct::new(ch, spacing))
     }
 
     /// Returns the value of this punctuation character as `char`.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn as_char(&self) -> char {
-        self.ch
+        self.0.as_char()
     }
 
     /// Returns the spacing of this punctuation character, indicating whether it's immediately
@@ -792,19 +749,28 @@ pub fn as_char(&self) -> char {
     /// (`Alone`) so the operator has certainly ended.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn spacing(&self) -> Spacing {
-        self.spacing
+        self.0.spacing()
     }
 
     /// Returns the span for this punctuation character.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn span(&self) -> Span {
-        self.span
+        Span(self.0.span())
     }
 
     /// Configure the span for this punctuation character.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn set_span(&mut self, span: Span) {
-        self.span = span;
+        self.0 = self.0.with_span(span.0);
+    }
+}
+
+// N.B., the bridge only provides `to_string`, implement `fmt::Display`
+// based on it (the reverse of the usual relationship between the two).
+#[stable(feature = "proc_macro_lib", since = "1.15.0")]
+impl ToString for Punct {
+    fn to_string(&self) -> String {
+        TokenStream::from(TokenTree::from(self.clone())).to_string()
     }
 }
 
@@ -813,7 +779,7 @@ pub fn set_span(&mut self, span: Span) {
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl fmt::Display for Punct {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        TokenStream::from(TokenTree::from(self.clone())).fmt(f)
+        f.write_str(&self.to_string())
     }
 }
 
@@ -831,16 +797,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 /// An identifier (`ident`).
 #[derive(Clone)]
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-pub struct Ident {
-    sym: Symbol,
-    span: Span,
-    is_raw: bool,
-}
-
-#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-impl !Send for Ident {}
-#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-impl !Sync for Ident {}
+pub struct Ident(bridge::client::Ident);
 
 impl Ident {
     fn is_valid(string: &str) -> bool {
@@ -877,7 +834,7 @@ pub fn new(string: &str, span: Span) -> Ident {
         if !Ident::is_valid(string) {
             panic!("`{:?}` is not a valid identifier", string)
         }
-        Ident::new_maybe_raw(string, span, false)
+        Ident(bridge::client::Ident::new(string, span.0, false))
     }
 
     /// Same as `Ident::new`, but creates a raw identifier (`r#ident`).
@@ -886,20 +843,29 @@ pub fn new_raw(string: &str, span: Span) -> Ident {
         if !Ident::is_valid(string) {
             panic!("`{:?}` is not a valid identifier", string)
         }
-        Ident::new_maybe_raw(string, span, true)
+        Ident(bridge::client::Ident::new(string, span.0, true))
     }
 
     /// Returns the span of this `Ident`, encompassing the entire string returned
     /// by `as_str`.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn span(&self) -> Span {
-        self.span
+        Span(self.0.span())
     }
 
     /// Configures the span of this `Ident`, possibly changing its hygiene context.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn set_span(&mut self, span: Span) {
-        self.span = span;
+        self.0 = self.0.with_span(span.0);
+    }
+}
+
+// N.B., the bridge only provides `to_string`, implement `fmt::Display`
+// based on it (the reverse of the usual relationship between the two).
+#[stable(feature = "proc_macro_lib", since = "1.15.0")]
+impl ToString for Ident {
+    fn to_string(&self) -> String {
+        TokenStream::from(TokenTree::from(self.clone())).to_string()
     }
 }
 
@@ -908,7 +874,7 @@ pub fn set_span(&mut self, span: Span) {
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl fmt::Display for Ident {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        TokenStream::from(TokenTree::from(self.clone())).fmt(f)
+        f.write_str(&self.to_string())
     }
 }
 
@@ -926,19 +892,9 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 /// character (`'a'`), byte character (`b'a'`), an integer or floating point number
 /// with or without a suffix (`1`, `1u8`, `2.3`, `2.3f32`).
 /// Boolean literals like `true` and `false` do not belong here, they are `Ident`s.
-// FIXME(eddyb) `Literal` should not expose internal `Debug` impls.
-#[derive(Clone, Debug)]
-#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-pub struct Literal {
-    lit: token::Lit,
-    suffix: Option<Symbol>,
-    span: Span,
-}
-
-#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-impl !Send for Literal {}
+#[derive(Clone)]
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
-impl !Sync for Literal {}
+pub struct Literal(bridge::client::Literal);
 
 macro_rules! suffixed_int_literals {
     ($($name:ident => $kind:ident,)*) => ($(
@@ -955,11 +911,7 @@ macro_rules! suffixed_int_literals {
         /// below.
         #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
         pub fn $name(n: $kind) -> Literal {
-            Literal {
-                lit: token::Lit::Integer(Symbol::intern(&n.to_string())),
-                suffix: Some(Symbol::intern(stringify!($kind))),
-                span: Span::call_site(),
-            }
+            Literal(bridge::client::Literal::typed_integer(&n.to_string(), stringify!($kind)))
         }
     )*)
 }
@@ -981,11 +933,7 @@ macro_rules! unsuffixed_int_literals {
         /// below.
         #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
         pub fn $name(n: $kind) -> Literal {
-            Literal {
-                lit: token::Lit::Integer(Symbol::intern(&n.to_string())),
-                suffix: None,
-                span: Span::call_site(),
-            }
+            Literal(bridge::client::Literal::integer(&n.to_string()))
         }
     )*)
 }
@@ -1038,11 +986,7 @@ pub fn f32_unsuffixed(n: f32) -> Literal {
         if !n.is_finite() {
             panic!("Invalid float literal {}", n);
         }
-        Literal {
-            lit: token::Lit::Float(Symbol::intern(&n.to_string())),
-            suffix: None,
-            span: Span::call_site(),
-        }
+        Literal(bridge::client::Literal::float(&n.to_string()))
     }
 
     /// Creates a new suffixed floating-point literal.
@@ -1063,11 +1007,7 @@ pub fn f32_suffixed(n: f32) -> Literal {
         if !n.is_finite() {
             panic!("Invalid float literal {}", n);
         }
-        Literal {
-            lit: token::Lit::Float(Symbol::intern(&n.to_string())),
-            suffix: Some(Symbol::intern("f32")),
-            span: Span::call_site(),
-        }
+        Literal(bridge::client::Literal::f32(&n.to_string()))
     }
 
     /// Creates a new unsuffixed floating-point literal.
@@ -1087,11 +1027,7 @@ pub fn f64_unsuffixed(n: f64) -> Literal {
         if !n.is_finite() {
             panic!("Invalid float literal {}", n);
         }
-        Literal {
-            lit: token::Lit::Float(Symbol::intern(&n.to_string())),
-            suffix: None,
-            span: Span::call_site(),
-        }
+        Literal(bridge::client::Literal::float(&n.to_string()))
     }
 
     /// Creates a new suffixed floating-point literal.
@@ -1112,61 +1048,74 @@ pub fn f64_suffixed(n: f64) -> Literal {
         if !n.is_finite() {
             panic!("Invalid float literal {}", n);
         }
-        Literal {
-            lit: token::Lit::Float(Symbol::intern(&n.to_string())),
-            suffix: Some(Symbol::intern("f64")),
-            span: Span::call_site(),
-        }
+        Literal(bridge::client::Literal::f64(&n.to_string()))
     }
 
     /// String literal.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn string(string: &str) -> Literal {
-        let mut escaped = String::new();
-        for ch in string.chars() {
-            escaped.extend(ch.escape_debug());
-        }
-        Literal {
-            lit: token::Lit::Str_(Symbol::intern(&escaped)),
-            suffix: None,
-            span: Span::call_site(),
-        }
+        Literal(bridge::client::Literal::string(string))
     }
 
     /// Character literal.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn character(ch: char) -> Literal {
-        let mut escaped = String::new();
-        escaped.extend(ch.escape_unicode());
-        Literal {
-            lit: token::Lit::Char(Symbol::intern(&escaped)),
-            suffix: None,
-            span: Span::call_site(),
-        }
+        Literal(bridge::client::Literal::character(ch))
     }
 
     /// Byte string literal.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn byte_string(bytes: &[u8]) -> Literal {
-        let string = bytes.iter().cloned().flat_map(ascii::escape_default)
-            .map(Into::<char>::into).collect::<String>();
-        Literal {
-            lit: token::Lit::ByteStr(Symbol::intern(&string)),
-            suffix: None,
-            span: Span::call_site(),
-        }
+        Literal(bridge::client::Literal::byte_string(bytes))
     }
 
     /// Returns the span encompassing this literal.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn span(&self) -> Span {
-        self.span
+        Span(self.0.span())
     }
 
     /// Configures the span associated for this literal.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn set_span(&mut self, span: Span) {
-        self.span = span;
+        self.0.set_span(span.0);
+    }
+
+    /// Returns a `Span` that is a subset of `self.span()` containing only the
+    /// source bytes in range `range`. Returns `None` if the would-be trimmed
+    /// span is outside the bounds of `self`.
+    // FIXME(SergioBenitez): check that the byte range starts and ends at a
+    // UTF-8 boundary of the source. otherwise, it's likely that a panic will
+    // occur elsewhere when the source text is printed.
+    // FIXME(SergioBenitez): there is no way for the user to know what
+    // `self.span()` actually maps to, so this method can currently only be
+    // called blindly. For example, `to_string()` for the character 'c' returns
+    // "'\u{63}'"; there is no way for the user to know whether the source text
+    // was 'c' or whether it was '\u{63}'.
+    #[unstable(feature = "proc_macro_span", issue = "54725")]
+    pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
+        // HACK(eddyb) something akin to `Option::cloned`, but for `Bound<&T>`.
+        fn cloned_bound<T: Clone>(bound: Bound<&T>) -> Bound<T> {
+            match bound {
+                Bound::Included(x) => Bound::Included(x.clone()),
+                Bound::Excluded(x) => Bound::Excluded(x.clone()),
+                Bound::Unbounded => Bound::Unbounded,
+            }
+        }
+
+        self.0.subspan(
+            cloned_bound(range.start_bound()),
+            cloned_bound(range.end_bound()),
+        ).map(Span)
+    }
+}
+
+// N.B., the bridge only provides `to_string`, implement `fmt::Display`
+// based on it (the reverse of the usual relationship between the two).
+#[stable(feature = "proc_macro_lib", since = "1.15.0")]
+impl ToString for Literal {
+    fn to_string(&self) -> String {
+        TokenStream::from(TokenTree::from(self.clone())).to_string()
     }
 }
 
@@ -1175,149 +1124,14 @@ pub fn set_span(&mut self, span: Span) {
 #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
 impl fmt::Display for Literal {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        TokenStream::from(TokenTree::from(self.clone())).fmt(f)
+        f.write_str(&self.to_string())
     }
 }
 
-/// Permanently unstable internal implementation details of this crate. This
-/// should not be used.
-///
-/// These methods are used by the rest of the compiler to generate instances of
-/// `TokenStream` to hand to macro definitions, as well as consume the output.
-///
-/// Note that this module is also intentionally separate from the rest of the
-/// crate. This allows the `#[unstable]` directive below to naturally apply to
-/// all of the contents.
-#[unstable(feature = "proc_macro_internals", issue = "27812")]
-#[doc(hidden)]
-pub mod __internal {
-    use std::cell::Cell;
-    use std::ptr;
-
-    use syntax::ast;
-    use syntax::ext::base::ExtCtxt;
-    use syntax::ptr::P;
-    use syntax::parse::{self, ParseSess};
-    use syntax::parse::token::{self, Token};
-    use syntax::tokenstream;
-    use syntax_pos::{BytePos, Loc, DUMMY_SP};
-    use syntax_pos::hygiene::{SyntaxContext, Transparency};
-
-    use super::{TokenStream, LexError, Span};
-
-    pub fn lookup_char_pos(pos: BytePos) -> Loc {
-        with_sess(|sess, _| sess.source_map().lookup_char_pos(pos))
-    }
-
-    pub fn new_token_stream(item: P<ast::Item>) -> TokenStream {
-        let token = Token::interpolated(token::NtItem(item));
-        TokenStream(tokenstream::TokenTree::Token(DUMMY_SP, token).into())
-    }
-
-    pub fn token_stream_wrap(inner: tokenstream::TokenStream) -> TokenStream {
-        TokenStream(inner)
-    }
-
-    pub fn token_stream_parse_items(stream: TokenStream) -> Result<Vec<P<ast::Item>>, LexError> {
-        with_sess(move |sess, _| {
-            let mut parser = parse::stream_to_parser(sess, stream.0);
-            let mut items = Vec::new();
-
-            while let Some(item) = try!(parser.parse_item().map_err(super::parse_to_lex_err)) {
-                items.push(item)
-            }
-
-            Ok(items)
-        })
-    }
-
-    pub fn token_stream_inner(stream: TokenStream) -> tokenstream::TokenStream {
-        stream.0
-    }
-
-    pub trait Registry {
-        fn register_custom_derive(&mut self,
-                                  trait_name: &str,
-                                  expand: fn(TokenStream) -> TokenStream,
-                                  attributes: &[&'static str]);
-
-        fn register_attr_proc_macro(&mut self,
-                                    name: &str,
-                                    expand: fn(TokenStream, TokenStream) -> TokenStream);
-
-        fn register_bang_proc_macro(&mut self,
-                                    name: &str,
-                                    expand: fn(TokenStream) -> TokenStream);
-    }
-
-    #[derive(Clone, Copy)]
-    pub struct ProcMacroData {
-        pub def_site: Span,
-        pub call_site: Span,
-    }
-
-    #[derive(Clone, Copy)]
-    struct ProcMacroSess {
-        parse_sess: *const ParseSess,
-        data: ProcMacroData,
-    }
-
-    // Emulate scoped_thread_local!() here essentially
-    thread_local! {
-        static CURRENT_SESS: Cell<ProcMacroSess> = Cell::new(ProcMacroSess {
-            parse_sess: ptr::null(),
-            data: ProcMacroData { def_site: Span(DUMMY_SP), call_site: Span(DUMMY_SP) },
-        });
-    }
-
-    pub fn set_sess<F, R>(cx: &ExtCtxt, f: F) -> R
-        where F: FnOnce() -> R
-    {
-        struct Reset { prev: ProcMacroSess }
-
-        impl Drop for Reset {
-            fn drop(&mut self) {
-                CURRENT_SESS.with(|p| p.set(self.prev));
-            }
-        }
-
-        CURRENT_SESS.with(|p| {
-            let _reset = Reset { prev: p.get() };
-
-            // No way to determine def location for a proc macro right now, so use call location.
-            let location = cx.current_expansion.mark.expn_info().unwrap().call_site;
-            let to_span = |transparency| Span(location.with_ctxt(
-                SyntaxContext::empty().apply_mark_with_transparency(cx.current_expansion.mark,
-                                                                    transparency))
-            );
-            p.set(ProcMacroSess {
-                parse_sess: cx.parse_sess,
-                data: ProcMacroData {
-                    def_site: to_span(Transparency::Opaque),
-                    call_site: to_span(Transparency::Transparent),
-                },
-            });
-            f()
-        })
-    }
-
-    pub fn in_sess() -> bool
-    {
-        !CURRENT_SESS.with(|sess| sess.get()).parse_sess.is_null()
-    }
-
-    pub fn with_sess<F, R>(f: F) -> R
-        where F: FnOnce(&ParseSess, &ProcMacroData) -> R
-    {
-        let sess = CURRENT_SESS.with(|sess| sess.get());
-        if sess.parse_sess.is_null() {
-            panic!("procedural macro API is used outside of a procedural macro");
-        }
-        f(unsafe { &*sess.parse_sess }, &sess.data)
+#[stable(feature = "proc_macro_lib2", since = "1.29.0")]
+impl fmt::Debug for Literal {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        // FIXME(eddyb) `Literal` should not expose internal `Debug` impls.
+        self.0.fmt(f)
     }
 }
-
-fn parse_to_lex_err(mut err: DiagnosticBuilder) -> LexError {
-    err.cancel();
-    LexError { _inner: () }
-}