Reserve prefix lifetimes too
This commit is contained in:
parent
59d4114b2d
commit
9aaf873396
@ -91,6 +91,12 @@ pub enum TokenKind {
|
||||
/// tokens.
|
||||
UnknownPrefix,
|
||||
|
||||
/// An unknown prefix in a lifetime, like `'foo#`.
|
||||
///
|
||||
/// Note that like above, only the `'` and prefix are included in the token
|
||||
/// and not the separator.
|
||||
UnknownPrefixLifetime,
|
||||
|
||||
/// Similar to the above, but *always* an error on every edition. This is used
|
||||
/// for emoji identifier recovery, as those are not meant to be ever accepted.
|
||||
InvalidPrefix,
|
||||
@ -688,15 +694,17 @@ fn lifetime_or_char(&mut self) -> TokenKind {
|
||||
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 };
|
||||
Literal { kind, suffix_start: self.pos_within_token() }
|
||||
} else {
|
||||
Lifetime { starts_with_number }
|
||||
match self.first() {
|
||||
// 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).
|
||||
'\'' => {
|
||||
self.bump();
|
||||
let kind = Char { terminated: true };
|
||||
Literal { kind, suffix_start: self.pos_within_token() }
|
||||
}
|
||||
'#' if !starts_with_number => UnknownPrefixLifetime,
|
||||
_ => Lifetime { starts_with_number },
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,6 +205,16 @@ fn next_token(&mut self) -> (Token, bool) {
|
||||
self.report_unknown_prefix(start);
|
||||
self.ident(start)
|
||||
}
|
||||
rustc_lexer::TokenKind::UnknownPrefixLifetime => {
|
||||
self.report_unknown_prefix(start);
|
||||
// Include the leading `'` in the real identifier, for macro
|
||||
// expansion purposes. See #12512 for the gory details of why
|
||||
// this is necessary.
|
||||
let lifetime_name = self.str_from(start);
|
||||
self.last_lifetime = Some(self.mk_sp(start, start + BytePos(1)));
|
||||
let ident = Symbol::intern(lifetime_name);
|
||||
token::Lifetime(ident, IdentIsRaw::No)
|
||||
}
|
||||
rustc_lexer::TokenKind::InvalidIdent
|
||||
| rustc_lexer::TokenKind::InvalidPrefix
|
||||
// Do not recover an identifier with emoji if the codepoint is a confusable
|
||||
|
10
tests/ui/lexer/prefixed-lifetime.rs
Normal file
10
tests/ui/lexer/prefixed-lifetime.rs
Normal file
@ -0,0 +1,10 @@
|
||||
//@ edition: 2021
|
||||
|
||||
macro_rules! w {
|
||||
($($tt:tt)*) => {};
|
||||
}
|
||||
|
||||
w!('foo#lifetime);
|
||||
//~^ ERROR prefix `'foo` is unknown
|
||||
|
||||
fn main() {}
|
14
tests/ui/lexer/prefixed-lifetime.stderr
Normal file
14
tests/ui/lexer/prefixed-lifetime.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: prefix `'foo` is unknown
|
||||
--> $DIR/prefixed-lifetime.rs:7:4
|
||||
|
|
||||
LL | w!('foo#lifetime);
|
||||
| ^^^^ unknown prefix
|
||||
|
|
||||
= note: prefixed identifiers and literals are reserved since Rust 2021
|
||||
help: consider inserting whitespace here
|
||||
|
|
||||
LL | w!('foo #lifetime);
|
||||
| +
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
Loading…
Reference in New Issue
Block a user