Skip to content

Commit 789aca0

Browse files
authored
Rollup merge of rust-lang#58876 - estebank:numeric-lifetime, r=petrochenkov
Parse lifetimes that start with a number and give specific error Fix rust-lang#58786.
2 parents 81920ff + f690821 commit 789aca0

File tree

3 files changed

+47
-3
lines changed

3 files changed

+47
-3
lines changed

src/libsyntax/parse/lexer/mod.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -1423,15 +1423,17 @@ impl<'a> StringReader<'a> {
14231423

14241424
// If the character is an ident start not followed by another single
14251425
// quote, then this is a lifetime name:
1426-
if ident_start(Some(c2)) && !self.ch_is('\'') {
1426+
if (ident_start(Some(c2)) || c2.is_numeric()) && !self.ch_is('\'') {
14271427
while ident_continue(self.ch) {
14281428
self.bump();
14291429
}
14301430
// lifetimes shouldn't end with a single quote
14311431
// if we find one, then this is an invalid character literal
14321432
if self.ch_is('\'') {
1433-
self.err_span_(start_with_quote, self.next_pos,
1434-
"character literal may only contain one codepoint");
1433+
self.err_span_(
1434+
start_with_quote,
1435+
self.next_pos,
1436+
"character literal may only contain one codepoint");
14351437
self.bump();
14361438
return Ok(token::Literal(token::Err(Symbol::intern("??")), None))
14371439

@@ -1444,6 +1446,15 @@ impl<'a> StringReader<'a> {
14441446
self.mk_ident(&format!("'{}", lifetime_name))
14451447
});
14461448

1449+
if c2.is_numeric() {
1450+
// this is a recovered lifetime written `'1`, error but accept it
1451+
self.err_span_(
1452+
start_with_quote,
1453+
self.pos,
1454+
"lifetimes cannot start with a number",
1455+
);
1456+
}
1457+
14471458
return Ok(token::Lifetime(ident));
14481459
}
14491460

@@ -1873,6 +1884,7 @@ fn is_block_doc_comment(s: &str) -> bool {
18731884
res
18741885
}
18751886

1887+
/// Determine whether `c` is a valid start for an ident.
18761888
fn ident_start(c: Option<char>) -> bool {
18771889
let c = match c {
18781890
Some(c) => c,
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
struct S<'1> { s: &'1 usize }
2+
//~^ ERROR lifetimes cannot start with a number
3+
//~| ERROR lifetimes cannot start with a number
4+
fn main() {
5+
// verify that the parse error doesn't stop type checking
6+
let x: usize = "";
7+
//~^ ERROR mismatched types
8+
}
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error: lifetimes cannot start with a number
2+
--> $DIR/numeric-lifetime.rs:1:10
3+
|
4+
LL | struct S<'1> { s: &'1 usize }
5+
| ^^
6+
7+
error: lifetimes cannot start with a number
8+
--> $DIR/numeric-lifetime.rs:1:20
9+
|
10+
LL | struct S<'1> { s: &'1 usize }
11+
| ^^
12+
13+
error[E0308]: mismatched types
14+
--> $DIR/numeric-lifetime.rs:6:20
15+
|
16+
LL | let x: usize = "";
17+
| ^^ expected usize, found reference
18+
|
19+
= note: expected type `usize`
20+
found type `&'static str`
21+
22+
error: aborting due to 3 previous errors
23+
24+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)