about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-03-13 03:33:36 +0100
committerGitHub <noreply@github.com>2019-03-13 03:33:36 +0100
commitad7b6508156b7455fc2d996062c7ab63cc4119e7 (patch)
tree8b1df85119fd76215c8cfe64392a73c73fe013f3 /src/libsyntax/parse
parent445c4bc0f878292f0b0a5b7e6080a996f74e44b1 (diff)
parentf690821d58650358f536606722a8f5531c8a6b84 (diff)
downloadrust-ad7b6508156b7455fc2d996062c7ab63cc4119e7.tar.gz
rust-ad7b6508156b7455fc2d996062c7ab63cc4119e7.zip
Rollup merge of #58876 - estebank:numeric-lifetime, r=petrochenkov
Parse lifetimes that start with a number and give specific error

Fix #58786.
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/lexer/mod.rs18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index db5b8dcda4e..01e3b292903 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,15 @@ 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 cannot start with a number",
+                        );
+                    }
+
                     return Ok(token::Lifetime(ident));
                 }
 
@@ -1873,6 +1884,7 @@ 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,