diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 69b48bf0aff71..f381995d346bd 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -698,7 +698,6 @@ 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)) @@ -706,25 +705,20 @@ impl<'psess, 'src> StringReader<'psess, 'src> { if self.cursor.first() == '\'' && let Some(start) = self.last_lifetime && self.cursor.third() != '\'' + && let end = self.mk_sp(self.pos, self.pos + BytePos(1)) + && !self.psess.source_map().is_multiline(start.until(end)) { - // 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)), - }) + // FIXME: An "unclosed `char`" error will be emitted already in some cases, + // but it's hard to silence this error while not also silencing important cases + // too. We should use the error stashing machinery instead. + Some(errors::UnknownPrefixSugg::MeantStr { start, end }) } else { Some(errors::UnknownPrefixSugg::Whitespace(prefix_span.shrink_to_hi())) } } else { None }; - 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); - } + self.dcx().emit_err(errors::UnknownPrefix { span: prefix_span, prefix, sugg }); } else { // Before Rust 2021, only emit a lint for migration. self.psess.buffer_lint_with_diagnostic( diff --git a/tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.rs b/tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.rs new file mode 100644 index 0000000000000..caae48dfd3bdf --- /dev/null +++ b/tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.rs @@ -0,0 +1,9 @@ +//@ edition:2021 +macro_rules! a { + ( ) => { + impl<'b> c for d { + e:: //~ ERROR prefix `f` is unknown + } + }; +} +fn main() {} diff --git a/tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.stderr b/tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.stderr new file mode 100644 index 0000000000000..ecce2c6650459 --- /dev/null +++ b/tests/ui/lexer/dont-ice-on-invalid-lifetime-in-macro-definition.stderr @@ -0,0 +1,14 @@ +error: prefix `f` is unknown + --> $DIR/dont-ice-on-invalid-lifetime-in-macro-definition.rs:5:17 + | +LL | e:: + | ^ unknown prefix + | + = note: prefixed identifiers and literals are reserved since Rust 2021 +help: consider inserting whitespace here + | +LL | e:: + | + + +error: aborting due to 1 previous error + diff --git a/tests/ui/lexer/lex-bad-str-literal-as-char-3.rs b/tests/ui/lexer/lex-bad-str-literal-as-char-3.rs index 0ae227da5f1e6..52781d9c6d858 100644 --- a/tests/ui/lexer/lex-bad-str-literal-as-char-3.rs +++ b/tests/ui/lexer/lex-bad-str-literal-as-char-3.rs @@ -3,5 +3,6 @@ //@[rust2021] edition:2021 fn main() { println!('hello world'); - //[rust2015,rust2018,rust2021]~^ ERROR unterminated character literal + //~^ ERROR unterminated character literal + //[rust2021]~| ERROR prefix `world` is unknown } diff --git a/tests/ui/lexer/lex-bad-str-literal-as-char-3.rust2021.stderr b/tests/ui/lexer/lex-bad-str-literal-as-char-3.rust2021.stderr index 06f127426679f..4170560cfcb04 100644 --- a/tests/ui/lexer/lex-bad-str-literal-as-char-3.rust2021.stderr +++ b/tests/ui/lexer/lex-bad-str-literal-as-char-3.rust2021.stderr @@ -1,3 +1,15 @@ +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 | @@ -9,6 +21,6 @@ help: if you meant to write a string literal, use double quotes LL | println!("hello world"); | ~ ~ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0762`. diff --git a/tests/ui/lexer/lex-bad-str-literal-as-char-4.rs b/tests/ui/lexer/lex-bad-str-literal-as-char-4.rs new file mode 100644 index 0000000000000..f0c7ad8f82b7e --- /dev/null +++ b/tests/ui/lexer/lex-bad-str-literal-as-char-4.rs @@ -0,0 +1,9 @@ +//@edition:2021 +macro_rules! foo { + () => { + println!('hello world'); + //~^ ERROR unterminated character literal + //~| ERROR prefix `world` is unknown + } +} +fn main() {} diff --git a/tests/ui/lexer/lex-bad-str-literal-as-char-4.stderr b/tests/ui/lexer/lex-bad-str-literal-as-char-4.stderr new file mode 100644 index 0000000000000..af42b5b7f7b78 --- /dev/null +++ b/tests/ui/lexer/lex-bad-str-literal-as-char-4.stderr @@ -0,0 +1,26 @@ +error: prefix `world` is unknown + --> $DIR/lex-bad-str-literal-as-char-4.rs:4:25 + | +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-4.rs:4:30 + | +LL | println!('hello world'); + | ^^^ + | +help: if you meant to write a string literal, use double quotes + | +LL | println!("hello world"); + | ~ ~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0762`.