Reserve prefixed identifiers and string literals (RFC 3101)
This commit denies any identifiers immediately followed by
one of three tokens `"`, `'` or `#`, which is stricter than
the requirements of RFC 3101 but may be necessary according
to the discussion at [Zulip].
[Zulip]: 238470099
This commit is contained in:
parent
831ae3c136
commit
8dee9bc8fc
5 changed files with 172 additions and 7 deletions
|
@ -5,6 +5,7 @@ use rustc_errors::{error_code, Applicability, DiagnosticBuilder, FatalError, PRe
|
|||
use rustc_lexer::unescape::{self, Mode};
|
||||
use rustc_lexer::{Base, DocStyle, RawStrError};
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_span::{BytePos, Pos, Span};
|
||||
|
||||
|
@ -166,12 +167,18 @@ impl<'a> StringReader<'a> {
|
|||
self.cook_doc_comment(content_start, content, CommentKind::Block, doc_style)
|
||||
}
|
||||
rustc_lexer::TokenKind::Whitespace => return None,
|
||||
rustc_lexer::TokenKind::Ident | rustc_lexer::TokenKind::RawIdent => {
|
||||
rustc_lexer::TokenKind::Ident
|
||||
| rustc_lexer::TokenKind::RawIdent
|
||||
| rustc_lexer::TokenKind::BadPrefix => {
|
||||
let is_raw_ident = token == rustc_lexer::TokenKind::RawIdent;
|
||||
let is_bad_prefix = token == rustc_lexer::TokenKind::BadPrefix;
|
||||
let mut ident_start = start;
|
||||
if is_raw_ident {
|
||||
ident_start = ident_start + BytePos(2);
|
||||
}
|
||||
if is_bad_prefix {
|
||||
self.report_reserved_prefix(start);
|
||||
}
|
||||
let sym = nfc_normalize(self.str_from(ident_start));
|
||||
let span = self.mk_sp(start, self.pos);
|
||||
self.sess.symbol_gallery.insert(sym, span);
|
||||
|
@ -491,6 +498,29 @@ impl<'a> StringReader<'a> {
|
|||
FatalError.raise()
|
||||
}
|
||||
|
||||
fn report_reserved_prefix(&self, start: BytePos) {
|
||||
// See RFC 3101.
|
||||
if self.sess.edition < Edition::Edition2021 {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut err = self.sess.span_diagnostic.struct_span_err(
|
||||
self.mk_sp(start, self.pos),
|
||||
&format!("prefix `{}` is unknown", self.str_from_to(start, self.pos)),
|
||||
);
|
||||
err.span_label(self.mk_sp(start, self.pos), "unknown prefix");
|
||||
err.span_label(
|
||||
self.mk_sp(self.pos, self.pos),
|
||||
&format!(
|
||||
"help: consider inserting a whitespace before this `{}`",
|
||||
self.str_from_to(self.pos, self.pos + BytePos(1)),
|
||||
),
|
||||
);
|
||||
err.note("prefixed identifiers and string literals are reserved since Rust 2021");
|
||||
|
||||
err.emit();
|
||||
}
|
||||
|
||||
/// Note: It was decided to not add a test case, because it would be too big.
|
||||
/// <https://github.com/rust-lang/rust/pull/50296#issuecomment-392135180>
|
||||
fn report_too_many_hashes(&self, start: BytePos, found: usize) -> ! {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue