Skip to content

Commit ea1883d

Browse files
committed
Silence redundant error on char literal that was meant to be a string in 2021 edition
1 parent 6f388ef commit ea1883d

File tree

4 files changed

+20
-15
lines changed

4 files changed

+20
-15
lines changed

compiler/rustc_lexer/src/cursor.rs

+9
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ impl<'a> Cursor<'a> {
5959
iter.next().unwrap_or(EOF_CHAR)
6060
}
6161

62+
/// Peeks the third symbol from the input stream without consuming it.
63+
pub fn third(&self) -> char {
64+
// `.next()` optimizes better than `.nth(1)`
65+
let mut iter = self.chars.clone();
66+
iter.next();
67+
iter.next();
68+
iter.next().unwrap_or(EOF_CHAR)
69+
}
70+
6271
/// Checks if there is nothing more to consume.
6372
pub(crate) fn is_eof(&self) -> bool {
6473
self.chars.as_str().is_empty()

compiler/rustc_parse/src/lexer/mod.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -698,13 +698,17 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
698698
let expn_data = prefix_span.ctxt().outer_expn_data();
699699

700700
if expn_data.edition >= Edition::Edition2021 {
701+
let mut silence = false;
701702
// In Rust 2021, this is a hard error.
702703
let sugg = if prefix == "rb" {
703704
Some(errors::UnknownPrefixSugg::UseBr(prefix_span))
704705
} else if expn_data.is_root() {
705706
if self.cursor.first() == '\''
706707
&& let Some(start) = self.last_lifetime
708+
&& self.cursor.third() != '\''
707709
{
710+
// An "unclosed `char`" error will be emitted already, silence redundant error.
711+
silence = true;
708712
Some(errors::UnknownPrefixSugg::MeantStr {
709713
start,
710714
end: self.mk_sp(self.pos, self.pos + BytePos(1)),
@@ -715,7 +719,12 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
715719
} else {
716720
None
717721
};
718-
self.dcx().emit_err(errors::UnknownPrefix { span: prefix_span, prefix, sugg });
722+
let err = errors::UnknownPrefix { span: prefix_span, prefix, sugg };
723+
if silence {
724+
self.dcx().create_err(err).delay_as_bug();
725+
} else {
726+
self.dcx().emit_err(err);
727+
}
719728
} else {
720729
// Before Rust 2021, only emit a lint for migration.
721730
self.psess.buffer_lint_with_diagnostic(

tests/ui/lexer/lex-bad-str-literal-as-char-3.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@
44
fn main() {
55
println!('hello world');
66
//[rust2015,rust2018,rust2021]~^ ERROR unterminated character literal
7-
//[rust2021]~^^ ERROR prefix `world` is unknown
87
}
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,3 @@
1-
error: prefix `world` is unknown
2-
--> $DIR/lex-bad-str-literal-as-char-3.rs:5:21
3-
|
4-
LL | println!('hello world');
5-
| ^^^^^ unknown prefix
6-
|
7-
= note: prefixed identifiers and literals are reserved since Rust 2021
8-
help: if you meant to write a string literal, use double quotes
9-
|
10-
LL | println!("hello world");
11-
| ~ ~
12-
131
error[E0762]: unterminated character literal
142
--> $DIR/lex-bad-str-literal-as-char-3.rs:5:26
153
|
@@ -21,6 +9,6 @@ help: if you meant to write a string literal, use double quotes
219
LL | println!("hello world");
2210
| ~ ~
2311

24-
error: aborting due to 2 previous errors
12+
error: aborting due to 1 previous error
2513

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

0 commit comments

Comments
 (0)