Skip to content

Commit c57f512

Browse files
author
Julian Wollersberger
committed
Implement raw keywords in the lexer and always emit an error, if encountered.
1 parent 080d302 commit c57f512

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

compiler/rustc_lexer/src/lib.rs

+15
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ pub enum TokenKind {
6666
Ident,
6767
/// "r#ident"
6868
RawIdent,
69+
/// "k#ident"
70+
/// Unstable feature handling is done in rustc_parse/src/lexer/mod.rs
71+
RawKeyword,
6972
/// "12_u8", "1.0e-40", "b"123"". See `LiteralKind` for more details.
7073
Literal { kind: LiteralKind, suffix_start: usize },
7174
/// "'a"
@@ -361,6 +364,9 @@ impl Cursor<'_> {
361364
_ => self.ident(),
362365
},
363366

367+
// Raw keyword
368+
'k' if self.first() == '#' && is_id_start(self.second()) => self.raw_keyword(),
369+
364370
// Identifier (this should be checked after other variant that can
365371
// start as identifier).
366372
c if is_id_start(c) => self.ident(),
@@ -487,6 +493,15 @@ impl Cursor<'_> {
487493
RawIdent
488494
}
489495

496+
fn raw_keyword(&mut self) -> TokenKind {
497+
debug_assert!(self.prev() == 'k' && self.first() == '#' && is_id_start(self.second()));
498+
// Eat "#" symbol.
499+
self.bump();
500+
// Eat the identifier part of the keyword.
501+
self.eat_identifier();
502+
RawKeyword
503+
}
504+
490505
fn ident(&mut self) -> TokenKind {
491506
debug_assert!(is_id_start(self.prev()));
492507
// Start is already eaten, eat the rest of identifier.

compiler/rustc_parse/src/lexer/mod.rs

+19
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,25 @@ impl<'a> StringReader<'a> {
187187
}
188188
token::Ident(sym, is_raw_ident)
189189
}
190+
rustc_lexer::TokenKind::RawKeyword => {
191+
let span = self.mk_sp(start, self.pos);
192+
self.sess
193+
.span_diagnostic
194+
.struct_span_err(span, "raw keyword syntax is reserved for future use")
195+
// With whitespace, it tokenizes as three tokens, just like before this reservation.
196+
.span_suggestion(
197+
span,
198+
"insert a whitespace",
199+
format!("k #{}", self.str_from(start + BytePos(2))),
200+
Applicability::MachineApplicable,
201+
)
202+
.emit();
203+
204+
let sym = nfc_normalize(self.str_from(start + BytePos(2)));
205+
// For recovery, treat it as a raw ident.
206+
// FIXME: Add a flag to Ident to mark it as a raw keyword.
207+
token::Ident(sym, true)
208+
}
190209
rustc_lexer::TokenKind::Literal { kind, suffix_start } => {
191210
let suffix_start = start + BytePos(suffix_start as u32);
192211
let (kind, symbol) = self.cook_lexer_literal(start, suffix_start, kind);

src/librustdoc/html/highlight.rs

+2
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,8 @@ impl<'a> Classifier<'a> {
408408
c => c,
409409
},
410410
TokenKind::RawIdent => Class::Ident,
411+
//TODO How do I test this?
412+
TokenKind::RawKeyword => Class::KeyWord,
411413
TokenKind::Lifetime { .. } => Class::Lifetime,
412414
};
413415
// Anything that didn't return above is the simple case where we the

0 commit comments

Comments
 (0)