Skip to content
Permalink
Browse files

Parse lifetimes that start with a number and give specific error

  • Loading branch information...
estebank committed Mar 2, 2019
1 parent 2a65cbe commit 0a505a71d3b8d61e982b305caf6d39c227c05957
@@ -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]
@@ -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
}
@@ -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`.

0 comments on commit 0a505a7

Please sign in to comment.
You can’t perform that action at this time.