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 | |
| parent | 2a65cbeea78c2c79b1030a0012cdea475104a44f (diff) | |
| download | rust-0a505a71d3b8d61e982b305caf6d39c227c05957.tar.gz rust-0a505a71d3b8d61e982b305caf6d39c227c05957.zip | |
Parse lifetimes that start with a number and give specific error
| -rw-r--r-- | src/libsyntax/parse/lexer/mod.rs | 24 | ||||
| -rw-r--r-- | src/test/ui/parser/numeric-lifetime.rs | 8 | ||||
| -rw-r--r-- | src/test/ui/parser/numeric-lifetime.stderr | 24 |
3 files changed, 50 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] diff --git a/src/test/ui/parser/numeric-lifetime.rs b/src/test/ui/parser/numeric-lifetime.rs new file mode 100644 index 00000000000..3483975a3cb --- /dev/null +++ b/src/test/ui/parser/numeric-lifetime.rs @@ -0,0 +1,8 @@ +struct S<'1> { s: &'1 usize } +//~^ ERROR lifetimes can't start with a number +//~| ERROR lifetimes can't start with a number +fn main() { + // verify that the parse error doesn't stop type checking + let x: usize = ""; + //~^ ERROR mismatched types +} diff --git a/src/test/ui/parser/numeric-lifetime.stderr b/src/test/ui/parser/numeric-lifetime.stderr new file mode 100644 index 00000000000..1bbc508d57d --- /dev/null +++ b/src/test/ui/parser/numeric-lifetime.stderr @@ -0,0 +1,24 @@ +error: lifetimes can't start with a number + --> $DIR/numeric-lifetime.rs:1:10 + | +LL | struct S<'1> { s: &'1 usize } + | ^^ + +error: lifetimes can't start with a number + --> $DIR/numeric-lifetime.rs:1:20 + | +LL | struct S<'1> { s: &'1 usize } + | ^^ + +error[E0308]: mismatched types + --> $DIR/numeric-lifetime.rs:6:20 + | +LL | let x: usize = ""; + | ^^ expected usize, found reference + | + = note: expected type `usize` + found type `&'static str` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. |
