// 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))
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));
}
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,
false,
false);
ParseSess {
- span_diagnostic: errors::Handler::with_emitter(true, false, Box::new(emitter)),
+ span_diagnostic: errors::Handler::with_emitter(true, None, Box::new(emitter)),
unstable_features: UnstableFeatures::from_environment(),
config: CrateConfig::default(),
included_mod_stack: Lock::new(Vec::new()),