Skip to content

Commit

Permalink
Silence redundant error on char literal that was meant to be a string…
Browse files Browse the repository at this point in the history
… in 2021 edition
  • Loading branch information
estebank committed Mar 14, 2024
1 parent 6fd0984 commit 11e9cb8
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 15 deletions.
9 changes: 9 additions & 0 deletions compiler/rustc_lexer/src/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ impl<'a> Cursor<'a> {
iter.next().unwrap_or(EOF_CHAR)
}

/// Peeks the third symbol from the input stream without consuming it.
pub fn third(&self) -> char {
// `.next()` optimizes better than `.nth(1)`
let mut iter = self.chars.clone();
iter.next();
iter.next();
iter.next().unwrap_or(EOF_CHAR)
}

/// Checks if there is nothing more to consume.
pub(crate) fn is_eof(&self) -> bool {
self.chars.as_str().is_empty()
Expand Down
11 changes: 10 additions & 1 deletion compiler/rustc_parse/src/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -698,13 +698,17 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
let expn_data = prefix_span.ctxt().outer_expn_data();

if expn_data.edition >= Edition::Edition2021 {
let mut silence = false;
// In Rust 2021, this is a hard error.
let sugg = if prefix == "rb" {
Some(errors::UnknownPrefixSugg::UseBr(prefix_span))
} else if expn_data.is_root() {
if self.cursor.first() == '\''
&& let Some(start) = self.last_lifetime
&& self.cursor.third() != '\''
{
// An "unclosed `char`" error will be emitted already, silence redundant error.
silence = true;
Some(errors::UnknownPrefixSugg::MeantStr {
start,
end: self.mk_sp(self.pos, self.pos + BytePos(1)),
Expand All @@ -715,7 +719,12 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
} else {
None
};
self.dcx().emit_err(errors::UnknownPrefix { span: prefix_span, prefix, sugg });
let err = errors::UnknownPrefix { span: prefix_span, prefix, sugg };
if silence {
self.dcx().create_err(err).delay_as_bug();
} else {
self.dcx().emit_err(err);
}
} else {
// Before Rust 2021, only emit a lint for migration.
self.psess.buffer_lint_with_diagnostic(
Expand Down
1 change: 0 additions & 1 deletion tests/ui/lexer/lex-bad-str-literal-as-char-3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@
fn main() {
println!('hello world');
//[rust2015,rust2018,rust2021]~^ ERROR unterminated character literal
//[rust2021]~^^ ERROR prefix `world` is unknown
}
14 changes: 1 addition & 13 deletions tests/ui/lexer/lex-bad-str-literal-as-char-3.rust2021.stderr
Original file line number Diff line number Diff line change
@@ -1,15 +1,3 @@
error: prefix `world` is unknown
--> $DIR/lex-bad-str-literal-as-char-3.rs:5:21
|
LL | println!('hello world');
| ^^^^^ unknown prefix
|
= note: prefixed identifiers and literals are reserved since Rust 2021
help: if you meant to write a string literal, use double quotes
|
LL | println!("hello world");
| ~ ~

error[E0762]: unterminated character literal
--> $DIR/lex-bad-str-literal-as-char-3.rs:5:26
|
Expand All @@ -21,6 +9,6 @@ help: if you meant to write a string literal, use double quotes
LL | println!("hello world");
| ~ ~

error: aborting due to 2 previous errors
error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0762`.

0 comments on commit 11e9cb8

Please sign in to comment.