about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-06-13 20:57:30 +0000
committerbors <bors@rust-lang.org>2014-06-13 20:57:30 +0000
commit63dcc9a4df50680686bee852e82a52fbc59b3c27 (patch)
tree2a5a941e0da26795babf286edf77f9f225bc906d /src/libsyntax/parse
parente7f11f20e5e72a3b22863a9913df94303321a5ce (diff)
parentb7af25060a1b0451cb06085ba5893980bc4e5333 (diff)
downloadrust-63dcc9a4df50680686bee852e82a52fbc59b3c27.tar.gz
rust-63dcc9a4df50680686bee852e82a52fbc59b3c27.zip
auto merge of #14867 : alexcrichton/rust/rollup, r=alexcrichton
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/lexer/mod.rs39
-rw-r--r--src/libsyntax/parse/mod.rs3
-rw-r--r--src/libsyntax/parse/parser.rs144
-rw-r--r--src/libsyntax/parse/token.rs103
4 files changed, 172 insertions, 117 deletions
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index bb23fe50bd9..459cb6d31ed 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -757,19 +757,34 @@ impl<'a> StringReader<'a> {
                 while ident_continue(self.curr) {
                     self.bump();
                 }
+
+                // Include the leading `'` in the real identifier, for macro
+                // expansion purposes. See #12512 for the gory details of why
+                // this is necessary.
                 let ident = self.with_str_from(start, |lifetime_name| {
-                    str_to_ident(lifetime_name)
+                    str_to_ident(format!("'{}", lifetime_name).as_slice())
                 });
-                let tok = &token::IDENT(ident, false);
-
-                if token::is_keyword(token::keywords::Self, tok) {
-                    self.err_span(start, self.last_pos,
-                               "invalid lifetime name: 'self \
-                                is no longer a special lifetime");
-                } else if token::is_any_keyword(tok) &&
-                    !token::is_keyword(token::keywords::Static, tok) {
-                    self.err_span(start, self.last_pos,
-                               "invalid lifetime name");
+
+                // Conjure up a "keyword checking ident" to make sure that
+                // the lifetime name is not a keyword.
+                let keyword_checking_ident =
+                    self.with_str_from(start, |lifetime_name| {
+                        str_to_ident(lifetime_name)
+                    });
+                let keyword_checking_token =
+                    &token::IDENT(keyword_checking_ident, false);
+                if token::is_keyword(token::keywords::Self,
+                                     keyword_checking_token) {
+                    self.err_span(start,
+                                  self.last_pos,
+                                  "invalid lifetime name: 'self \
+                                   is no longer a special lifetime");
+                } else if token::is_any_keyword(keyword_checking_token) &&
+                    !token::is_keyword(token::keywords::Static,
+                                       keyword_checking_token) {
+                    self.err_span(start,
+                                  self.last_pos,
+                                  "invalid lifetime name");
                 }
                 return token::LIFETIME(ident);
             }
@@ -1128,7 +1143,7 @@ mod test {
 
     #[test] fn lifetime_name() {
         assert_eq!(setup(&mk_sh(), "'abc".to_string()).next_token().tok,
-                   token::LIFETIME(token::str_to_ident("abc")));
+                   token::LIFETIME(token::str_to_ident("'abc")));
     }
 
     #[test] fn raw_string() {
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 88746d145b6..1ebcbc8a7d1 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -117,8 +117,7 @@ pub fn parse_item_from_source_str(name: String,
                                   sess: &ParseSess)
                                   -> Option<Gc<ast::Item>> {
     let mut p = new_parser_from_source_str(sess, cfg, name, source);
-    let attrs = p.parse_outer_attributes();
-    maybe_aborted(p.parse_item(attrs),p)
+    maybe_aborted(p.parse_item_with_outer_attributes(),p)
 }
 
 pub fn parse_meta_from_source_str(name: String,
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 437b06e3df6..d11d303059f 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -51,7 +51,7 @@ use ast::{TokenTree, TraitMethod, TraitRef, TTDelim, TTSeq, TTTok};
 use ast::{TTNonterminal, TupleVariantKind, Ty, Ty_, TyBot, TyBox};
 use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn};
 use ast::{TyTypeof, TyInfer, TypeMethod};
-use ast::{TyNil, TyParam, TyParamBound, TyPath, TyPtr, TyRptr};
+use ast::{TyNil, TyParam, TyParamBound, TyParen, TyPath, TyPtr, TyRptr};
 use ast::{TyTup, TyU32, TyUnboxedFn, TyUniq, TyVec, UnUniq};
 use ast::{UnboxedFnTy, UnboxedFnTyParamBound, UnnamedField, UnsafeBlock};
 use ast::{UnsafeFn, ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse};
@@ -105,7 +105,7 @@ pub enum PathParsingMode {
     /// the type parameters; e.g. `foo::bar::<'a>::Baz::<T>`
     LifetimeAndTypesWithColons,
     /// A path with a lifetime and type parameters with bounds before the last
-    /// set of type parameters only; e.g. `foo::bar<'a>::Baz:X+Y<T>` This
+    /// set of type parameters only; e.g. `foo::bar<'a>::Baz+X+Y<T>` This
     /// form does not use extra double colons.
     LifetimeAndTypesAndBounds,
 }
@@ -1015,7 +1015,14 @@ impl<'a> Parser<'a> {
         };
 
         let (inputs, variadic) = self.parse_fn_args(false, false);
-        let (_, bounds) = self.parse_optional_ty_param_bounds(false);
+        let bounds = {
+            if self.eat(&token::COLON) {
+                let (_, bounds) = self.parse_ty_param_bounds(false);
+                Some(bounds)
+            } else {
+                None
+            }
+        };
         let (ret_style, ret_ty) = self.parse_ret_ty();
         let decl = P(FnDecl {
             inputs: inputs,
@@ -1083,7 +1090,14 @@ impl<'a> Parser<'a> {
             (is_unboxed, inputs)
         };
 
-        let (region, bounds) = self.parse_optional_ty_param_bounds(true);
+        let (region, bounds) = {
+            if self.eat(&token::COLON) {
+                let (region, bounds) = self.parse_ty_param_bounds(true);
+                (region, Some(bounds))
+            } else {
+                (None, None)
+            }
+        };
 
         let (return_style, output) = self.parse_ret_ty();
         let decl = P(FnDecl {
@@ -1227,7 +1241,7 @@ impl<'a> Parser<'a> {
     // parse a possibly mutable type
     pub fn parse_mt(&mut self) -> MutTy {
         let mutbl = self.parse_mutability();
-        let t = self.parse_ty(false);
+        let t = self.parse_ty(true);
         MutTy { ty: t, mutbl: mutbl }
     }
 
@@ -1238,7 +1252,7 @@ impl<'a> Parser<'a> {
         let mutbl = self.parse_mutability();
         let id = self.parse_ident();
         self.expect(&token::COLON);
-        let ty = self.parse_ty(false);
+        let ty = self.parse_ty(true);
         let hi = ty.span.hi;
         ast::TypeField {
             ident: id,
@@ -1261,7 +1275,7 @@ impl<'a> Parser<'a> {
                     })
                 )
             } else {
-                (Return, self.parse_ty(false))
+                (Return, self.parse_ty(true))
             }
         } else {
             let pos = self.span.lo;
@@ -1276,10 +1290,11 @@ impl<'a> Parser<'a> {
         }
     }
 
-    // parse a type.
-    // Useless second parameter for compatibility with quasiquote macros.
-    // Bleh!
-    pub fn parse_ty(&mut self, _: bool) -> P<Ty> {
+    /// Parse a type.
+    ///
+    /// The second parameter specifies whether the `+` binary operator is
+    /// allowed in the type grammar.
+    pub fn parse_ty(&mut self, plus_allowed: bool) -> P<Ty> {
         maybe_whole!(no_clone self, NtTy);
 
         let lo = self.span.lo;
@@ -1293,12 +1308,12 @@ impl<'a> Parser<'a> {
                 // (t) is a parenthesized ty
                 // (t,) is the type of a tuple with only one field,
                 // of type t
-                let mut ts = vec!(self.parse_ty(false));
+                let mut ts = vec!(self.parse_ty(true));
                 let mut one_tuple = false;
                 while self.token == token::COMMA {
                     self.bump();
                     if self.token != token::RPAREN {
-                        ts.push(self.parse_ty(false));
+                        ts.push(self.parse_ty(true));
                     }
                     else {
                         one_tuple = true;
@@ -1307,17 +1322,17 @@ impl<'a> Parser<'a> {
 
                 if ts.len() == 1 && !one_tuple {
                     self.expect(&token::RPAREN);
-                    return *ts.get(0)
+                    TyParen(*ts.get(0))
+                } else {
+                    let t = TyTup(ts);
+                    self.expect(&token::RPAREN);
+                    t
                 }
-
-                let t = TyTup(ts);
-                self.expect(&token::RPAREN);
-                t
             }
         } else if self.token == token::AT {
             // MANAGED POINTER
             self.bump();
-            TyBox(self.parse_ty(false))
+            TyBox(self.parse_ty(plus_allowed))
         } else if self.token == token::TILDE {
             // OWNED POINTER
             self.bump();
@@ -1326,7 +1341,7 @@ impl<'a> Parser<'a> {
                     self.obsolete(self.last_span, ObsoleteOwnedVector),
                 _ => self.obsolete(self.last_span, ObsoleteOwnedType),
             };
-            TyUniq(self.parse_ty(false))
+            TyUniq(self.parse_ty(true))
         } else if self.token == token::BINOP(token::STAR) {
             // STAR POINTER (bare pointer?)
             self.bump();
@@ -1334,7 +1349,7 @@ impl<'a> Parser<'a> {
         } else if self.token == token::LBRACKET {
             // VECTOR
             self.expect(&token::LBRACKET);
-            let t = self.parse_ty(false);
+            let t = self.parse_ty(true);
 
             // Parse the `, ..e` in `[ int, ..e ]`
             // where `e` is a const expression
@@ -1377,10 +1392,15 @@ impl<'a> Parser<'a> {
         } else if self.token == token::MOD_SEP
             || is_ident_or_path(&self.token) {
             // NAMED TYPE
+            let mode = if plus_allowed {
+                LifetimeAndTypesAndBounds
+            } else {
+                LifetimeAndTypesWithoutColons
+            };
             let PathAndBounds {
                 path,
                 bounds
-            } = self.parse_path(LifetimeAndTypesAndBounds);
+            } = self.parse_path(mode);
             TyPath(path, bounds, ast::DUMMY_NODE_ID)
         } else if self.eat(&token::UNDERSCORE) {
             // TYPE TO BE INFERRED
@@ -1438,7 +1458,7 @@ impl<'a> Parser<'a> {
                                    special_idents::invalid)
         };
 
-        let t = self.parse_ty(false);
+        let t = self.parse_ty(true);
 
         Arg {
             ty: t,
@@ -1456,7 +1476,7 @@ impl<'a> Parser<'a> {
     pub fn parse_fn_block_arg(&mut self) -> Arg {
         let pat = self.parse_pat();
         let t = if self.eat(&token::COLON) {
-            self.parse_ty(false)
+            self.parse_ty(true)
         } else {
             P(Ty {
                 id: ast::DUMMY_NODE_ID,
@@ -1611,9 +1631,19 @@ impl<'a> Parser<'a> {
             }
         }
 
-        // Next, parse a colon and bounded type parameters, if applicable.
+        // Next, parse a plus and bounded type parameters, if applicable.
+        //
+        // NOTE(stage0, pcwalton): Remove `token::COLON` after a snapshot.
         let bounds = if mode == LifetimeAndTypesAndBounds {
-            let (_, bounds) = self.parse_optional_ty_param_bounds(false);
+            let bounds = {
+                if self.eat(&token::BINOP(token::PLUS)) ||
+                        self.eat(&token::COLON) {
+                    let (_, bounds) = self.parse_ty_param_bounds(false);
+                    Some(bounds)
+                } else {
+                    None
+                }
+            };
             bounds
         } else {
             None
@@ -2438,7 +2468,7 @@ impl<'a> Parser<'a> {
             }
             None => {
                 if as_prec > min_prec && self.eat_keyword(keywords::As) {
-                    let rhs = self.parse_ty(true);
+                    let rhs = self.parse_ty(false);
                     let _as = self.mk_expr(lhs.span.lo,
                                            rhs.span.hi,
                                            ExprCast(lhs, rhs));
@@ -3067,7 +3097,9 @@ impl<'a> Parser<'a> {
             node: TyInfer,
             span: mk_sp(lo, lo),
         });
-        if self.eat(&token::COLON) { ty = self.parse_ty(false); }
+        if self.eat(&token::COLON) {
+            ty = self.parse_ty(true);
+        }
         let init = self.parse_initializer();
         box(GC) ast::Local {
             ty: ty,
@@ -3095,7 +3127,7 @@ impl<'a> Parser<'a> {
         }
         let name = self.parse_ident();
         self.expect(&token::COLON);
-        let ty = self.parse_ty(false);
+        let ty = self.parse_ty(true);
         spanned(lo, self.last_span.hi, ast::StructField_ {
             kind: NamedField(name, pr),
             id: ast::DUMMY_NODE_ID,
@@ -3427,7 +3459,7 @@ impl<'a> Parser<'a> {
         }
     }
 
-    // matches optbounds = ( ( : ( boundseq )? )? )
+    // matches bounds    = ( boundseq )?
     // where   boundseq  = ( bound + boundseq ) | bound
     // and     bound     = 'static | ty
     // Returns "None" if there's no colon (e.g. "T");
@@ -3439,20 +3471,16 @@ impl<'a> Parser<'a> {
     // AST doesn't support arbitrary lifetimes in bounds on type parameters. In
     // the future, this flag should be removed, and the return value of this
     // function should be Option<~[TyParamBound]>
-    fn parse_optional_ty_param_bounds(&mut self, allow_any_lifetime: bool)
-        -> (Option<ast::Lifetime>, Option<OwnedSlice<TyParamBound>>)
-    {
-        if !self.eat(&token::COLON) {
-            return (None, None);
-        }
-
+    fn parse_ty_param_bounds(&mut self, allow_any_lifetime: bool)
+                             -> (Option<ast::Lifetime>,
+                                 OwnedSlice<TyParamBound>) {
         let mut ret_lifetime = None;
         let mut result = vec!();
         loop {
             match self.token {
                 token::LIFETIME(lifetime) => {
                     let lifetime_interned_string = token::get_ident(lifetime);
-                    if lifetime_interned_string.equiv(&("static")) {
+                    if lifetime_interned_string.equiv(&("'static")) {
                         result.push(StaticRegionTyParamBound);
                         if allow_any_lifetime && ret_lifetime.is_none() {
                             ret_lifetime = Some(ast::Lifetime {
@@ -3489,7 +3517,7 @@ impl<'a> Parser<'a> {
             }
         }
 
-        return (ret_lifetime, Some(OwnedSlice::from_vec(result)));
+        return (ret_lifetime, OwnedSlice::from_vec(result));
     }
 
     // matches typaram = type? IDENT optbounds ( EQ ty )?
@@ -3497,13 +3525,20 @@ impl<'a> Parser<'a> {
         let sized = self.parse_sized();
         let span = self.span;
         let ident = self.parse_ident();
-        let (_, opt_bounds) = self.parse_optional_ty_param_bounds(false);
+        let opt_bounds = {
+            if self.eat(&token::COLON) {
+                let (_, bounds) = self.parse_ty_param_bounds(false);
+                Some(bounds)
+            } else {
+                None
+            }
+        };
         // For typarams we don't care about the difference b/w "<T>" and "<T:>".
         let bounds = opt_bounds.unwrap_or_default();
 
         let default = if self.token == token::EQ {
             self.bump();
-            Some(self.parse_ty(false))
+            Some(self.parse_ty(true))
         }
         else { None };
 
@@ -3548,7 +3583,7 @@ impl<'a> Parser<'a> {
             Some(token::COMMA),
             |p| {
                 p.forbid_lifetime();
-                p.parse_ty(false)
+                p.parse_ty(true)
             }
         );
         (lifetimes, result.into_vec())
@@ -3804,7 +3839,7 @@ impl<'a> Parser<'a> {
             }
         };
         let output = if self.eat(&token::RARROW) {
-            self.parse_ty(false)
+            self.parse_ty(true)
         } else {
             P(Ty {
                 id: ast::DUMMY_NODE_ID,
@@ -3830,7 +3865,7 @@ impl<'a> Parser<'a> {
                                      |p| p.parse_fn_block_arg());
 
         let output = if self.eat(&token::RARROW) {
-            self.parse_ty(false)
+            self.parse_ty(true)
         } else {
             P(Ty {
                 id: ast::DUMMY_NODE_ID,
@@ -3942,7 +3977,7 @@ impl<'a> Parser<'a> {
         let could_be_trait = self.token != token::LPAREN;
 
         // Parse the trait.
-        let mut ty = self.parse_ty(false);
+        let mut ty = self.parse_ty(true);
 
         // Parse traits, if necessary.
         let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) {
@@ -3965,7 +4000,7 @@ impl<'a> Parser<'a> {
                 }
             };
 
-            ty = self.parse_ty(false);
+            ty = self.parse_ty(true);
             opt_trait_ref
         } else {
             None
@@ -4008,7 +4043,7 @@ impl<'a> Parser<'a> {
         let generics = self.parse_generics();
 
         let super_struct = if self.eat(&token::COLON) {
-            let ty = self.parse_ty(false);
+            let ty = self.parse_ty(true);
             match ty.node {
                 TyPath(_, None, _) => {
                     Some(ty)
@@ -4051,7 +4086,7 @@ impl<'a> Parser<'a> {
                 let struct_field_ = ast::StructField_ {
                     kind: UnnamedField(p.parse_visibility()),
                     id: ast::DUMMY_NODE_ID,
-                    ty: p.parse_ty(false),
+                    ty: p.parse_ty(true),
                     attrs: attrs,
                 };
                 spanned(lo, p.span.hi, struct_field_)
@@ -4205,7 +4240,7 @@ impl<'a> Parser<'a> {
         let m = if self.eat_keyword(keywords::Mut) {MutMutable} else {MutImmutable};
         let id = self.parse_ident();
         self.expect(&token::COLON);
-        let ty = self.parse_ty(false);
+        let ty = self.parse_ty(true);
         self.expect(&token::EQ);
         let e = self.parse_expr();
         self.commit_expr_expecting(e, token::SEMI);
@@ -4386,7 +4421,7 @@ impl<'a> Parser<'a> {
 
         let ident = self.parse_ident();
         self.expect(&token::COLON);
-        let ty = self.parse_ty(false);
+        let ty = self.parse_ty(true);
         let hi = self.span.hi;
         self.expect(&token::SEMI);
         box(GC) ast::ForeignItem {
@@ -4514,7 +4549,7 @@ impl<'a> Parser<'a> {
         let ident = self.parse_ident();
         let tps = self.parse_generics();
         self.expect(&token::EQ);
-        let ty = self.parse_ty(false);
+        let ty = self.parse_ty(true);
         self.expect(&token::SEMI);
         (ident, ItemTy(ty, tps), None)
     }
@@ -4562,7 +4597,7 @@ impl<'a> Parser<'a> {
                     &token::LPAREN,
                     &token::RPAREN,
                     seq_sep_trailing_disallowed(token::COMMA),
-                    |p| p.parse_ty(false)
+                    |p| p.parse_ty(true)
                 );
                 for ty in arg_tys.move_iter() {
                     args.push(ast::VariantArg {
@@ -4930,6 +4965,11 @@ impl<'a> Parser<'a> {
         return IoviNone(attrs);
     }
 
+    pub fn parse_item_with_outer_attributes(&mut self) -> Option<Gc<Item>> {
+        let attrs = self.parse_outer_attributes();
+        self.parse_item(attrs)
+    }
+
     pub fn parse_item(&mut self, attrs: Vec<Attribute> ) -> Option<Gc<Item>> {
         match self.parse_item_or_view_item(attrs, true) {
             IoviNone(_) => None,
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index fa70261a7d7..a4a022708d9 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -232,7 +232,7 @@ pub fn to_str(t: &Token) -> String {
       /* Name components */
       IDENT(s, _) => get_ident(s).get().to_string(),
       LIFETIME(s) => {
-          (format!("'{}", get_ident(s))).to_string()
+          (format!("{}", get_ident(s))).to_string()
       }
       UNDERSCORE => "_".to_string(),
 
@@ -433,71 +433,72 @@ declare_special_idents_and_keywords! {
         (0,                          invalid,                "");
         (super::SELF_KEYWORD_NAME,   self_,                  "self");
         (super::STATIC_KEYWORD_NAME, statik,                 "static");
+        (3,                          static_lifetime,        "'static");
 
         // for matcher NTs
-        (3,                          tt,                     "tt");
-        (4,                          matchers,               "matchers");
+        (4,                          tt,                     "tt");
+        (5,                          matchers,               "matchers");
 
         // outside of libsyntax
-        (5,                          clownshoe_abi,          "__rust_abi");
-        (6,                          opaque,                 "<opaque>");
-        (7,                          unnamed_field,          "<unnamed_field>");
-        (8,                          type_self,              "Self");
+        (6,                          clownshoe_abi,          "__rust_abi");
+        (7,                          opaque,                 "<opaque>");
+        (8,                          unnamed_field,          "<unnamed_field>");
+        (9,                          type_self,              "Self");
     }
 
     pub mod keywords {
         // These ones are variants of the Keyword enum
 
         'strict:
-        (9,                          As,         "as");
-        (10,                         Break,      "break");
-        (11,                         Crate,      "crate");
-        (12,                         Else,       "else");
-        (13,                         Enum,       "enum");
-        (14,                         Extern,     "extern");
-        (15,                         False,      "false");
-        (16,                         Fn,         "fn");
-        (17,                         For,        "for");
-        (18,                         If,         "if");
-        (19,                         Impl,       "impl");
-        (20,                         In,         "in");
-        (21,                         Let,        "let");
-        (22,                         Loop,       "loop");
-        (23,                         Match,      "match");
-        (24,                         Mod,        "mod");
-        (25,                         Mut,        "mut");
-        (26,                         Once,       "once");
-        (27,                         Pub,        "pub");
-        (28,                         Ref,        "ref");
-        (29,                         Return,     "return");
+        (10,                         As,         "as");
+        (11,                         Break,      "break");
+        (12,                         Crate,      "crate");
+        (13,                         Else,       "else");
+        (14,                         Enum,       "enum");
+        (15,                         Extern,     "extern");
+        (16,                         False,      "false");
+        (17,                         Fn,         "fn");
+        (18,                         For,        "for");
+        (19,                         If,         "if");
+        (20,                         Impl,       "impl");
+        (21,                         In,         "in");
+        (22,                         Let,        "let");
+        (23,                         Loop,       "loop");
+        (24,                         Match,      "match");
+        (25,                         Mod,        "mod");
+        (26,                         Mut,        "mut");
+        (27,                         Once,       "once");
+        (28,                         Pub,        "pub");
+        (29,                         Ref,        "ref");
+        (30,                         Return,     "return");
         // Static and Self are also special idents (prefill de-dupes)
         (super::STATIC_KEYWORD_NAME, Static,     "static");
         (super::SELF_KEYWORD_NAME,   Self,       "self");
-        (30,                         Struct,     "struct");
-        (31,                         Super,      "super");
-        (32,                         True,       "true");
-        (33,                         Trait,      "trait");
-        (34,                         Type,       "type");
-        (35,                         Unsafe,     "unsafe");
-        (36,                         Use,        "use");
-        (37,                         Virtual,    "virtual");
-        (38,                         While,      "while");
-        (39,                         Continue,   "continue");
-        (40,                         Proc,       "proc");
-        (41,                         Box,        "box");
+        (31,                         Struct,     "struct");
+        (32,                         Super,      "super");
+        (33,                         True,       "true");
+        (34,                         Trait,      "trait");
+        (35,                         Type,       "type");
+        (36,                         Unsafe,     "unsafe");
+        (37,                         Use,        "use");
+        (38,                         Virtual,    "virtual");
+        (39,                         While,      "while");
+        (40,                         Continue,   "continue");
+        (41,                         Proc,       "proc");
+        (42,                         Box,        "box");
 
         'reserved:
-        (42,                         Alignof,    "alignof");
-        (43,                         Be,         "be");
-        (44,                         Const,      "const");
-        (45,                         Offsetof,   "offsetof");
-        (46,                         Priv,       "priv");
-        (47,                         Pure,       "pure");
-        (48,                         Sizeof,     "sizeof");
-        (49,                         Typeof,     "typeof");
-        (50,                         Unsized,    "unsized");
-        (51,                         Yield,      "yield");
-        (52,                         Do,         "do");
+        (43,                         Alignof,    "alignof");
+        (44,                         Be,         "be");
+        (45,                         Const,      "const");
+        (46,                         Offsetof,   "offsetof");
+        (47,                         Priv,       "priv");
+        (48,                         Pure,       "pure");
+        (49,                         Sizeof,     "sizeof");
+        (50,                         Typeof,     "typeof");
+        (51,                         Unsized,    "unsized");
+        (52,                         Yield,      "yield");
+        (53,                         Do,         "do");
     }
 }