diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2019-03-02 10:38:20 -0800 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2019-03-08 16:56:31 -0800 |
| commit | 0a505a71d3b8d61e982b305caf6d39c227c05957 (patch) | |
| tree | ae9b56e65d089bcfdee6db0f5620213863f75d9d /src/libsyntax/parse | |
| parent | 2a65cbeea78c2c79b1030a0012cdea475104a44f (diff) | |
| download | rust-0a505a71d3b8d61e982b305caf6d39c227c05957.tar.gz rust-0a505a71d3b8d61e982b305caf6d39c227c05957.zip | |
Parse lifetimes that start with a number and give specific error
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/lexer/mod.rs | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index a7cde5fbb92..f45f5e65312 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1423,15 +1423,17 @@ impl<'a> StringReader<'a> { // If the character is an ident start not followed by another single // quote, then this is a lifetime name: - if ident_start(Some(c2)) && !self.ch_is('\'') { + if (ident_start(Some(c2)) || c2.is_numeric()) && !self.ch_is('\'') { while ident_continue(self.ch) { self.bump(); } // lifetimes shouldn't end with a single quote // if we find one, then this is an invalid character literal if self.ch_is('\'') { - self.err_span_(start_with_quote, self.next_pos, - "character literal may only contain one codepoint"); + self.err_span_( + start_with_quote, + self.next_pos, + "character literal may only contain one codepoint"); self.bump(); return Ok(token::Literal(token::Err(Symbol::intern("??")), None)) @@ -1444,6 +1446,16 @@ impl<'a> StringReader<'a> { self.mk_ident(&format!("'{}", lifetime_name)) }); + if c2.is_numeric() { + // this is a recovered lifetime written `'1`, error but accept it + self.err_span_( + start_with_quote, + self.pos, + "lifetimes can't start with a number", + ); + } + + return Ok(token::Lifetime(ident)); } @@ -1873,13 +1885,14 @@ fn is_block_doc_comment(s: &str) -> bool { res } +/// Determine whether `c` is a valid start for an ident. fn ident_start(c: Option<char>) -> bool { let c = match c { Some(c) => c, None => return false, }; - (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c > '\x7f' && c.is_xid_start()) + (c.is_alphabetic() || c == '_' || (c > '\x7f' && c.is_xid_start())) } fn ident_continue(c: Option<char>) -> bool { @@ -1888,8 +1901,7 @@ fn ident_continue(c: Option<char>) -> bool { None => return false, }; - (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_' || - (c > '\x7f' && c.is_xid_continue()) + (c.is_alphabetic() || c.is_numeric() || c == '_' || (c > '\x7f' && c.is_xid_continue())) } #[inline] |
