about summary refs log tree commit diff
path: root/src/libsyntax_ext
diff options
context:
space:
mode:
authorKonrad Borowski <konrad@borowski.pw>2018-12-23 16:47:11 +0100
committerGitHub <noreply@github.com>2018-12-23 16:47:11 +0100
commit8ac5380ea0204dbdcbc8108d259928b67d5f8ebb (patch)
tree174d912756fc2678af50d46ff457f7504750a975 /src/libsyntax_ext
parentb4a306c1e648c84f289c63e984941b7faad10af1 (diff)
parentddab10a692aab2e2984b5c826ed9d78a57e94851 (diff)
downloadrust-8ac5380ea0204dbdcbc8108d259928b67d5f8ebb.tar.gz
rust-8ac5380ea0204dbdcbc8108d259928b67d5f8ebb.zip
Merge branch 'master' into copied
Diffstat (limited to 'src/libsyntax_ext')
-rw-r--r--src/libsyntax_ext/Cargo.toml2
-rw-r--r--src/libsyntax_ext/asm.rs2
-rw-r--r--src/libsyntax_ext/assert.rs8
-rw-r--r--src/libsyntax_ext/deriving/clone.rs2
-rw-r--r--src/libsyntax_ext/deriving/cmp/partial_ord.rs2
-rw-r--r--src/libsyntax_ext/deriving/custom.rs1
-rw-r--r--src/libsyntax_ext/deriving/generic/mod.rs20
-rw-r--r--src/libsyntax_ext/deriving/generic/ty.rs2
-rw-r--r--src/libsyntax_ext/format.rs135
-rw-r--r--src/libsyntax_ext/global_asm.rs2
-rw-r--r--src/libsyntax_ext/lib.rs9
-rw-r--r--src/libsyntax_ext/proc_macro_decls.rs3
-rw-r--r--src/libsyntax_ext/proc_macro_server.rs127
-rw-r--r--src/libsyntax_ext/test.rs2
14 files changed, 150 insertions, 167 deletions
diff --git a/src/libsyntax_ext/Cargo.toml b/src/libsyntax_ext/Cargo.toml
index 4979d0b3e92..7ad08f75e8b 100644
--- a/src/libsyntax_ext/Cargo.toml
+++ b/src/libsyntax_ext/Cargo.toml
@@ -15,5 +15,5 @@ syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_target = { path = "../librustc_target" }
-smallvec = { version = "0.6.5", features = ["union"] }
+smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
 log = "0.4"
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index 026ddccd7be..2ff9fb487c4 100644
--- a/src/libsyntax_ext/asm.rs
+++ b/src/libsyntax_ext/asm.rs
@@ -47,7 +47,7 @@ impl State {
     }
 }
 
-const OPTIONS: &'static [&'static str] = &["volatile", "alignstack", "intel"];
+const OPTIONS: &[&str] = &["volatile", "alignstack", "intel"];
 
 pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
                        sp: Span,
diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs
index e3bd2ca0131..a2384b59048 100644
--- a/src/libsyntax_ext/assert.rs
+++ b/src/libsyntax_ext/assert.rs
@@ -24,6 +24,14 @@ pub fn expand_assert<'cx>(
     tts: &[TokenTree],
 ) -> Box<dyn MacResult + 'cx> {
     let mut parser = cx.new_parser_from_tts(tts);
+
+    if parser.token == token::Eof {
+        cx.struct_span_err(sp, "macro requires a boolean expression as an argument")
+            .span_label(sp, "boolean expression required")
+            .emit();
+        return DummyResult::expr(sp);
+    }
+
     let cond_expr = panictry!(parser.parse_expr());
     let custom_msg_args = if parser.eat(&token::Comma) {
         let ts = parser.parse_tokens();
diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs
index ec935b3e72f..b9e0933331c 100644
--- a/src/libsyntax_ext/deriving/clone.rs
+++ b/src/libsyntax_ext/deriving/clone.rs
@@ -140,7 +140,7 @@ fn cs_clone_shallow(name: &str,
     let mut stmts = Vec::new();
     if is_union {
         // let _: AssertParamIsCopy<Self>;
-        let self_ty = cx.ty_path(cx.path_ident(trait_span, keywords::SelfType.ident()));
+        let self_ty = cx.ty_path(cx.path_ident(trait_span, keywords::SelfUpper.ident()));
         assert_ty_bounds(cx, &mut stmts, self_ty, trait_span, "AssertParamIsCopy");
     } else {
         match *substr.fields {
diff --git a/src/libsyntax_ext/deriving/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs
index 32a58de3529..196cfa5fe35 100644
--- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs
+++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs
@@ -227,7 +227,7 @@ fn cs_op(less: bool,
     let fold = cs_fold1(false, // need foldr
         |cx, span, subexpr, self_f, other_fs| {
             // build up a series of `partial_cmp`s from the inside
-            // out (hence foldr) to get lexical ordering, i.e. for op ==
+            // out (hence foldr) to get lexical ordering, i.e., for op ==
             // `ast::lt`
             //
             // ```
diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs
index 5c82d191138..cc2fa685687 100644
--- a/src/libsyntax_ext/deriving/custom.rs
+++ b/src/libsyntax_ext/deriving/custom.rs
@@ -74,7 +74,6 @@ impl MultiItemModifier for ProcMacroDerive {
         // Mark attributes as known, and used.
         MarkAttrs(&self.attrs).visit_item(&item);
 
-        let item = ecx.resolver.eliminate_crate_var(item);
         let token = Token::interpolated(token::NtItem(item));
         let input = tokenstream::TokenTree::Token(DUMMY_SP, token).into();
 
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index a5b12ce4c4d..443fd48120e 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -18,7 +18,7 @@
 //! - Methods taking any number of parameters of any type, and returning
 //!   any type, other than vectors, bottom and closures.
 //! - Generating `impl`s for types with type parameters and lifetimes
-//!   (e.g. `Option<T>`), the parameters are automatically given the
+//!   (e.g., `Option<T>`), the parameters are automatically given the
 //!   current trait as a bound. (This includes separate type parameters
 //!   and lifetimes for methods.)
 //! - Additional bounds on the type parameters (`TraitDef.additional_bounds`)
@@ -30,9 +30,9 @@
 //! - `Struct`, when `Self` is a struct (including tuple structs, e.g
 //!   `struct T(i32, char)`).
 //! - `EnumMatching`, when `Self` is an enum and all the arguments are the
-//!   same variant of the enum (e.g. `Some(1)`, `Some(3)` and `Some(4)`)
+//!   same variant of the enum (e.g., `Some(1)`, `Some(3)` and `Some(4)`)
 //! - `EnumNonMatchingCollapsed` when `Self` is an enum and the arguments
-//!   are not the same variant (e.g. `None`, `Some(1)` and `None`).
+//!   are not the same variant (e.g., `None`, `Some(1)` and `None`).
 //! - `StaticEnum` and `StaticStruct` for static methods, where the type
 //!   being derived upon is either an enum or struct respectively. (Any
 //!   argument with type Self is just grouped among the non-self
@@ -224,7 +224,7 @@ pub struct TraitDef<'a> {
     /// other than the current trait
     pub additional_bounds: Vec<Ty<'a>>,
 
-    /// Any extra lifetimes and/or bounds, e.g. `D: serialize::Decoder`
+    /// Any extra lifetimes and/or bounds, e.g., `D: serialize::Decoder`
     pub generics: LifetimeBounds<'a>,
 
     /// Is it an `unsafe` trait?
@@ -242,10 +242,10 @@ pub struct TraitDef<'a> {
 pub struct MethodDef<'a> {
     /// name of the method
     pub name: &'a str,
-    /// List of generics, e.g. `R: rand::Rng`
+    /// List of generics, e.g., `R: rand::Rng`
     pub generics: LifetimeBounds<'a>,
 
-    /// Whether there is a self argument (outer Option) i.e. whether
+    /// Whether there is a self argument (outer Option) i.e., whether
     /// this is a static function, and whether it is a pointer (inner
     /// Option)
     pub explicit_self: Option<Option<PtrTy<'a>>>,
@@ -938,7 +938,7 @@ impl<'a> MethodDef<'a> {
         let args = {
             let self_args = explicit_self.map(|explicit_self| {
                 ast::Arg::from_self(explicit_self,
-                                    keywords::SelfValue.ident().with_span_pos(trait_.span))
+                                    keywords::SelfLower.ident().with_span_pos(trait_.span))
             });
             let nonself_args = arg_types.into_iter()
                 .map(|(name, ty)| cx.arg(trait_.span, name, ty));
@@ -1371,7 +1371,7 @@ impl<'a> MethodDef<'a> {
             // that type.  Otherwise casts to `i32` (the default repr
             // type).
             //
-            // i.e. for `enum E<T> { A, B(1), C(T, T) }`, and a deriving
+            // i.e., for `enum E<T> { A, B(1), C(T, T) }`, and a deriving
             // with three Self args, builds three statements:
             //
             // ```
@@ -1489,8 +1489,8 @@ impl<'a> MethodDef<'a> {
             //
             // (See also #4499 and #12609; note that some of the
             // discussions there influence what choice we make here;
-            // e.g. if we feature-gate `match x { ... }` when x refers
-            // to an uninhabited type (e.g. a zero-variant enum or a
+            // e.g., if we feature-gate `match x { ... }` when x refers
+            // to an uninhabited type (e.g., a zero-variant enum or a
             // type holding such an enum), but do not feature-gate
             // zero-variant enums themselves, then attempting to
             // derive Debug on such a type could here generate code
diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs
index fa284f4ab0e..11689a98a79 100644
--- a/src/libsyntax_ext/deriving/generic/ty.rs
+++ b/src/libsyntax_ext/deriving/generic/ty.rs
@@ -32,7 +32,7 @@ pub enum PtrTy<'a> {
     Raw(ast::Mutability),
 }
 
-/// A path, e.g. `::std::option::Option::<i32>` (global). Has support
+/// A path, e.g., `::std::option::Option::<i32>` (global). Has support
 /// for type parameters and a lifetime.
 #[derive(Clone)]
 pub struct Path<'a> {
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 31e608de1f8..41799eede9e 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -158,28 +158,15 @@ fn parse_args(ecx: &mut ExtCtxt,
         } // accept trailing commas
         if named || (p.token.is_ident() && p.look_ahead(1, |t| *t == token::Eq)) {
             named = true;
-            let ident = match p.token {
-                token::Ident(i, _) => {
-                    p.bump();
-                    i
-                }
-                _ if named => {
-                    ecx.span_err(
-                        p.span,
-                        "expected ident, positional arguments cannot follow named arguments",
-                    );
-                    return None;
-                }
-                _ => {
-                    ecx.span_err(
-                        p.span,
-                        &format!(
-                            "expected ident for named argument, found `{}`",
-                            p.this_token_to_string()
-                        ),
-                    );
-                    return None;
-                }
+            let ident = if let token::Ident(i, _) = p.token {
+                p.bump();
+                i
+            } else {
+                ecx.span_err(
+                    p.span,
+                    "expected ident, positional arguments cannot follow named arguments",
+                );
+                return None;
             };
             let name: &str = &ident.as_str();
 
@@ -209,7 +196,7 @@ fn parse_args(ecx: &mut ExtCtxt,
 impl<'a, 'b> Context<'a, 'b> {
     fn resolve_name_inplace(&self, p: &mut parse::Piece) {
         // NOTE: the `unwrap_or` branch is needed in case of invalid format
-        // arguments, e.g. `format_args!("{foo}")`.
+        // arguments, e.g., `format_args!("{foo}")`.
         let lookup = |s| *self.names.get(s).unwrap_or(&0);
 
         match *p {
@@ -286,11 +273,11 @@ impl<'a, 'b> Context<'a, 'b> {
         } else {
             MultiSpan::from_span(self.fmtsp)
         };
-        let mut refs: Vec<_> = self
+        let refs_len = self.invalid_refs.len();
+        let mut refs = self
             .invalid_refs
             .iter()
-            .map(|(r, pos)| (r.to_string(), self.arg_spans.get(*pos)))
-            .collect();
+            .map(|(r, pos)| (r.to_string(), self.arg_spans.get(*pos)));
 
         if self.names.is_empty() && !numbered_position_args {
             e = self.ecx.mut_span_err(
@@ -303,28 +290,24 @@ impl<'a, 'b> Context<'a, 'b> {
                 ),
             );
         } else {
-            let (arg_list, mut sp) = match refs.len() {
-                1 => {
-                    let (reg, pos) = refs.pop().unwrap();
-                    (
-                        format!("argument {}", reg),
-                        MultiSpan::from_span(*pos.unwrap_or(&self.fmtsp)),
-                    )
-                }
-                _ => {
-                    let pos =
-                        MultiSpan::from_spans(refs.iter().map(|(_, p)| *p.unwrap()).collect());
-                    let mut refs: Vec<String> = refs.iter().map(|(s, _)| s.to_owned()).collect();
-                    let reg = refs.pop().unwrap();
-                    (
-                        format!(
-                            "arguments {head} and {tail}",
-                            tail = reg,
-                            head = refs.join(", ")
-                        ),
-                        pos,
-                    )
-                }
+            let (arg_list, mut sp) = if refs_len == 1 {
+                let (reg, pos) = refs.next().unwrap();
+                (
+                    format!("argument {}", reg),
+                    MultiSpan::from_span(*pos.unwrap_or(&self.fmtsp)),
+                )
+            } else {
+                let (mut refs, spans): (Vec<_>, Vec<_>) = refs.unzip();
+                let pos = MultiSpan::from_spans(spans.into_iter().map(|s| *s.unwrap()).collect());
+                let reg = refs.pop().unwrap();
+                (
+                    format!(
+                        "arguments {head} and {tail}",
+                        head = refs.join(", "),
+                        tail = reg,
+                    ),
+                    pos,
+                )
             };
             if !self.is_literal {
                 sp = MultiSpan::from_span(self.fmtsp);
@@ -353,33 +336,30 @@ impl<'a, 'b> Context<'a, 'b> {
                     Placeholder(_) => {
                         // record every (position, type) combination only once
                         let ref mut seen_ty = self.arg_unique_types[arg];
-                        let i = match seen_ty.iter().position(|x| *x == ty) {
-                            Some(i) => i,
-                            None => {
-                                let i = seen_ty.len();
-                                seen_ty.push(ty);
-                                i
-                            }
-                        };
+                        let i = seen_ty.iter().position(|x| *x == ty).unwrap_or_else(|| {
+                            let i = seen_ty.len();
+                            seen_ty.push(ty);
+                            i
+                        });
                         self.arg_types[arg].push(i);
                     }
                     Count => {
-                        match self.count_positions.entry(arg) {
-                            Entry::Vacant(e) => {
-                                let i = self.count_positions_count;
-                                e.insert(i);
-                                self.count_args.push(Exact(arg));
-                                self.count_positions_count += 1;
-                            }
-                            Entry::Occupied(_) => {}
+                        if let Entry::Vacant(e) = self.count_positions.entry(arg) {
+                            let i = self.count_positions_count;
+                            e.insert(i);
+                            self.count_args.push(Exact(arg));
+                            self.count_positions_count += 1;
                         }
                     }
                 }
             }
 
             Named(name) => {
-                let idx = match self.names.get(&name) {
-                    Some(e) => *e,
+                match self.names.get(&name) {
+                    Some(idx) => {
+                        // Treat as positional arg.
+                        self.verify_arg_type(Exact(*idx), ty)
+                    }
                     None => {
                         let msg = format!("there is no argument named `{}`", name);
                         let sp = if self.is_literal {
@@ -389,11 +369,8 @@ impl<'a, 'b> Context<'a, 'b> {
                         };
                         let mut err = self.ecx.struct_span_err(sp, &msg[..]);
                         err.emit();
-                        return;
                     }
-                };
-                // Treat as positional arg.
-                self.verify_arg_type(Exact(idx), ty)
+                }
             }
         }
     }
@@ -436,12 +413,10 @@ impl<'a, 'b> Context<'a, 'b> {
             parse::CountIs(i) => count("Is", Some(self.ecx.expr_usize(sp, i))),
             parse::CountIsParam(i) => {
                 // This needs mapping too, as `i` is referring to a macro
-                // argument.
-                let i = match self.count_positions.get(&i) {
-                    Some(&i) => i,
-                    None => 0, // error already emitted elsewhere
-                };
-                let i = i + self.count_args_index_offset;
+                // argument. If `i` is not found in `count_positions` then
+                // the error had already been emitted elsewhere.
+                let i = self.count_positions.get(&i).cloned().unwrap_or(0)
+                      + self.count_args_index_offset;
                 count("Param", Some(self.ecx.expr_usize(sp, i)))
             }
             parse::CountImplied => count("Implied", None),
@@ -526,10 +501,7 @@ impl<'a, 'b> Context<'a, 'b> {
                     },
                 };
 
-                let fill = match arg.format.fill {
-                    Some(c) => c,
-                    None => ' ',
-                };
+                let fill = arg.format.fill.unwrap_or(' ');
 
                 if *arg != simple_arg || fill != ' ' {
                     self.all_pieces_simple = false;
@@ -828,8 +800,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
     if !parser.errors.is_empty() {
         let err = parser.errors.remove(0);
         let sp = fmt.span.from_inner_byte_pos(err.start, err.end);
-        let mut e = ecx.struct_span_err(sp, &format!("invalid format string: {}",
-                                                        err.description));
+        let mut e = ecx.struct_span_err(sp, &format!("invalid format string: {}", err.description));
         e.span_label(sp, err.label + " in format string");
         if let Some(note) = err.note {
             e.note(&note);
diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs
index 1130a50537d..000bede7348 100644
--- a/src/libsyntax_ext/global_asm.rs
+++ b/src/libsyntax_ext/global_asm.rs
@@ -28,7 +28,7 @@ use syntax::symbol::Symbol;
 use syntax_pos::Span;
 use syntax::tokenstream;
 
-pub const MACRO: &'static str = "global_asm";
+pub const MACRO: &str = "global_asm";
 
 pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt,
                               sp: Span,
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index 1d814a67876..c49d5772531 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -39,10 +39,6 @@ extern crate log;
 
 mod diagnostics;
 
-#[macro_use]
-// for custom_derive
-pub mod deriving;
-
 mod asm;
 mod assert;
 mod cfg;
@@ -54,13 +50,14 @@ mod format;
 mod format_foreign;
 mod global_asm;
 mod log_syntax;
-mod trace_macros;
+mod proc_macro_server;
 mod test;
 mod test_case;
+mod trace_macros;
 
+pub mod deriving;
 pub mod proc_macro_decls;
 pub mod proc_macro_impl;
-mod proc_macro_server;
 
 use rustc_data_structures::sync::Lrc;
 use syntax::ast;
diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs
index c859275ed02..f4ff0989b5d 100644
--- a/src/libsyntax_ext/proc_macro_decls.rs
+++ b/src/libsyntax_ext/proc_macro_decls.rs
@@ -30,8 +30,7 @@ use syntax_pos::{Span, DUMMY_SP};
 
 use deriving;
 
-const PROC_MACRO_KINDS: [&'static str; 3] =
-    ["proc_macro_derive", "proc_macro_attribute", "proc_macro"];
+const PROC_MACRO_KINDS: [&str; 3] = ["proc_macro_derive", "proc_macro_attribute", "proc_macro"];
 
 struct ProcMacroDerive {
     trait_name: ast::Name,
diff --git a/src/libsyntax_ext/proc_macro_server.rs b/src/libsyntax_ext/proc_macro_server.rs
index 4babc2e612f..ca960cbe41b 100644
--- a/src/libsyntax_ext/proc_macro_server.rs
+++ b/src/libsyntax_ext/proc_macro_server.rs
@@ -64,11 +64,11 @@ impl FromInternal<(TokenStream, &'_ ParseSess, &'_ mut Vec<Self>)>
 
         let (tree, joint) = stream.as_tree();
         let (span, token) = match tree {
-            tokenstream::TokenTree::Delimited(span, delimed) => {
-                let delimiter = Delimiter::from_internal(delimed.delim);
+            tokenstream::TokenTree::Delimited(span, delim, tts) => {
+                let delimiter = Delimiter::from_internal(delim);
                 return TokenTree::Group(Group {
                     delimiter,
-                    stream: delimed.tts.into(),
+                    stream: tts.into(),
                     span,
                 });
             }
@@ -81,29 +81,23 @@ impl FromInternal<(TokenStream, &'_ ParseSess, &'_ mut Vec<Self>)>
                     $($field $(: $value)*,)*
                     span,
                 })
-            )
+            );
+            ($ty:ident::$method:ident($($value:expr),*)) => (
+                TokenTree::$ty(self::$ty::$method($($value,)* span))
+            );
         }
         macro_rules! op {
             ($a:expr) => {
-                tt!(Punct { ch: $a, joint })
+                tt!(Punct::new($a, joint))
             };
             ($a:expr, $b:expr) => {{
-                stack.push(tt!(Punct { ch: $b, joint }));
-                tt!(Punct {
-                    ch: $a,
-                    joint: true
-                })
+                stack.push(tt!(Punct::new($b, joint)));
+                tt!(Punct::new($a, true))
             }};
             ($a:expr, $b:expr, $c:expr) => {{
-                stack.push(tt!(Punct { ch: $c, joint }));
-                stack.push(tt!(Punct {
-                    ch: $b,
-                    joint: true
-                }));
-                tt!(Punct {
-                    ch: $a,
-                    joint: true
-                })
+                stack.push(tt!(Punct::new($c, joint)));
+                stack.push(tt!(Punct::new($b, true)));
+                tt!(Punct::new($a, true))
             }};
         }
 
@@ -156,20 +150,13 @@ impl FromInternal<(TokenStream, &'_ ParseSess, &'_ mut Vec<Self>)>
             Question => op!('?'),
             SingleQuote => op!('\''),
 
-            Ident(ident, is_raw) => tt!(Ident {
-                sym: ident.name,
-                is_raw
-            }),
+            Ident(ident, false) if ident.name == keywords::DollarCrate.name() =>
+                tt!(Ident::dollar_crate()),
+            Ident(ident, is_raw) => tt!(Ident::new(ident.name, is_raw)),
             Lifetime(ident) => {
                 let ident = ident.without_first_quote();
-                stack.push(tt!(Ident {
-                    sym: ident.name,
-                    is_raw: false
-                }));
-                tt!(Punct {
-                    ch: '\'',
-                    joint: true
-                })
+                stack.push(tt!(Ident::new(ident.name, false)));
+                tt!(Punct::new('\'', true))
             }
             Literal(lit, suffix) => tt!(Literal { lit, suffix }),
             DocComment(c) => {
@@ -193,15 +180,9 @@ impl FromInternal<(TokenStream, &'_ ParseSess, &'_ mut Vec<Self>)>
                     span: DelimSpan::from_single(span),
                 }));
                 if style == ast::AttrStyle::Inner {
-                    stack.push(tt!(Punct {
-                        ch: '!',
-                        joint: false
-                    }));
+                    stack.push(tt!(Punct::new('!', false)));
                 }
-                tt!(Punct {
-                    ch: '#',
-                    joint: false
-                })
+                tt!(Punct::new('#', false))
             }
 
             Interpolated(_) => {
@@ -232,14 +213,12 @@ impl ToInternal<TokenStream> for TokenTree<Group, Punct, Ident, Literal> {
             }) => {
                 return tokenstream::TokenTree::Delimited(
                     span,
-                    tokenstream::Delimited {
-                        delim: delimiter.to_internal(),
-                        tts: stream.into(),
-                    },
+                    delimiter.to_internal(),
+                    stream.into(),
                 )
                 .into();
             }
-            TokenTree::Ident(self::Ident { sym, span, is_raw }) => {
+            TokenTree::Ident(self::Ident { sym, is_raw, span }) => {
                 let token = Ident(ast::Ident::new(sym, span), is_raw);
                 return tokenstream::TokenTree::Token(span, token).into();
             }
@@ -340,11 +319,52 @@ pub struct Punct {
     span: Span,
 }
 
+impl Punct {
+    fn new(ch: char, joint: bool, span: Span) -> Punct {
+        const LEGAL_CHARS: &[char] = &['=', '<', '>', '!', '~', '+', '-', '*', '/', '%', '^',
+                                       '&', '|', '@', '.', ',', ';', ':', '#', '$', '?', '\''];
+        if !LEGAL_CHARS.contains(&ch) {
+            panic!("unsupported character `{:?}`", ch)
+        }
+        Punct { ch, joint, span }
+    }
+}
+
 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Ident {
     sym: Symbol,
-    span: Span,
     is_raw: bool,
+    span: Span,
+}
+
+impl Ident {
+    fn is_valid(string: &str) -> bool {
+        let mut chars = string.chars();
+        if let Some(start) = chars.next() {
+            (start == '_' || start.is_xid_start())
+                && chars.all(|cont| cont == '_' || cont.is_xid_continue())
+        } else {
+            false
+        }
+    }
+    fn new(sym: Symbol, is_raw: bool, span: Span) -> Ident {
+        let string = sym.as_str().get();
+        if !Self::is_valid(string) {
+            panic!("`{:?}` is not a valid identifier", string)
+        }
+        if is_raw {
+            let normalized_sym = Symbol::intern(string);
+            if normalized_sym == keywords::Underscore.name() ||
+               ast::Ident::with_empty_ctxt(normalized_sym).is_path_segment_keyword() {
+                panic!("`{:?}` is not a valid raw identifier", string)
+            }
+        }
+        Ident { sym, is_raw, span }
+    }
+    fn dollar_crate(span: Span) -> Ident {
+        // `$crate` is accepted as an ident only if it comes from the compiler.
+        Ident { sym: keywords::DollarCrate.name(), is_raw: false, span }
+    }
 }
 
 // FIXME(eddyb) `Literal` should not expose internal `Debug` impls.
@@ -402,7 +422,7 @@ impl server::TokenStream for Rustc<'_> {
     }
     fn from_str(&mut self, src: &str) -> Self::TokenStream {
         parse::parse_stream_from_source_str(
-            FileName::ProcMacroSourceCode,
+            FileName::proc_macro_source_code(src.clone()),
             src.to_string(),
             self.sess,
             Some(self.call_site),
@@ -494,11 +514,7 @@ impl server::Group for Rustc<'_> {
 
 impl server::Punct for Rustc<'_> {
     fn new(&mut self, ch: char, spacing: Spacing) -> Self::Punct {
-        Punct {
-            ch,
-            joint: spacing == Spacing::Joint,
-            span: server::Span::call_site(self),
-        }
+        Punct::new(ch, spacing == Spacing::Joint, server::Span::call_site(self))
     }
     fn as_char(&mut self, punct: Self::Punct) -> char {
         punct.ch
@@ -520,14 +536,7 @@ impl server::Punct for Rustc<'_> {
 
 impl server::Ident for Rustc<'_> {
     fn new(&mut self, string: &str, span: Self::Span, is_raw: bool) -> Self::Ident {
-        let sym = Symbol::intern(string);
-        if is_raw
-            && (sym == keywords::Underscore.name()
-                || ast::Ident::with_empty_ctxt(sym).is_path_segment_keyword())
-        {
-            panic!("`{:?}` is not a valid raw identifier", string)
-        }
-        Ident { sym, span, is_raw }
+        Ident::new(Symbol::intern(string), is_raw, span)
     }
     fn span(&mut self, ident: Self::Ident) -> Self::Span {
         ident.span
diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs
index b8a171b52ad..1f2e6fc81c8 100644
--- a/src/libsyntax_ext/test.rs
+++ b/src/libsyntax_ext/test.rs
@@ -318,7 +318,7 @@ fn has_test_signature(cx: &ExtCtxt, i: &ast::Item) -> bool {
 
 fn has_bench_signature(cx: &ExtCtxt, i: &ast::Item) -> bool {
     let has_sig = if let ast::ItemKind::Fn(ref decl, _, _, _) = i.node {
-        // NB: inadequate check, but we're running
+        // N.B., inadequate check, but we're running
         // well before resolve, can't get too deep.
         decl.inputs.len() == 1
     } else {