Skip to content

Commit 83f35c0

Browse files
committed
Treat k#ident keywords as valid tokens
1 parent 8d76d07 commit 83f35c0

File tree

8 files changed

+44
-2
lines changed

8 files changed

+44
-2
lines changed

compiler/rustc_ast/src/token.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,10 @@ pub enum TokenKind {
299299
/// It's recommended to use `Token::(ident,uninterpolate,uninterpolated_span)` to
300300
/// treat regular and interpolated identifiers in the same way.
301301
Ident(Symbol, /* is_raw */ bool),
302+
303+
/// A `k#ident` keyword
304+
Keyword(Symbol),
305+
302306
/// Lifetime identifier token.
303307
/// Do not forget about `NtLifetime` when you want to match on lifetime identifiers.
304308
/// It's recommended to use `Token::(lifetime,uninterpolate,uninterpolated_span)` to
@@ -438,7 +442,7 @@ impl Token {
438442
| ModSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question | SingleQuote => true,
439443

440444
OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) | Ident(..)
441-
| Lifetime(..) | Interpolated(..) | Eof => false,
445+
| Keyword(..) | Lifetime(..) | Interpolated(..) | Eof => false,
442446
}
443447
}
444448

@@ -812,7 +816,7 @@ impl Token {
812816

813817
Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot
814818
| DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar
815-
| Question | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..)
819+
| Question | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..) | Keyword(..)
816820
| Lifetime(..) | Interpolated(..) | DocComment(..) | Eof => return None,
817821
};
818822

compiler/rustc_ast_pretty/src/pprust/state.rs

+1
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
781781
token::Ident(s, is_raw) => {
782782
IdentPrinter::new(s, is_raw, convert_dollar_crate).to_string().into()
783783
}
784+
token::Keyword(s) => format!("k#{s}").into(),
784785
token::Lifetime(s) => s.to_string().into(),
785786

786787
/* Other */

compiler/rustc_expand/src/proc_macro_server.rs

+5
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,11 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre
203203
SingleQuote => op("'"),
204204

205205
Ident(sym, is_raw) => trees.push(TokenTree::Ident(Ident { sym, is_raw, span })),
206+
Keyword(sym) => trees.extend([
207+
TokenTree::Ident(Ident { sym: sym::k, is_raw: false, span }),
208+
TokenTree::Punct(Punct { ch: b'#', joint: true, span }),
209+
TokenTree::Ident(Ident { sym, is_raw: false, span }),
210+
]),
206211
Lifetime(name) => {
207212
let ident = symbol::Ident::new(name, span).without_first_quote();
208213
trees.extend([

compiler/rustc_lexer/src/lib.rs

+17
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ pub enum TokenKind {
7878
/// "r#ident"
7979
RawIdent,
8080

81+
/// "k#ident"
82+
KeywordIdent,
83+
8184
/// An unknown prefix, like `foo#`, `foo'`, `foo"`.
8285
///
8386
/// Note that only the
@@ -375,6 +378,11 @@ impl Cursor<'_> {
375378
None,
376379
),
377380

381+
'k' => match (self.first(), self.second()) {
382+
('#', c1) if is_id_start(c1) => self.keyword_ident(),
383+
_ => self.ident_or_unknown_prefix(),
384+
},
385+
378386
// Identifier (this should be checked after other variant that can
379387
// start as identifier).
380388
c if is_id_start(c) => self.ident_or_unknown_prefix(),
@@ -505,6 +513,15 @@ impl Cursor<'_> {
505513
RawIdent
506514
}
507515

516+
fn keyword_ident(&mut self) -> TokenKind {
517+
debug_assert!(self.prev() == 'k' && self.first() == '#' && is_id_start(self.second()));
518+
// Eat "#" symbol.
519+
self.bump();
520+
// Eat the identifier part of KeywordIdent.
521+
self.eat_identifier();
522+
KeywordIdent
523+
}
524+
508525
fn ident_or_unknown_prefix(&mut self) -> TokenKind {
509526
debug_assert!(is_id_start(self.prev()));
510527
// Start is already eaten, eat the rest of identifier.

compiler/rustc_parse/src/lexer/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,18 @@ impl<'a> StringReader<'a> {
185185
self.sess.raw_identifier_spans.push(span);
186186
token::Ident(sym, true)
187187
}
188+
// Treat `k#ident` as a normal identifier token before 2021.
189+
rustc_lexer::TokenKind::KeywordIdent if !self.mk_sp(start, self.pos).edition().at_least_rust_2021() => {
190+
// FIXME: what should we do when this is a _known_ prefix?
191+
self.report_unknown_prefix(start);
192+
self.ident(start)
193+
}
194+
rustc_lexer::TokenKind::KeywordIdent => {
195+
let sym = nfc_normalize(self.str_from(start));
196+
let span = self.mk_sp(start, self.pos);
197+
self.sess.symbol_gallery.insert(sym, span);
198+
token::Keyword(sym)
199+
}
188200
rustc_lexer::TokenKind::UnknownPrefix => {
189201
self.report_unknown_prefix(start);
190202
self.ident(start)

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,7 @@ symbols! {
918918
iter_repeat,
919919
iterator,
920920
iterator_collect_fn,
921+
k,
921922
kcfi,
922923
keyword,
923924
kind,

src/librustdoc/html/highlight.rs

+1
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,7 @@ impl<'src> Classifier<'src> {
878878
TokenKind::RawIdent | TokenKind::UnknownPrefix | TokenKind::InvalidIdent => {
879879
Class::Ident(self.new_span(before, text))
880880
}
881+
TokenKind::KeywordIdent => Class::KeyWord,
881882
TokenKind::Lifetime { .. } => Class::Lifetime,
882883
TokenKind::Eof => panic!("Eof in advance"),
883884
};

src/tools/rust-analyzer/crates/parser/src/lexed_str.rs

+1
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ impl<'a> Converter<'a> {
224224
rustc_lexer::TokenKind::Slash => T![/],
225225
rustc_lexer::TokenKind::Caret => T![^],
226226
rustc_lexer::TokenKind::Percent => T![%],
227+
rustc_lexer::TokenKind::KeywordIdent => ERROR,
227228
rustc_lexer::TokenKind::Unknown => ERROR,
228229
rustc_lexer::TokenKind::UnknownPrefix if token_text == "builtin" => IDENT,
229230
rustc_lexer::TokenKind::UnknownPrefix => {

0 commit comments

Comments
 (0)