Skip to content

Commit ecd2673

Browse files
committed
librustc_lexer: Simplify "lifetime_or_char" method
1 parent 6e350bd commit ecd2673

File tree

1 file changed

+37
-30
lines changed

1 file changed

+37
-30
lines changed

src/librustc_lexer/src/lib.rs

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -498,41 +498,48 @@ impl Cursor<'_> {
498498

499499
fn lifetime_or_char(&mut self) -> TokenKind {
500500
debug_assert!(self.prev() == '\'');
501-
let mut starts_with_number = false;
502-
503-
// Check if the first symbol after '\'' is a valid identifier
504-
// character or a number (not a digit followed by '\'').
505-
if (is_id_start(self.nth_char(0))
506-
|| self.nth_char(0).is_digit(10) && {
507-
starts_with_number = true;
508-
true
509-
})
510-
&& self.nth_char(1) != '\''
511-
{
512-
self.bump();
513501

514-
// Skip the identifier.
515-
while is_id_continue(self.nth_char(0)) {
516-
self.bump();
517-
}
502+
let can_be_a_lifetime = if self.second() == '\'' {
503+
// It's surely not a lifetime.
504+
false
505+
} else {
506+
// If the first symbol is valid for identifier, it can be a lifetime.
507+
// Also check if it's a number for a better error reporting (so '0 will
508+
// be reported as invalid lifetime and not as unterminated char literal).
509+
is_id_start(self.first()) || self.first().is_digit(10)
510+
};
518511

519-
return if self.nth_char(0) == '\'' {
520-
self.bump();
521-
let kind = Char { terminated: true };
522-
Literal { kind, suffix_start: self.len_consumed() }
523-
} else {
524-
Lifetime { starts_with_number }
525-
};
512+
if !can_be_a_lifetime {
513+
let terminated = self.single_quoted_string();
514+
let suffix_start = self.len_consumed();
515+
if terminated {
516+
self.eat_literal_suffix();
517+
}
518+
let kind = Char { terminated };
519+
return Literal { kind, suffix_start };
526520
}
527521

528-
// This is not a lifetime (checked above), parse a char literal.
529-
let terminated = self.single_quoted_string();
530-
let suffix_start = self.len_consumed();
531-
if terminated {
532-
self.eat_literal_suffix();
522+
// Either a lifetime or a character literal with
523+
// length greater than 1.
524+
525+
let starts_with_number = self.first().is_digit(10);
526+
527+
// Skip the literal contents.
528+
// First symbol can be a number (which isn't a valid identifier start),
529+
// so skip it without any checks.
530+
self.bump();
531+
self.eat_while(is_id_continue);
532+
533+
// Check if after skipping literal contents we've met a closing
534+
// single quote (which means that user attempted to create a
535+
// string with single quotes).
536+
if self.first() == '\'' {
537+
self.bump();
538+
let kind = Char { terminated: true };
539+
return Literal { kind, suffix_start: self.len_consumed() };
533540
}
534-
let kind = Char { terminated };
535-
return Literal { kind, suffix_start };
541+
542+
return Lifetime { starts_with_number };
536543
}
537544

538545
fn single_quoted_string(&mut self) -> bool {

0 commit comments

Comments
 (0)