about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-03-08 14:27:23 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-03-17 22:08:07 +0300
commit5d06c890fececc6f6779cd65ca83cef4647b8fdd (patch)
tree7ffd581b7c7b9ac7294ecb6f28994b1afe753659 /src
parent61b6bf54fdf56195baf9a8ee7383551b0d468c81 (diff)
downloadrust-5d06c890fececc6f6779cd65ca83cef4647b8fdd.tar.gz
rust-5d06c890fececc6f6779cd65ca83cef4647b8fdd.zip
syntax: Make `_` an identifier
Diffstat (limited to 'src')
-rw-r--r--src/libproc_macro/lib.rs2
-rw-r--r--src/librustc/hir/mod.rs2
-rw-r--r--src/librustc/ich/impls_syntax.rs1
-rw-r--r--src/librustc_passes/ast_validation.rs6
-rw-r--r--src/librustdoc/html/highlight.rs2
-rw-r--r--src/libsyntax/diagnostics/plugin.rs4
-rw-r--r--src/libsyntax/ext/quote.rs1
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs3
-rw-r--r--src/libsyntax/feature_gate.rs2
-rw-r--r--src/libsyntax/parse/lexer/mod.rs14
-rw-r--r--src/libsyntax/parse/parser.rs36
-rw-r--r--src/libsyntax/parse/token.rs9
-rw-r--r--src/libsyntax/print/pprust.rs1
-rw-r--r--src/libsyntax_ext/env.rs6
-rw-r--r--src/libsyntax_pos/symbol.rs126
-rw-r--r--src/test/parse-fail/issue-32501.rs4
-rw-r--r--src/test/parse-fail/recover-enum2.rs2
-rw-r--r--src/test/parse-fail/underscore-suffix-for-float.rs3
-rw-r--r--src/test/run-pass/macro-pat.rs2
-rw-r--r--src/test/ui/cross-file-errors/main.stderr2
20 files changed, 109 insertions, 119 deletions
diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs
index 1163c1a98d5..b239f8018be 100644
--- a/src/libproc_macro/lib.rs
+++ b/src/libproc_macro/lib.rs
@@ -680,7 +680,6 @@ impl TokenTree {
             Pound => op!('#'),
             Dollar => op!('$'),
             Question => op!('?'),
-            Underscore => op!('_'),
 
             Ident(ident) | Lifetime(ident) => TokenNode::Term(Term(ident.name)),
             Literal(..) | DocComment(..) => TokenNode::Literal(self::Literal(token)),
@@ -743,7 +742,6 @@ impl TokenTree {
             '#' => Pound,
             '$' => Dollar,
             '?' => Question,
-            '_' => Underscore,
             _ => panic!("unsupported character {}", op),
         };
 
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index f4638c23c5f..83e855178db 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -214,7 +214,7 @@ impl LifetimeName {
         use self::LifetimeName::*;
         match *self {
             Implicit => keywords::Invalid.name(),
-            Underscore => Symbol::intern("'_"),
+            Underscore => keywords::UnderscoreLifetime.name(),
             Static => keywords::StaticLifetime.name(),
             Name(name) => name,
         }
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 289bc753d7f..513b6c835f9 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -287,7 +287,6 @@ fn hash_token<'a, 'gcx, W: StableHasherResult>(
         token::Token::Pound |
         token::Token::Dollar |
         token::Token::Question |
-        token::Token::Underscore |
         token::Token::Whitespace |
         token::Token::Comment |
         token::Token::Eof => {}
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index 55d00f92e4d..4215bf306a4 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -37,7 +37,9 @@ impl<'a> AstValidator<'a> {
     }
 
     fn check_lifetime(&self, lifetime: &Lifetime) {
-        let valid_names = [keywords::StaticLifetime.name(), keywords::Invalid.name()];
+        let valid_names = [keywords::UnderscoreLifetime.name(),
+                           keywords::StaticLifetime.name(),
+                           keywords::Invalid.name()];
         if !valid_names.contains(&lifetime.ident.name) &&
             token::Ident(lifetime.ident.without_first_quote()).is_reserved_ident() {
             self.err_handler().span_err(lifetime.span, "lifetimes cannot use keyword names");
@@ -45,7 +47,7 @@ impl<'a> AstValidator<'a> {
     }
 
     fn check_label(&self, label: Ident, span: Span) {
-        if token::Ident(label.without_first_quote()).is_reserved_ident() || label.name == "'_" {
+        if token::Ident(label.without_first_quote()).is_reserved_ident() {
             self.err_handler().span_err(span, &format!("invalid label name `{}`", label.name));
         }
     }
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index ef01c3e6bdb..659ec8a993d 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -352,7 +352,7 @@ impl<'a> Classifier<'a> {
 
             token::Lifetime(..) => Class::Lifetime,
 
-            token::Underscore | token::Eof | token::Interpolated(..) |
+            token::Eof | token::Interpolated(..) |
             token::Tilde | token::At | token::DotEq => Class::None,
         };
 
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
index e8c2d325bd6..6c0fe525f55 100644
--- a/src/libsyntax/diagnostics/plugin.rs
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -19,7 +19,7 @@ use ext::base::{ExtCtxt, MacEager, MacResult};
 use ext::build::AstBuilder;
 use parse::token;
 use ptr::P;
-use symbol::Symbol;
+use symbol::{keywords, Symbol};
 use tokenstream::{TokenTree};
 use util::small_vector::SmallVector;
 
@@ -192,7 +192,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt,
             (descriptions.len(), ecx.expr_vec(span, descriptions))
         });
 
-    let static_ = ecx.lifetime(span, Ident::from_str("'static"));
+    let static_ = ecx.lifetime(span, keywords::StaticLifetime.ident());
     let ty_str = ecx.ty_rptr(
         span,
         ecx.ty_ident(span, ecx.ident_of("str")),
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 7a024dbad88..d6642b7b6c2 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -709,7 +709,6 @@ fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> {
         token::Pound        => "Pound",
         token::Dollar       => "Dollar",
         token::Question     => "Question",
-        token::Underscore   => "Underscore",
         token::Eof          => "Eof",
 
         token::Whitespace | token::Comment | token::Shebang(_) => {
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index 0621f728e2a..beefdb3a6ea 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -765,8 +765,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool {
             Token::DotDotDot |                  // range pattern (future compat)
             Token::ModSep |                     // path
             Token::Lt |                         // path (UFCS constant)
-            Token::BinOp(token::Shl) |          // path (double UFCS)
-            Token::Underscore => true,          // placeholder
+            Token::BinOp(token::Shl) => true,   // path (double UFCS)
             Token::Interpolated(ref nt) => may_be_ident(&nt.0),
             _ => false,
         },
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index f42cb8a2583..0098f2ae89b 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -1790,7 +1790,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     }
 
     fn visit_lifetime(&mut self, lt: &'a ast::Lifetime) {
-        if lt.ident.name == "'_" {
+        if lt.ident.name == keywords::UnderscoreLifetime.name() {
             gate_feature_post!(&self, underscore_lifetimes, lt.span,
                                "underscore lifetimes are unstable");
         }
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 815ba49a60a..9d1bfba7b94 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -34,7 +34,7 @@ pub struct TokenAndSpan {
 
 impl Default for TokenAndSpan {
     fn default() -> Self {
-        TokenAndSpan { tok: token::Underscore, sp: syntax_pos::DUMMY_SP }
+        TokenAndSpan { tok: token::Whitespace, sp: syntax_pos::DUMMY_SP }
     }
 }
 
@@ -126,7 +126,7 @@ impl<'a> StringReader<'a> {
     pub fn try_next_token(&mut self) -> Result<TokenAndSpan, ()> {
         assert!(self.fatal_errs.is_empty());
         let ret_val = TokenAndSpan {
-            tok: replace(&mut self.peek_tok, token::Underscore),
+            tok: replace(&mut self.peek_tok, token::Whitespace),
             sp: self.peek_span,
         };
         self.advance_token()?;
@@ -1133,14 +1133,8 @@ impl<'a> StringReader<'a> {
                 self.bump();
             }
 
-            return Ok(self.with_str_from(start, |string| {
-                if string == "_" {
-                    token::Underscore
-                } else {
-                    // FIXME: perform NFKC normalization here. (Issue #2253)
-                    token::Ident(self.mk_ident(string))
-                }
-            }));
+            // FIXME: perform NFKC normalization here. (Issue #2253)
+            return Ok(self.with_str_from(start, |string| token::Ident(self.mk_ident(string))));
         }
 
         if is_dec_digit(c) {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index a3a6489fe8b..aa2a6f1cb47 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -549,7 +549,7 @@ impl<'a> Parser<'a> {
                -> Self {
         let mut parser = Parser {
             sess,
-            token: token::Underscore,
+            token: token::Whitespace,
             span: syntax_pos::DUMMY_SP,
             prev_span: syntax_pos::DUMMY_SP,
             meta_var_span: None,
@@ -800,11 +800,7 @@ impl<'a> Parser<'a> {
                 Err(if self.prev_token_kind == PrevTokenKind::DocComment {
                         self.span_fatal_err(self.prev_span, Error::UselessDocComment)
                     } else {
-                        let mut err = self.expected_ident_found();
-                        if self.token == token::Underscore {
-                            err.note("`_` is a wildcard pattern, not an identifier");
-                        }
-                        err
+                        self.expected_ident_found()
                     })
             }
         }
@@ -1602,7 +1598,7 @@ impl<'a> Parser<'a> {
             let e = self.parse_expr()?;
             self.expect(&token::CloseDelim(token::Paren))?;
             TyKind::Typeof(e)
-        } else if self.eat(&token::Underscore) {
+        } else if self.eat_keyword(keywords::Underscore) {
             // A type to be inferred `_`
             TyKind::Infer
         } else if self.token_is_bare_fn_keyword() {
@@ -1796,7 +1792,7 @@ impl<'a> Parser<'a> {
             _ => 0,
         };
 
-        self.look_ahead(offset, |t| t.is_ident() || t == &token::Underscore) &&
+        self.look_ahead(offset, |t| t.is_ident()) &&
         self.look_ahead(offset + 1, |t| t == &token::Colon)
     }
 
@@ -2782,7 +2778,7 @@ impl<'a> Parser<'a> {
             },
             token::CloseDelim(_) | token::Eof => unreachable!(),
             _ => {
-                let (token, span) = (mem::replace(&mut self.token, token::Underscore), self.span);
+                let (token, span) = (mem::replace(&mut self.token, token::Whitespace), self.span);
                 self.bump();
                 TokenTree::Token(span, token)
             }
@@ -3815,11 +3811,6 @@ impl<'a> Parser<'a> {
         let lo = self.span;
         let pat;
         match self.token {
-            token::Underscore => {
-                // Parse _
-                self.bump();
-                pat = PatKind::Wild;
-            }
             token::BinOp(token::And) | token::AndAnd => {
                 // Parse &pat / &mut pat
                 self.expect_and()?;
@@ -3849,8 +3840,11 @@ impl<'a> Parser<'a> {
                 self.expect(&token::CloseDelim(token::Bracket))?;
                 pat = PatKind::Slice(before, slice, after);
             }
-            // At this point, token != _, &, &&, (, [
-            _ => if self.eat_keyword(keywords::Mut) {
+            // At this point, token != &, &&, (, [
+            _ => if self.eat_keyword(keywords::Underscore) {
+                // Parse _
+                pat = PatKind::Wild;
+            } else if self.eat_keyword(keywords::Mut) {
                 // Parse mut ident @ pat / mut ref ident @ pat
                 let mutref_span = self.prev_span.to(self.span);
                 let binding_mode = if self.eat_keyword(keywords::Ref) {
@@ -7065,10 +7059,12 @@ impl<'a> Parser<'a> {
 
     fn parse_rename(&mut self) -> PResult<'a, Option<Ident>> {
         if self.eat_keyword(keywords::As) {
-            if self.eat(&token::Underscore) {
-                Ok(Some(Ident::with_empty_ctxt(Symbol::gensym("_"))))
-            } else {
-                self.parse_ident().map(Some)
+            match self.token {
+                token::Ident(ident) if ident.name == keywords::Underscore.name() => {
+                    self.bump(); // `_`
+                    Ok(Some(Ident { name: ident.name.gensymed(), ..ident }))
+                }
+                _ => self.parse_ident().map(Some),
             }
         } else {
             Ok(None)
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 097a2eb89fd..5c051e9b358 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -122,6 +122,7 @@ fn ident_can_begin_type(ident: ast::Ident) -> bool {
     !ident_token.is_reserved_ident() ||
     ident_token.is_path_segment_keyword() ||
     [
+        keywords::Underscore.name(),
         keywords::For.name(),
         keywords::Impl.name(),
         keywords::Fn.name(),
@@ -175,7 +176,6 @@ pub enum Token {
 
     /* Name components */
     Ident(ast::Ident),
-    Underscore,
     Lifetime(ast::Ident),
 
     // The `LazyTokenStream` is a pure function of the `Nonterminal`,
@@ -242,7 +242,6 @@ impl Token {
             Ident(ident)                => ident_can_begin_type(ident), // type name or keyword
             OpenDelim(Paren)            | // tuple
             OpenDelim(Bracket)          | // array
-            Underscore                  | // placeholder
             Not                         | // never
             BinOp(Star)                 | // raw pointer
             BinOp(And)                  | // reference
@@ -371,7 +370,7 @@ impl Token {
     // unnamed method parameters, crate root module, error recovery etc.
     pub fn is_special_ident(&self) -> bool {
         match self.ident() {
-            Some(id) => id.name <= keywords::DollarCrate.name(),
+            Some(id) => id.name <= keywords::Underscore.name(),
             _ => false,
         }
     }
@@ -441,7 +440,7 @@ impl Token {
 
             Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot | DotEq |
             DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar |
-            Question | OpenDelim(..) | CloseDelim(..) | Underscore => return None,
+            Question | OpenDelim(..) | CloseDelim(..) => return None,
 
             Literal(..) | Ident(..) | Lifetime(..) | Interpolated(..) | DocComment(..) |
             Whitespace | Comment | Shebang(..) | Eof => return None,
@@ -573,7 +572,7 @@ impl fmt::Debug for Nonterminal {
 pub fn is_op(tok: &Token) -> bool {
     match *tok {
         OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) |
-        Ident(..) | Underscore | Lifetime(..) | Interpolated(..) |
+        Ident(..) | Lifetime(..) | Interpolated(..) |
         Whitespace | Comment | Shebang(..) | Eof => false,
         _ => true,
     }
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 1cf2b7a44bc..36698a86374 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -252,7 +252,6 @@ pub fn token_to_string(tok: &Token) -> String {
         /* Name components */
         token::Ident(s)             => s.to_string(),
         token::Lifetime(s)          => s.to_string(),
-        token::Underscore           => "_".to_string(),
 
         /* Other */
         token::DocComment(s)        => s.to_string(),
diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs
index fcad065be52..ba6d25f7a60 100644
--- a/src/libsyntax_ext/env.rs
+++ b/src/libsyntax_ext/env.rs
@@ -17,7 +17,7 @@ use syntax::ast::{self, Ident};
 use syntax::ext::base::*;
 use syntax::ext::base;
 use syntax::ext::build::AstBuilder;
-use syntax::symbol::Symbol;
+use syntax::symbol::{keywords, Symbol};
 use syntax_pos::Span;
 use syntax::tokenstream;
 
@@ -35,14 +35,14 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt,
     let sp = sp.with_ctxt(sp.ctxt().apply_mark(cx.current_expansion.mark));
     let e = match env::var(&*var.as_str()) {
         Err(..) => {
+            let lt = cx.lifetime(sp, keywords::StaticLifetime.ident());
             cx.expr_path(cx.path_all(sp,
                                      true,
                                      cx.std_path(&["option", "Option", "None"]),
                                      Vec::new(),
                                      vec![cx.ty_rptr(sp,
                                                      cx.ty_ident(sp, Ident::from_str("str")),
-                                                     Some(cx.lifetime(sp,
-                                                                      Ident::from_str("'static"))),
+                                                     Some(lt),
                                                      ast::Mutability::Immutable)],
                                      Vec::new()))
         }
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index e95079f7c88..0cba094da64 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -261,73 +261,77 @@ macro_rules! declare_keywords {(
 declare_keywords! {
     // Special reserved identifiers used internally for elided lifetimes,
     // unnamed method parameters, crate root module, error recovery etc.
-    (0,  Invalid,        "")
-    (1,  CrateRoot,      "{{root}}")
-    (2,  DollarCrate,    "$crate")
+    (0,  Invalid,            "")
+    (1,  CrateRoot,          "{{root}}")
+    (2,  DollarCrate,        "$crate")
+    (3,  Underscore,         "_")
 
     // Keywords used in the language.
-    (3,  As,             "as")
-    (4,  Box,            "box")
-    (5,  Break,          "break")
-    (6,  Const,          "const")
-    (7,  Continue,       "continue")
-    (8,  Crate,          "crate")
-    (9,  Else,           "else")
-    (10, Enum,           "enum")
-    (11, Extern,         "extern")
-    (12, False,          "false")
-    (13, Fn,             "fn")
-    (14, For,            "for")
-    (15, If,             "if")
-    (16, Impl,           "impl")
-    (17, In,             "in")
-    (18, Let,            "let")
-    (19, Loop,           "loop")
-    (20, Match,          "match")
-    (21, Mod,            "mod")
-    (22, Move,           "move")
-    (23, Mut,            "mut")
-    (24, Pub,            "pub")
-    (25, Ref,            "ref")
-    (26, Return,         "return")
-    (27, SelfValue,      "self")
-    (28, SelfType,       "Self")
-    (29, Static,         "static")
-    (30, Struct,         "struct")
-    (31, Super,          "super")
-    (32, Trait,          "trait")
-    (33, True,           "true")
-    (34, Type,           "type")
-    (35, Unsafe,         "unsafe")
-    (36, Use,            "use")
-    (37, Where,          "where")
-    (38, While,          "while")
+    (4,  As,                 "as")
+    (5,  Box,                "box")
+    (6,  Break,              "break")
+    (7,  Const,              "const")
+    (8,  Continue,           "continue")
+    (9,  Crate,              "crate")
+    (10, Else,               "else")
+    (11, Enum,               "enum")
+    (12, Extern,             "extern")
+    (13, False,              "false")
+    (14, Fn,                 "fn")
+    (15, For,                "for")
+    (16, If,                 "if")
+    (17, Impl,               "impl")
+    (18, In,                 "in")
+    (19, Let,                "let")
+    (20, Loop,               "loop")
+    (21, Match,              "match")
+    (22, Mod,                "mod")
+    (23, Move,               "move")
+    (24, Mut,                "mut")
+    (25, Pub,                "pub")
+    (26, Ref,                "ref")
+    (27, Return,             "return")
+    (28, SelfValue,          "self")
+    (29, SelfType,           "Self")
+    (30, Static,             "static")
+    (31, Struct,             "struct")
+    (32, Super,              "super")
+    (33, Trait,              "trait")
+    (34, True,               "true")
+    (35, Type,               "type")
+    (36, Unsafe,             "unsafe")
+    (37, Use,                "use")
+    (38, Where,              "where")
+    (39, While,              "while")
 
     // Keywords reserved for future use.
-    (39, Abstract,       "abstract")
-    (40, Alignof,        "alignof")
-    (41, Become,         "become")
-    (42, Do,             "do")
-    (43, Final,          "final")
-    (44, Macro,          "macro")
-    (45, Offsetof,       "offsetof")
-    (46, Override,       "override")
-    (47, Priv,           "priv")
-    (48, Proc,           "proc")
-    (49, Pure,           "pure")
-    (50, Sizeof,         "sizeof")
-    (51, Typeof,         "typeof")
-    (52, Unsized,        "unsized")
-    (53, Virtual,        "virtual")
-    (54, Yield,          "yield")
+    (40, Abstract,           "abstract")
+    (41, Alignof,            "alignof")
+    (42, Become,             "become")
+    (43, Do,                 "do")
+    (44, Final,              "final")
+    (45, Macro,              "macro")
+    (46, Offsetof,           "offsetof")
+    (47, Override,           "override")
+    (48, Priv,               "priv")
+    (49, Proc,               "proc")
+    (50, Pure,               "pure")
+    (51, Sizeof,             "sizeof")
+    (52, Typeof,             "typeof")
+    (53, Unsized,            "unsized")
+    (54, Virtual,            "virtual")
+    (55, Yield,              "yield")
+
+    // Special lifetime names
+    (56, UnderscoreLifetime, "'_")
+    (57, StaticLifetime,     "'static")
 
     // Weak keywords, have special meaning only in specific contexts.
-    (55, Auto,           "auto")
-    (56, Catch,          "catch")
-    (57, Default,        "default")
-    (58, Dyn,            "dyn")
-    (59, StaticLifetime, "'static")
-    (60, Union,          "union")
+    (58, Auto,               "auto")
+    (59, Catch,              "catch")
+    (60, Default,            "default")
+    (61, Dyn,                "dyn")
+    (62, Union,              "union")
 }
 
 // If an interner exists, return it. Otherwise, prepare a fresh one.
diff --git a/src/test/parse-fail/issue-32501.rs b/src/test/parse-fail/issue-32501.rs
index f29c1fa2794..21db2f50517 100644
--- a/src/test/parse-fail/issue-32501.rs
+++ b/src/test/parse-fail/issue-32501.rs
@@ -16,7 +16,5 @@ fn main() {
     let _ = 0;
     let mut b = 0;
     let mut _b = 0;
-    let mut _ = 0; //~ ERROR expected identifier, found `_`
-    //~^ NOTE `_` is a wildcard pattern, not an identifier
-    //~| NOTE expected identifier
+    let mut _ = 0; //~ ERROR expected identifier, found reserved identifier `_`
 }
diff --git a/src/test/parse-fail/recover-enum2.rs b/src/test/parse-fail/recover-enum2.rs
index 49380a03e15..6fd32f842f1 100644
--- a/src/test/parse-fail/recover-enum2.rs
+++ b/src/test/parse-fail/recover-enum2.rs
@@ -39,5 +39,5 @@ fn main() {
         }
     }
     // still recover later
-    let bad_syntax = _; //~ ERROR: found `_`
+    let bad_syntax = _; //~ ERROR: expected expression, found reserved identifier `_`
 }
diff --git a/src/test/parse-fail/underscore-suffix-for-float.rs b/src/test/parse-fail/underscore-suffix-for-float.rs
index df7d9aa374d..8327217e6f2 100644
--- a/src/test/parse-fail/underscore-suffix-for-float.rs
+++ b/src/test/parse-fail/underscore-suffix-for-float.rs
@@ -9,5 +9,6 @@
 // except according to those terms.
 
 fn main() {
-    let a = 42._; //~ ERROR unexpected token: `_`
+    let a = 42._; //~ ERROR expected identifier, found reserved identifier `_`
+                  //~^ ERROR `{integer}` is a primitive type and therefore doesn't have fields
 }
diff --git a/src/test/run-pass/macro-pat.rs b/src/test/run-pass/macro-pat.rs
index 48e521de57e..8de3996245f 100644
--- a/src/test/run-pass/macro-pat.rs
+++ b/src/test/run-pass/macro-pat.rs
@@ -71,4 +71,6 @@ pub fn main() {
         let ident_pat!(x) = 2;
         x+1
     });
+
+    let ident_pat!(_) = 2; // OK
 }
diff --git a/src/test/ui/cross-file-errors/main.stderr b/src/test/ui/cross-file-errors/main.stderr
index a9db5214e6a..41a2172d295 100644
--- a/src/test/ui/cross-file-errors/main.stderr
+++ b/src/test/ui/cross-file-errors/main.stderr
@@ -1,4 +1,4 @@
-error: expected expression, found `_`
+error: expected expression, found reserved identifier `_`
   --> $DIR/underscore.rs:18:9
    |
 LL |         _