diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2014-06-10 13:54:13 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-06-13 13:53:34 -0700 |
| commit | 2ed473487323bb4e5a600a3318e0981981214210 (patch) | |
| tree | a48635d0cac054e7045be8d0fbbd506f4f50b74e /src/libsyntax/parse | |
| parent | e7f11f20e5e72a3b22863a9913df94303321a5ce (diff) | |
| download | rust-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.rs | 39 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 103 |
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"); } } |
