librustc_lexer: Simplify "lifetime_or_char" method

This commit is contained in:
Igor Aleksanov 2019-11-03 12:56:49 +03:00
parent 6e350bd999
commit ecd26739d4

View File

@ -498,41 +498,48 @@ impl Cursor<'_> {
fn lifetime_or_char(&mut self) -> TokenKind { fn lifetime_or_char(&mut self) -> TokenKind {
debug_assert!(self.prev() == '\''); debug_assert!(self.prev() == '\'');
let mut starts_with_number = false;
// Check if the first symbol after '\'' is a valid identifier let can_be_a_lifetime = if self.second() == '\'' {
// character or a number (not a digit followed by '\''). // It's surely not a lifetime.
if (is_id_start(self.nth_char(0)) false
|| self.nth_char(0).is_digit(10) && { } else {
starts_with_number = true; // If the first symbol is valid for identifier, it can be a lifetime.
true // Also check if it's a number for a better error reporting (so '0 will
}) // be reported as invalid lifetime and not as unterminated char literal).
&& self.nth_char(1) != '\'' is_id_start(self.first()) || self.first().is_digit(10)
{ };
self.bump();
// Skip the identifier. if !can_be_a_lifetime {
while is_id_continue(self.nth_char(0)) { let terminated = self.single_quoted_string();
self.bump(); let suffix_start = self.len_consumed();
if terminated {
self.eat_literal_suffix();
} }
let kind = Char { terminated };
return if self.nth_char(0) == '\'' { return Literal { kind, suffix_start };
self.bump();
let kind = Char { terminated: true };
Literal { kind, suffix_start: self.len_consumed() }
} else {
Lifetime { starts_with_number }
};
} }
// This is not a lifetime (checked above), parse a char literal. // Either a lifetime or a character literal with
let terminated = self.single_quoted_string(); // length greater than 1.
let suffix_start = self.len_consumed();
if terminated { let starts_with_number = self.first().is_digit(10);
self.eat_literal_suffix();
// Skip the literal contents.
// First symbol can be a number (which isn't a valid identifier start),
// so skip it without any checks.
self.bump();
self.eat_while(is_id_continue);
// Check if after skipping literal contents we've met a closing
// single quote (which means that user attempted to create a
// string with single quotes).
if self.first() == '\'' {
self.bump();
let kind = Char { terminated: true };
return Literal { kind, suffix_start: self.len_consumed() };
} }
let kind = Char { terminated };
return Literal { kind, suffix_start }; return Lifetime { starts_with_number };
} }
fn single_quoted_string(&mut self) -> bool { fn single_quoted_string(&mut self) -> bool {