about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2014-06-10 13:54:13 -0700
committerAlex Crichton <alex@alexcrichton.com>2014-06-13 13:53:34 -0700
commit2ed473487323bb4e5a600a3318e0981981214210 (patch)
treea48635d0cac054e7045be8d0fbbd506f4f50b74e /src/libsyntax/parse
parente7f11f20e5e72a3b22863a9913df94303321a5ce (diff)
downloadrust-2ed473487323bb4e5a600a3318e0981981214210.tar.gz
rust-2ed473487323bb4e5a600a3318e0981981214210.zip
librustc: Fix the issue with labels shadowing variable names by making
the leading quote part of the identifier for the purposes of hygiene.

This adopts @jbclements' solution to #14539.

I'm not sure if this is a breaking change or not.

Closes #12512.

[breaking-change]
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/lexer/mod.rs39
-rw-r--r--src/libsyntax/parse/parser.rs2
-rw-r--r--src/libsyntax/parse/token.rs103
3 files changed, 80 insertions, 64 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/parser.rs b/src/libsyntax/parse/parser.rs
index 437b06e3df6..aaedb570955 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -3452,7 +3452,7 @@ impl<'a> Parser<'a> {
             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 {
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");
     }
 }