Skip to content

Commit

Permalink
Rollup merge of rust-lang#58876 - estebank:numeric-lifetime, r=petroc…
Browse files Browse the repository at this point in the history
…henkov

Parse lifetimes that start with a number and give specific error

Fix rust-lang#58786.
  • Loading branch information
Centril authored Mar 10, 2019
2 parents f847d3d + f690821 commit 2eeca49
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 3 deletions.
18 changes: 15 additions & 3 deletions src/libsyntax/parse/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))

Expand All @@ -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));
}

Expand Down Expand Up @@ -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,
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/parser/numeric-lifetime.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
struct S<'1> { s: &'1 usize }
//~^ ERROR lifetimes cannot start with a number
//~| ERROR lifetimes cannot start with a number
fn main() {
// verify that the parse error doesn't stop type checking
let x: usize = "";
//~^ ERROR mismatched types
}
24 changes: 24 additions & 0 deletions src/test/ui/parser/numeric-lifetime.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
error: lifetimes cannot start with a number
--> $DIR/numeric-lifetime.rs:1:10
|
LL | struct S<'1> { s: &'1 usize }
| ^^

error: lifetimes cannot 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`.

0 comments on commit 2eeca49

Please sign in to comment.