From 3b5d018ebb6ee8aa6181ebf1cf9ba0cb407f622f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 23 Jan 2021 12:48:31 -0800 Subject: [PATCH] Handle `Span`s for byte and raw strings and add more detail --- compiler/rustc_parse/src/lexer/mod.rs | 30 ++- .../src/lexer/unescape_error_reporting.rs | 186 +++++++++++------- src/test/ui/attributes/key-value-non-ascii.rs | 2 +- .../ui/attributes/key-value-non-ascii.stderr | 5 +- .../ui/parser/ascii-only-character-escape.rs | 6 +- .../parser/ascii-only-character-escape.stderr | 12 +- src/test/ui/parser/bad-char-literals.rs | 8 +- src/test/ui/parser/bad-char-literals.stderr | 16 +- src/test/ui/parser/byte-literals.rs | 4 +- src/test/ui/parser/byte-literals.stderr | 25 ++- src/test/ui/parser/byte-string-literals.rs | 5 +- .../ui/parser/byte-string-literals.stderr | 27 ++- .../ui/parser/issue-23620-invalid-escapes.rs | 14 +- .../parser/issue-23620-invalid-escapes.stderr | 34 ++-- src/test/ui/parser/issue-43692.stderr | 4 +- src/test/ui/parser/issue-62913.stderr | 2 +- src/test/ui/parser/issue-64732.stderr | 6 +- .../ui/parser/lex-bad-char-literals-1.stderr | 8 +- src/test/ui/parser/lex-bad-char-literals-7.rs | 2 +- .../ui/parser/lex-bad-char-literals-7.stderr | 6 +- .../lex-bare-cr-string-literal-doc-comment.rs | 2 +- ...-bare-cr-string-literal-doc-comment.stderr | 6 +- ...rals-are-validated-before-expansion.stderr | 4 +- src/test/ui/parser/new-unicode-escapes-1.rs | 2 +- .../ui/parser/new-unicode-escapes-1.stderr | 9 +- src/test/ui/parser/new-unicode-escapes-2.rs | 2 +- .../ui/parser/new-unicode-escapes-2.stderr | 4 +- .../ui/parser/new-unicode-escapes-3.stderr | 4 +- src/test/ui/parser/new-unicode-escapes-4.rs | 2 +- .../ui/parser/new-unicode-escapes-4.stderr | 4 +- .../raw/raw-byte-string-literals.stderr | 2 +- .../trailing-carriage-return-in-string.rs | 4 +- .../trailing-carriage-return-in-string.stderr | 2 +- .../ui/parser/wrong-escape-of-curly-braces.rs | 8 +- .../wrong-escape-of-curly-braces.stderr | 4 +- 35 files changed, 278 insertions(+), 183 deletions(-) diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index b5b34c7338d88..4a638ec3f8020 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -14,7 +14,7 @@ mod tokentrees; mod unescape_error_reporting; mod unicode_chars; -use unescape_error_reporting::{emit_unescape_error, push_escaped_char}; +use unescape_error_reporting::{emit_unescape_error, escaped_char}; #[derive(Clone, Debug)] pub struct UnmatchedBrace { @@ -122,11 +122,9 @@ impl<'a> StringReader<'a> { m: &str, c: char, ) -> DiagnosticBuilder<'a> { - let mut m = m.to_string(); - m.push_str(": "); - push_escaped_char(&mut m, c); - - self.sess.span_diagnostic.struct_span_fatal(self.mk_sp(from_pos, to_pos), &m[..]) + self.sess + .span_diagnostic + .struct_span_fatal(self.mk_sp(from_pos, to_pos), &format!("{}: {}", m, escaped_char(c))) } /// Turns simple `rustc_lexer::TokenKind` enum into a rich @@ -421,7 +419,7 @@ impl<'a> StringReader<'a> { let content_start = start + BytePos(prefix_len); let content_end = suffix_start - BytePos(postfix_len); let id = self.symbol_from_to(content_start, content_end); - self.validate_literal_escape(mode, content_start, content_end); + self.validate_literal_escape(mode, content_start, content_end, prefix_len, postfix_len); (lit_kind, id) } @@ -525,17 +523,29 @@ impl<'a> StringReader<'a> { .raise(); } - fn validate_literal_escape(&self, mode: Mode, content_start: BytePos, content_end: BytePos) { + fn validate_literal_escape( + &self, + mode: Mode, + content_start: BytePos, + content_end: BytePos, + prefix_len: u32, + postfix_len: u32, + ) { let lit_content = self.str_from_to(content_start, content_end); unescape::unescape_literal(lit_content, mode, &mut |range, result| { // Here we only check for errors. The actual unescaping is done later. if let Err(err) = result { - let span_with_quotes = - self.mk_sp(content_start - BytePos(1), content_end + BytePos(1)); + let span_with_quotes = self + .mk_sp(content_start - BytePos(prefix_len), content_end + BytePos(postfix_len)); + let (start, end) = (range.start as u32, range.end as u32); + let lo = content_start + BytePos(start); + let hi = lo + BytePos(end - start); + let span = self.mk_sp(lo, hi); emit_unescape_error( &self.sess.span_diagnostic, lit_content, span_with_quotes, + span, mode, range, err, diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 47d317f918865..a580f0c55d0e3 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -13,6 +13,8 @@ pub(crate) fn emit_unescape_error( lit: &str, // full span of the literal, including quotes span_with_quotes: Span, + // interior span of the literal, without quotes + span: Span, mode: Mode, // range of the error inside `lit` range: Range, @@ -26,13 +28,6 @@ pub(crate) fn emit_unescape_error( range, error ); - let span = { - let Range { start, end } = range; - let (start, end) = (start as u32, end as u32); - let lo = span_with_quotes.lo() + BytePos(start + 1); - let hi = lo + BytePos(end - start); - span_with_quotes.with_lo(lo).with_hi(hi) - }; let last_char = || { let c = lit[range.clone()].chars().rev().next().unwrap(); let span = span.with_lo(span.hi() - BytePos(c.len_utf8() as u32)); @@ -42,20 +37,22 @@ pub(crate) fn emit_unescape_error( EscapeError::LoneSurrogateUnicodeEscape => { handler .struct_span_err(span, "invalid unicode character escape") + .span_label(span, "invalid escape") .help("unicode escape must not be a surrogate") .emit(); } EscapeError::OutOfRangeUnicodeEscape => { handler .struct_span_err(span, "invalid unicode character escape") + .span_label(span, "invalid escape") .help("unicode escape must be at most 10FFFF") .emit(); } EscapeError::MoreThanOneChar => { - let msg = if mode.is_bytes() { - "if you meant to write a byte string literal, use double quotes" + let (prefix, msg) = if mode.is_bytes() { + ("b", "if you meant to write a byte string literal, use double quotes") } else { - "if you meant to write a `str` literal, use double quotes" + ("", "if you meant to write a `str` literal, use double quotes") }; handler @@ -66,31 +63,44 @@ pub(crate) fn emit_unescape_error( .span_suggestion( span_with_quotes, msg, - format!("\"{}\"", lit), + format!("{}\"{}\"", prefix, lit), Applicability::MachineApplicable, ) .emit(); } EscapeError::EscapeOnlyChar => { - let (c, _span) = last_char(); + let (c, char_span) = last_char(); - let mut msg = if mode.is_bytes() { - "byte constant must be escaped: " + let msg = if mode.is_bytes() { + "byte constant must be escaped" } else { - "character constant must be escaped: " - } - .to_string(); - push_escaped_char(&mut msg, c); - - handler.span_err(span, msg.as_str()) + "character constant must be escaped" + }; + handler + .struct_span_err(span, &format!("{}: `{}`", msg, escaped_char(c))) + .span_suggestion( + char_span, + "escape the character", + c.escape_default().to_string(), + Applicability::MachineApplicable, + ) + .emit() } EscapeError::BareCarriageReturn => { let msg = if mode.in_double_quotes() { - "bare CR not allowed in string, use \\r instead" + "bare CR not allowed in string, use `\\r` instead" } else { - "character constant must be escaped: \\r" + "character constant must be escaped: `\\r`" }; - handler.span_err(span, msg); + handler + .struct_span_err(span, msg) + .span_suggestion( + span, + "escape the character", + "\\r".to_string(), + Applicability::MachineApplicable, + ) + .emit(); } EscapeError::BareCarriageReturnInRawString => { assert!(mode.in_double_quotes()); @@ -102,21 +112,22 @@ pub(crate) fn emit_unescape_error( let label = if mode.is_bytes() { "unknown byte escape" } else { "unknown character escape" }; - let mut msg = label.to_string(); - msg.push_str(": "); - push_escaped_char(&mut msg, c); - - let mut diag = handler.struct_span_err(span, msg.as_str()); + let ec = escaped_char(c); + let mut diag = handler.struct_span_err(span, &format!("{}: `{}`", label, ec)); diag.span_label(span, label); if c == '{' || c == '}' && !mode.is_bytes() { diag.help( - "if used in a formatting string, \ - curly braces are escaped with `{{` and `}}`", + "if used in a formatting string, curly braces are escaped with `{{` and `}}`", ); } else if c == '\r' { diag.help( - "this is an isolated carriage return; \ - consider checking your editor and version control settings", + "this is an isolated carriage return; consider checking your editor and \ + version control settings", + ); + } else { + diag.help( + "for more information, visit \ + ", ); } diag.emit(); @@ -127,45 +138,70 @@ pub(crate) fn emit_unescape_error( EscapeError::InvalidCharInHexEscape | EscapeError::InvalidCharInUnicodeEscape => { let (c, span) = last_char(); - let mut msg = if error == EscapeError::InvalidCharInHexEscape { - "invalid character in numeric character escape: " + let msg = if error == EscapeError::InvalidCharInHexEscape { + "invalid character in numeric character escape" } else { - "invalid character in unicode escape: " - } - .to_string(); - push_escaped_char(&mut msg, c); + "invalid character in unicode escape" + }; + let c = escaped_char(c); - handler.span_err(span, msg.as_str()) + handler + .struct_span_err(span, &format!("{}: `{}`", msg, c)) + .span_label(span, msg) + .emit(); } EscapeError::NonAsciiCharInByte => { assert!(mode.is_bytes()); - let (_c, span) = last_char(); - handler.span_err( - span, - "byte constant must be ASCII. \ - Use a \\xHH escape for a non-ASCII byte", - ) + let (c, span) = last_char(); + handler + .struct_span_err(span, "non-ASCII character in byte constant") + .span_label(span, "byte constant must be ASCII") + .span_suggestion( + span, + "use a \\xHH escape for a non-ASCII byte", + format!("\\x{:X}", c as u32), + Applicability::MachineApplicable, + ) + .emit(); } EscapeError::NonAsciiCharInByteString => { assert!(mode.is_bytes()); let (_c, span) = last_char(); - handler.span_err(span, "raw byte string must be ASCII") + handler + .struct_span_err(span, "raw byte string must be ASCII") + .span_label(span, "must be ASCII") + .emit(); + } + EscapeError::OutOfRangeHexEscape => { + handler + .struct_span_err(span, "out of range hex escape") + .span_label(span, "must be a character in the range [\\x00-\\x7f]") + .emit(); } - EscapeError::OutOfRangeHexEscape => handler.span_err( - span, - "this form of character escape may only be used \ - with characters in the range [\\x00-\\x7f]", - ), EscapeError::LeadingUnderscoreUnicodeEscape => { - let (_c, span) = last_char(); - handler.span_err(span, "invalid start of unicode escape") + let (c, span) = last_char(); + let msg = "invalid start of unicode escape"; + handler + .struct_span_err(span, &format!("{}: `{}`", msg, c)) + .span_label(span, msg) + .emit(); } EscapeError::OverlongUnicodeEscape => { - handler.span_err(span, "overlong unicode escape (must have at most 6 hex digits)") - } - EscapeError::UnclosedUnicodeEscape => { - handler.span_err(span, "unterminated unicode escape (needed a `}`)") + handler + .struct_span_err(span, "overlong unicode escape") + .span_label(span, "must have at most 6 hex digits") + .emit(); } + EscapeError::UnclosedUnicodeEscape => handler + .struct_span_err(span, "unterminated unicode escape") + .span_label(span, "missing a closing `}`") + .span_suggestion_verbose( + span.shrink_to_hi(), + "terminate the unicode escape", + "}".to_string(), + Applicability::MaybeIncorrect, + ) + .emit(), EscapeError::NoBraceInUnicodeEscape => { let msg = "incorrect unicode escape sequence"; let mut diag = handler.struct_span_err(span, msg); @@ -195,28 +231,38 @@ pub(crate) fn emit_unescape_error( diag.emit(); } - EscapeError::UnicodeEscapeInByte => handler.span_err( - span, - "unicode escape sequences cannot be used \ - as a byte or in a byte string", - ), + EscapeError::UnicodeEscapeInByte => { + let msg = "unicode escape in byte string"; + handler + .struct_span_err(span, msg) + .span_label(span, msg) + .help("unicode escape sequences cannot be used as a byte or in a byte string") + .emit(); + } EscapeError::EmptyUnicodeEscape => { - handler.span_err(span, "empty unicode escape (must have at least 1 hex digit)") + handler + .struct_span_err(span, "empty unicode escape") + .span_label(span, "this escape must have at least 1 hex digit") + .emit(); + } + EscapeError::ZeroChars => { + let msg = "empty character literal"; + handler.struct_span_err(span, msg).span_label(span, msg).emit() + } + EscapeError::LoneSlash => { + let msg = "invalid trailing slash in literal"; + handler.struct_span_err(span, msg).span_label(span, msg).emit(); } - EscapeError::ZeroChars => handler.span_err(span, "empty character literal"), - EscapeError::LoneSlash => handler.span_err(span, "invalid trailing slash in literal"), } } /// Pushes a character to a message string for error reporting -pub(crate) fn push_escaped_char(msg: &mut String, c: char) { +pub(crate) fn escaped_char(c: char) -> String { match c { '\u{20}'..='\u{7e}' => { // Don't escape \, ' or " for user-facing messages - msg.push(c); - } - _ => { - msg.extend(c.escape_default()); + c.to_string() } + _ => c.escape_default().to_string(), } } diff --git a/src/test/ui/attributes/key-value-non-ascii.rs b/src/test/ui/attributes/key-value-non-ascii.rs index 91c917e7db56f..12942eabdf7b5 100644 --- a/src/test/ui/attributes/key-value-non-ascii.rs +++ b/src/test/ui/attributes/key-value-non-ascii.rs @@ -1,4 +1,4 @@ #![feature(rustc_attrs)] -#[rustc_dummy = b"ffi.rs"] //~ ERROR byte constant must be ASCII +#[rustc_dummy = b"ffi.rs"] //~ ERROR non-ASCII character in byte constant fn main() {} diff --git a/src/test/ui/attributes/key-value-non-ascii.stderr b/src/test/ui/attributes/key-value-non-ascii.stderr index 3e082139f895b..1d4b0d5b2b130 100644 --- a/src/test/ui/attributes/key-value-non-ascii.stderr +++ b/src/test/ui/attributes/key-value-non-ascii.stderr @@ -1,8 +1,11 @@ -error: byte constant must be ASCII. Use a \xHH escape for a non-ASCII byte +error: non-ASCII character in byte constant --> $DIR/key-value-non-ascii.rs:3:19 | LL | #[rustc_dummy = b"ffi.rs"] | ^ + | | + | byte constant must be ASCII + | help: use a \xHH escape for a non-ASCII byte: `\xFB03` error: aborting due to previous error diff --git a/src/test/ui/parser/ascii-only-character-escape.rs b/src/test/ui/parser/ascii-only-character-escape.rs index 20d3edf125175..725c8ad23515e 100644 --- a/src/test/ui/parser/ascii-only-character-escape.rs +++ b/src/test/ui/parser/ascii-only-character-escape.rs @@ -1,6 +1,6 @@ fn main() { - let x = "\x80"; //~ ERROR may only be used - let y = "\xff"; //~ ERROR may only be used - let z = "\xe2"; //~ ERROR may only be used + let x = "\x80"; //~ ERROR out of range hex escape + let y = "\xff"; //~ ERROR out of range hex escape + let z = "\xe2"; //~ ERROR out of range hex escape let a = b"\x00e2"; // ok because byte literal } diff --git a/src/test/ui/parser/ascii-only-character-escape.stderr b/src/test/ui/parser/ascii-only-character-escape.stderr index cf51b00cdc39a..b599b35f4b324 100644 --- a/src/test/ui/parser/ascii-only-character-escape.stderr +++ b/src/test/ui/parser/ascii-only-character-escape.stderr @@ -1,20 +1,20 @@ -error: this form of character escape may only be used with characters in the range [\x00-\x7f] +error: out of range hex escape --> $DIR/ascii-only-character-escape.rs:2:14 | LL | let x = "\x80"; - | ^^^^ + | ^^^^ must be a character in the range [\x00-\x7f] -error: this form of character escape may only be used with characters in the range [\x00-\x7f] +error: out of range hex escape --> $DIR/ascii-only-character-escape.rs:3:14 | LL | let y = "\xff"; - | ^^^^ + | ^^^^ must be a character in the range [\x00-\x7f] -error: this form of character escape may only be used with characters in the range [\x00-\x7f] +error: out of range hex escape --> $DIR/ascii-only-character-escape.rs:4:14 | LL | let z = "\xe2"; - | ^^^^ + | ^^^^ must be a character in the range [\x00-\x7f] error: aborting due to 3 previous errors diff --git a/src/test/ui/parser/bad-char-literals.rs b/src/test/ui/parser/bad-char-literals.rs index 11696b82bc9ac..748b4a22253f5 100644 --- a/src/test/ui/parser/bad-char-literals.rs +++ b/src/test/ui/parser/bad-char-literals.rs @@ -4,17 +4,17 @@ fn main() { // these literals are just silly. '''; - //~^ ERROR: character constant must be escaped: ' + //~^ ERROR: character constant must be escaped: `'` // note that this is a literal "\n" byte ' '; - //~^^ ERROR: character constant must be escaped: \n + //~^^ ERROR: character constant must be escaped: `\n` // note that this is a literal "\r" byte - ' '; //~ ERROR: character constant must be escaped: \r + ' '; //~ ERROR: character constant must be escaped: `\r` // note that this is a literal tab character here ' '; - //~^ ERROR: character constant must be escaped: \t + //~^ ERROR: character constant must be escaped: `\t` } diff --git a/src/test/ui/parser/bad-char-literals.stderr b/src/test/ui/parser/bad-char-literals.stderr index 093978fd84d00..a22ddbac1b931 100644 --- a/src/test/ui/parser/bad-char-literals.stderr +++ b/src/test/ui/parser/bad-char-literals.stderr @@ -1,28 +1,28 @@ -error: character constant must be escaped: ' +error: character constant must be escaped: `'` --> $DIR/bad-char-literals.rs:6:6 | LL | '''; - | ^ + | ^ help: escape the character: `\'` -error: character constant must be escaped: \n +error: character constant must be escaped: `\n` --> $DIR/bad-char-literals.rs:10:6 | LL | ' | ______^ LL | | '; - | |_ + | |_ help: escape the character: `\n` -error: character constant must be escaped: \r +error: character constant must be escaped: `\r` --> $DIR/bad-char-literals.rs:15:6 | LL | ' '; - | ^ + | ^ help: escape the character: `\r` -error: character constant must be escaped: \t +error: character constant must be escaped: `\t` --> $DIR/bad-char-literals.rs:18:6 | LL | ' '; - | ^^^^ + | ^^^^ help: escape the character: `\t` error: aborting due to 4 previous errors diff --git a/src/test/ui/parser/byte-literals.rs b/src/test/ui/parser/byte-literals.rs index 9683a83e72095..05a510b24a7ab 100644 --- a/src/test/ui/parser/byte-literals.rs +++ b/src/test/ui/parser/byte-literals.rs @@ -4,9 +4,9 @@ static FOO: u8 = b'\f'; //~ ERROR unknown byte escape pub fn main() { b'\f'; //~ ERROR unknown byte escape - b'\x0Z'; //~ ERROR invalid character in numeric character escape: Z + b'\x0Z'; //~ ERROR invalid character in numeric character escape: `Z` b' '; //~ ERROR byte constant must be escaped b'''; //~ ERROR byte constant must be escaped - b'é'; //~ ERROR byte constant must be ASCII + b'é'; //~ ERROR non-ASCII character in byte constant b'a //~ ERROR unterminated byte constant [E0763] } diff --git a/src/test/ui/parser/byte-literals.stderr b/src/test/ui/parser/byte-literals.stderr index 7bbdc07cd835f..55be113e16b99 100644 --- a/src/test/ui/parser/byte-literals.stderr +++ b/src/test/ui/parser/byte-literals.stderr @@ -1,38 +1,45 @@ -error: unknown byte escape: f +error: unknown byte escape: `f` --> $DIR/byte-literals.rs:3:21 | LL | static FOO: u8 = b'\f'; | ^ unknown byte escape + | + = help: for more information, visit -error: unknown byte escape: f +error: unknown byte escape: `f` --> $DIR/byte-literals.rs:6:8 | LL | b'\f'; | ^ unknown byte escape + | + = help: for more information, visit -error: invalid character in numeric character escape: Z +error: invalid character in numeric character escape: `Z` --> $DIR/byte-literals.rs:7:10 | LL | b'\x0Z'; - | ^ + | ^ invalid character in numeric character escape -error: byte constant must be escaped: \t +error: byte constant must be escaped: `\t` --> $DIR/byte-literals.rs:8:7 | LL | b' '; - | ^^^^ + | ^^^^ help: escape the character: `\t` -error: byte constant must be escaped: ' +error: byte constant must be escaped: `'` --> $DIR/byte-literals.rs:9:7 | LL | b'''; - | ^ + | ^ help: escape the character: `\'` -error: byte constant must be ASCII. Use a \xHH escape for a non-ASCII byte +error: non-ASCII character in byte constant --> $DIR/byte-literals.rs:10:7 | LL | b'é'; | ^ + | | + | byte constant must be ASCII + | help: use a \xHH escape for a non-ASCII byte: `\xE9` error[E0763]: unterminated byte constant --> $DIR/byte-literals.rs:11:6 diff --git a/src/test/ui/parser/byte-string-literals.rs b/src/test/ui/parser/byte-string-literals.rs index caffd9efbed37..b1f11024a7bb6 100644 --- a/src/test/ui/parser/byte-string-literals.rs +++ b/src/test/ui/parser/byte-string-literals.rs @@ -2,7 +2,8 @@ static FOO: &'static [u8] = b"\f"; //~ ERROR unknown byte escape pub fn main() { b"\f"; //~ ERROR unknown byte escape - b"\x0Z"; //~ ERROR invalid character in numeric character escape: Z - b"é"; //~ ERROR byte constant must be ASCII + b"\x0Z"; //~ ERROR invalid character in numeric character escape: `Z` + b"é"; //~ ERROR non-ASCII character in byte constant + br##"é"##; //~ ERROR raw byte string must be ASCII b"a //~ ERROR unterminated double quote byte string } diff --git a/src/test/ui/parser/byte-string-literals.stderr b/src/test/ui/parser/byte-string-literals.stderr index 9be9064414796..3a5a8b331d339 100644 --- a/src/test/ui/parser/byte-string-literals.stderr +++ b/src/test/ui/parser/byte-string-literals.stderr @@ -1,35 +1,48 @@ -error: unknown byte escape: f +error: unknown byte escape: `f` --> $DIR/byte-string-literals.rs:1:32 | LL | static FOO: &'static [u8] = b"\f"; | ^ unknown byte escape + | + = help: for more information, visit -error: unknown byte escape: f +error: unknown byte escape: `f` --> $DIR/byte-string-literals.rs:4:8 | LL | b"\f"; | ^ unknown byte escape + | + = help: for more information, visit -error: invalid character in numeric character escape: Z +error: invalid character in numeric character escape: `Z` --> $DIR/byte-string-literals.rs:5:10 | LL | b"\x0Z"; - | ^ + | ^ invalid character in numeric character escape -error: byte constant must be ASCII. Use a \xHH escape for a non-ASCII byte +error: non-ASCII character in byte constant --> $DIR/byte-string-literals.rs:6:7 | LL | b"é"; | ^ + | | + | byte constant must be ASCII + | help: use a \xHH escape for a non-ASCII byte: `\xE9` + +error: raw byte string must be ASCII + --> $DIR/byte-string-literals.rs:7:10 + | +LL | br##"é"##; + | ^ must be ASCII error[E0766]: unterminated double quote byte string - --> $DIR/byte-string-literals.rs:7:6 + --> $DIR/byte-string-literals.rs:8:6 | LL | b"a | ______^ LL | | } | |__^ -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0766`. diff --git a/src/test/ui/parser/issue-23620-invalid-escapes.rs b/src/test/ui/parser/issue-23620-invalid-escapes.rs index ab445a9329426..c1355f0d6fe0c 100644 --- a/src/test/ui/parser/issue-23620-invalid-escapes.rs +++ b/src/test/ui/parser/issue-23620-invalid-escapes.rs @@ -1,9 +1,9 @@ fn main() { let _ = b"\u{a66e}"; - //~^ ERROR unicode escape sequences cannot be used as a byte or in a byte string + //~^ ERROR unicode escape in byte string let _ = b'\u{a66e}'; - //~^ ERROR unicode escape sequences cannot be used as a byte or in a byte string + //~^ ERROR unicode escape in byte string let _ = b'\u'; //~^ ERROR incorrect unicode escape sequence @@ -12,21 +12,21 @@ fn main() { //~^ ERROR numeric character escape is too short let _ = b'\xxy'; - //~^ ERROR invalid character in numeric character escape: x + //~^ ERROR invalid character in numeric character escape: `x` let _ = '\x5'; //~^ ERROR numeric character escape is too short let _ = '\xxy'; - //~^ ERROR invalid character in numeric character escape: x + //~^ ERROR invalid character in numeric character escape: `x` let _ = b"\u{a4a4} \xf \u"; - //~^ ERROR unicode escape sequences cannot be used as a byte or in a byte string - //~^^ ERROR invalid character in numeric character escape: + //~^ ERROR unicode escape in byte string + //~^^ ERROR invalid character in numeric character escape: ` ` //~^^^ ERROR incorrect unicode escape sequence let _ = "\xf \u"; - //~^ ERROR invalid character in numeric character escape: + //~^ ERROR invalid character in numeric character escape: ` ` //~^^ ERROR incorrect unicode escape sequence let _ = "\u8f"; diff --git a/src/test/ui/parser/issue-23620-invalid-escapes.stderr b/src/test/ui/parser/issue-23620-invalid-escapes.stderr index 8c924ad0330e9..88d97c795fc2a 100644 --- a/src/test/ui/parser/issue-23620-invalid-escapes.stderr +++ b/src/test/ui/parser/issue-23620-invalid-escapes.stderr @@ -1,14 +1,18 @@ -error: unicode escape sequences cannot be used as a byte or in a byte string +error: unicode escape in byte string --> $DIR/issue-23620-invalid-escapes.rs:2:15 | LL | let _ = b"\u{a66e}"; - | ^^^^^^^^ + | ^^^^^^^^ unicode escape in byte string + | + = help: unicode escape sequences cannot be used as a byte or in a byte string -error: unicode escape sequences cannot be used as a byte or in a byte string +error: unicode escape in byte string --> $DIR/issue-23620-invalid-escapes.rs:5:15 | LL | let _ = b'\u{a66e}'; - | ^^^^^^^^ + | ^^^^^^^^ unicode escape in byte string + | + = help: unicode escape sequences cannot be used as a byte or in a byte string error: incorrect unicode escape sequence --> $DIR/issue-23620-invalid-escapes.rs:8:15 @@ -24,11 +28,11 @@ error: numeric character escape is too short LL | let _ = b'\x5'; | ^^^ -error: invalid character in numeric character escape: x +error: invalid character in numeric character escape: `x` --> $DIR/issue-23620-invalid-escapes.rs:14:17 | LL | let _ = b'\xxy'; - | ^ + | ^ invalid character in numeric character escape error: numeric character escape is too short --> $DIR/issue-23620-invalid-escapes.rs:17:14 @@ -36,23 +40,25 @@ error: numeric character escape is too short LL | let _ = '\x5'; | ^^^ -error: invalid character in numeric character escape: x +error: invalid character in numeric character escape: `x` --> $DIR/issue-23620-invalid-escapes.rs:20:16 | LL | let _ = '\xxy'; - | ^ + | ^ invalid character in numeric character escape -error: unicode escape sequences cannot be used as a byte or in a byte string +error: unicode escape in byte string --> $DIR/issue-23620-invalid-escapes.rs:23:15 | LL | let _ = b"\u{a4a4} \xf \u"; - | ^^^^^^^^ + | ^^^^^^^^ unicode escape in byte string + | + = help: unicode escape sequences cannot be used as a byte or in a byte string -error: invalid character in numeric character escape: +error: invalid character in numeric character escape: ` ` --> $DIR/issue-23620-invalid-escapes.rs:23:27 | LL | let _ = b"\u{a4a4} \xf \u"; - | ^ + | ^ invalid character in numeric character escape error: incorrect unicode escape sequence --> $DIR/issue-23620-invalid-escapes.rs:23:28 @@ -62,11 +68,11 @@ LL | let _ = b"\u{a4a4} \xf \u"; | = help: format of unicode escape sequences is `\u{...}` -error: invalid character in numeric character escape: +error: invalid character in numeric character escape: ` ` --> $DIR/issue-23620-invalid-escapes.rs:28:17 | LL | let _ = "\xf \u"; - | ^ + | ^ invalid character in numeric character escape error: incorrect unicode escape sequence --> $DIR/issue-23620-invalid-escapes.rs:28:18 diff --git a/src/test/ui/parser/issue-43692.stderr b/src/test/ui/parser/issue-43692.stderr index 69a54af3d82ed..baf998035178b 100644 --- a/src/test/ui/parser/issue-43692.stderr +++ b/src/test/ui/parser/issue-43692.stderr @@ -1,8 +1,8 @@ -error: invalid start of unicode escape +error: invalid start of unicode escape: `_` --> $DIR/issue-43692.rs:2:9 | LL | '\u{_10FFFF}'; - | ^ + | ^ invalid start of unicode escape error: aborting due to previous error diff --git a/src/test/ui/parser/issue-62913.stderr b/src/test/ui/parser/issue-62913.stderr index f72174f8929b8..6f385e8dc1777 100644 --- a/src/test/ui/parser/issue-62913.stderr +++ b/src/test/ui/parser/issue-62913.stderr @@ -10,7 +10,7 @@ error: invalid trailing slash in literal --> $DIR/issue-62913.rs:1:5 | LL | "\u\" - | ^ + | ^ invalid trailing slash in literal error: expected item, found `"\u\"` --> $DIR/issue-62913.rs:1:1 diff --git a/src/test/ui/parser/issue-64732.stderr b/src/test/ui/parser/issue-64732.stderr index 3b00ffc8f6c8d..ac04258096280 100644 --- a/src/test/ui/parser/issue-64732.stderr +++ b/src/test/ui/parser/issue-64732.stderr @@ -1,13 +1,13 @@ error: character literal may only contain one codepoint - --> $DIR/issue-64732.rs:3:17 + --> $DIR/issue-64732.rs:3:16 | LL | let _foo = b'hello\0'; - | ^^^^^^^^^ + | ^^^^^^^^^^ | help: if you meant to write a byte string literal, use double quotes | LL | let _foo = b"hello\0"; - | ^^^^^^^^^ + | ^^^^^^^^^^ error: character literal may only contain one codepoint --> $DIR/issue-64732.rs:6:16 diff --git a/src/test/ui/parser/lex-bad-char-literals-1.stderr b/src/test/ui/parser/lex-bad-char-literals-1.stderr index fcf4802f79bba..ed129a1d13388 100644 --- a/src/test/ui/parser/lex-bad-char-literals-1.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-1.stderr @@ -10,17 +10,21 @@ error: numeric character escape is too short LL | "\x1" | ^^^ -error: unknown character escape: \u{25cf} +error: unknown character escape: `\u{25cf}` --> $DIR/lex-bad-char-literals-1.rs:10:7 | LL | '\●' | ^ unknown character escape + | + = help: for more information, visit -error: unknown character escape: \u{25cf} +error: unknown character escape: `\u{25cf}` --> $DIR/lex-bad-char-literals-1.rs:14:7 | LL | "\●" | ^ unknown character escape + | + = help: for more information, visit error: aborting due to 4 previous errors diff --git a/src/test/ui/parser/lex-bad-char-literals-7.rs b/src/test/ui/parser/lex-bad-char-literals-7.rs index 1580157210e69..c675df2f3ccd0 100644 --- a/src/test/ui/parser/lex-bad-char-literals-7.rs +++ b/src/test/ui/parser/lex-bad-char-literals-7.rs @@ -2,7 +2,7 @@ fn main() { let _: char = ''; //~^ ERROR: empty character literal let _: char = '\u{}'; - //~^ ERROR: empty unicode escape (must have at least 1 hex digit) + //~^ ERROR: empty unicode escape // Next two are OK, but may befool error recovery let _ = '/'; diff --git a/src/test/ui/parser/lex-bad-char-literals-7.stderr b/src/test/ui/parser/lex-bad-char-literals-7.stderr index 70ee8087b5163..255b9c6899999 100644 --- a/src/test/ui/parser/lex-bad-char-literals-7.stderr +++ b/src/test/ui/parser/lex-bad-char-literals-7.stderr @@ -2,13 +2,13 @@ error: empty character literal --> $DIR/lex-bad-char-literals-7.rs:2:20 | LL | let _: char = ''; - | ^ + | ^ empty character literal -error: empty unicode escape (must have at least 1 hex digit) +error: empty unicode escape --> $DIR/lex-bad-char-literals-7.rs:4:20 | LL | let _: char = '\u{}'; - | ^^^^ + | ^^^^ this escape must have at least 1 hex digit error[E0762]: unterminated character literal --> $DIR/lex-bad-char-literals-7.rs:11:13 diff --git a/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.rs b/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.rs index 9a9f9c433e1d6..b7752e1f0c45f 100644 --- a/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.rs +++ b/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.rs @@ -22,5 +22,5 @@ fn main() { let _s = r"bar foo"; //~ ERROR: bare CR not allowed in raw string // the following string literal has a bare CR in it - let _s = "foo\ bar"; //~ ERROR: unknown character escape: \r + let _s = "foo\ bar"; //~ ERROR: unknown character escape: `\r` } diff --git a/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr b/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr index 598da6b930730..1a21fed63bdec 100644 --- a/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr +++ b/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr @@ -22,11 +22,11 @@ error: bare CR not allowed in block doc-comment LL | /*! block doc comment with bare CR: ' ' */ | ^ -error: bare CR not allowed in string, use \r instead +error: bare CR not allowed in string, use `\r` instead --> $DIR/lex-bare-cr-string-literal-doc-comment.rs:19:18 | LL | let _s = "foo bar"; - | ^ + | ^ help: escape the character: `\r` error: bare CR not allowed in raw string --> $DIR/lex-bare-cr-string-literal-doc-comment.rs:22:19 @@ -34,7 +34,7 @@ error: bare CR not allowed in raw string LL | let _s = r"bar foo"; | ^ -error: unknown character escape: \r +error: unknown character escape: `\r` --> $DIR/lex-bare-cr-string-literal-doc-comment.rs:25:19 | LL | let _s = "foo\ bar"; diff --git a/src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr b/src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr index d20eb0fb30a49..e874f62497ea8 100644 --- a/src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr +++ b/src/test/ui/parser/macro/literals-are-validated-before-expansion.stderr @@ -2,7 +2,7 @@ error: invalid unicode character escape --> $DIR/literals-are-validated-before-expansion.rs:6:20 | LL | black_hole! { '\u{FFFFFF}' } - | ^^^^^^^^^^ + | ^^^^^^^^^^ invalid escape | = help: unicode escape must be at most 10FFFF @@ -10,7 +10,7 @@ error: invalid unicode character escape --> $DIR/literals-are-validated-before-expansion.rs:8:39 | LL | black_hole! { "this is surrogate: \u{DAAA}" } - | ^^^^^^^^ + | ^^^^^^^^ invalid escape | = help: unicode escape must not be a surrogate diff --git a/src/test/ui/parser/new-unicode-escapes-1.rs b/src/test/ui/parser/new-unicode-escapes-1.rs index 0e1421214d9d8..d6a54660ea6e8 100644 --- a/src/test/ui/parser/new-unicode-escapes-1.rs +++ b/src/test/ui/parser/new-unicode-escapes-1.rs @@ -1,3 +1,3 @@ pub fn main() { - let s = "\u{2603"; //~ ERROR unterminated unicode escape (needed a `}`) + let s = "\u{2603"; //~ ERROR unterminated unicode escape } diff --git a/src/test/ui/parser/new-unicode-escapes-1.stderr b/src/test/ui/parser/new-unicode-escapes-1.stderr index 22d6a0981ffd6..1ffdc0401e59c 100644 --- a/src/test/ui/parser/new-unicode-escapes-1.stderr +++ b/src/test/ui/parser/new-unicode-escapes-1.stderr @@ -1,8 +1,13 @@ -error: unterminated unicode escape (needed a `}`) +error: unterminated unicode escape --> $DIR/new-unicode-escapes-1.rs:2:14 | LL | let s = "\u{2603"; - | ^^^^^^^ + | ^^^^^^^ missing a closing `}` + | +help: terminate the unicode escape + | +LL | let s = "\u{2603}"; + | ^ error: aborting due to previous error diff --git a/src/test/ui/parser/new-unicode-escapes-2.rs b/src/test/ui/parser/new-unicode-escapes-2.rs index b30b3dbf9036a..cbb614c19c004 100644 --- a/src/test/ui/parser/new-unicode-escapes-2.rs +++ b/src/test/ui/parser/new-unicode-escapes-2.rs @@ -1,3 +1,3 @@ pub fn main() { - let s = "\u{260311111111}"; //~ ERROR overlong unicode escape (must have at most 6 hex digits) + let s = "\u{260311111111}"; //~ ERROR overlong unicode escape } diff --git a/src/test/ui/parser/new-unicode-escapes-2.stderr b/src/test/ui/parser/new-unicode-escapes-2.stderr index b5148279c7450..2f3f8c0f9dae5 100644 --- a/src/test/ui/parser/new-unicode-escapes-2.stderr +++ b/src/test/ui/parser/new-unicode-escapes-2.stderr @@ -1,8 +1,8 @@ -error: overlong unicode escape (must have at most 6 hex digits) +error: overlong unicode escape --> $DIR/new-unicode-escapes-2.rs:2:14 | LL | let s = "\u{260311111111}"; - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ must have at most 6 hex digits error: aborting due to previous error diff --git a/src/test/ui/parser/new-unicode-escapes-3.stderr b/src/test/ui/parser/new-unicode-escapes-3.stderr index 361698467f97d..f5a0f8fc785c5 100644 --- a/src/test/ui/parser/new-unicode-escapes-3.stderr +++ b/src/test/ui/parser/new-unicode-escapes-3.stderr @@ -2,7 +2,7 @@ error: invalid unicode character escape --> $DIR/new-unicode-escapes-3.rs:2:15 | LL | let s1 = "\u{d805}"; - | ^^^^^^^^ + | ^^^^^^^^ invalid escape | = help: unicode escape must not be a surrogate @@ -10,7 +10,7 @@ error: invalid unicode character escape --> $DIR/new-unicode-escapes-3.rs:3:15 | LL | let s2 = "\u{ffffff}"; - | ^^^^^^^^^^ + | ^^^^^^^^^^ invalid escape | = help: unicode escape must be at most 10FFFF diff --git a/src/test/ui/parser/new-unicode-escapes-4.rs b/src/test/ui/parser/new-unicode-escapes-4.rs index 9ac03cedc3f3e..79882713e59a2 100644 --- a/src/test/ui/parser/new-unicode-escapes-4.rs +++ b/src/test/ui/parser/new-unicode-escapes-4.rs @@ -1,4 +1,4 @@ pub fn main() { let s = "\u{lol}"; - //~^ ERROR invalid character in unicode escape: l + //~^ ERROR invalid character in unicode escape: `l` } diff --git a/src/test/ui/parser/new-unicode-escapes-4.stderr b/src/test/ui/parser/new-unicode-escapes-4.stderr index a35c5f0f21658..514591af17e6e 100644 --- a/src/test/ui/parser/new-unicode-escapes-4.stderr +++ b/src/test/ui/parser/new-unicode-escapes-4.stderr @@ -1,8 +1,8 @@ -error: invalid character in unicode escape: l +error: invalid character in unicode escape: `l` --> $DIR/new-unicode-escapes-4.rs:2:17 | LL | let s = "\u{lol}"; - | ^ + | ^ invalid character in unicode escape error: aborting due to previous error diff --git a/src/test/ui/parser/raw/raw-byte-string-literals.stderr b/src/test/ui/parser/raw/raw-byte-string-literals.stderr index 4076fe334e653..cfc877104bd9f 100644 --- a/src/test/ui/parser/raw/raw-byte-string-literals.stderr +++ b/src/test/ui/parser/raw/raw-byte-string-literals.stderr @@ -8,7 +8,7 @@ error: raw byte string must be ASCII --> $DIR/raw-byte-string-literals.rs:5:8 | LL | br"é"; - | ^ + | ^ must be ASCII error: found invalid character; only `#` is allowed in raw string delimitation: ~ --> $DIR/raw-byte-string-literals.rs:6:5 diff --git a/src/test/ui/parser/trailing-carriage-return-in-string.rs b/src/test/ui/parser/trailing-carriage-return-in-string.rs index 8abf2624e4f97..5d3c31944064a 100644 --- a/src/test/ui/parser/trailing-carriage-return-in-string.rs +++ b/src/test/ui/parser/trailing-carriage-return-in-string.rs @@ -8,7 +8,7 @@ fn main() { a test"; // \r only let bad = "This is \ a test"; - //~^ ERROR unknown character escape: \r - //~^^ HELP this is an isolated carriage return + //~^ ERROR unknown character escape: `\r` + //~| HELP this is an isolated carriage return } diff --git a/src/test/ui/parser/trailing-carriage-return-in-string.stderr b/src/test/ui/parser/trailing-carriage-return-in-string.stderr index 3687b9dd282d1..8a44e02707ce5 100644 --- a/src/test/ui/parser/trailing-carriage-return-in-string.stderr +++ b/src/test/ui/parser/trailing-carriage-return-in-string.stderr @@ -1,4 +1,4 @@ -error: unknown character escape: \r +error: unknown character escape: `\r` --> $DIR/trailing-carriage-return-in-string.rs:10:25 | LL | let bad = "This is \ a test"; diff --git a/src/test/ui/parser/wrong-escape-of-curly-braces.rs b/src/test/ui/parser/wrong-escape-of-curly-braces.rs index 7a5c27afca552..8e5258acd49da 100644 --- a/src/test/ui/parser/wrong-escape-of-curly-braces.rs +++ b/src/test/ui/parser/wrong-escape-of-curly-braces.rs @@ -1,8 +1,8 @@ fn main() { let ok = "{{everything fine}}"; let bad = "\{it is wrong\}"; - //~^ ERROR unknown character escape: { - //~^^ HELP if used in a formatting string, curly braces are escaped with `{{` and `}}` - //~^^^ ERROR unknown character escape: } - //~^^^^ HELP if used in a formatting string, curly braces are escaped with `{{` and `}}` + //~^ ERROR unknown character escape: `{` + //~| HELP if used in a formatting string, curly braces are escaped with `{{` and `}}` + //~| ERROR unknown character escape: `}` + //~| HELP if used in a formatting string, curly braces are escaped with `{{` and `}}` } diff --git a/src/test/ui/parser/wrong-escape-of-curly-braces.stderr b/src/test/ui/parser/wrong-escape-of-curly-braces.stderr index 1406b795ba8c3..ff1a2fb0f3c67 100644 --- a/src/test/ui/parser/wrong-escape-of-curly-braces.stderr +++ b/src/test/ui/parser/wrong-escape-of-curly-braces.stderr @@ -1,4 +1,4 @@ -error: unknown character escape: { +error: unknown character escape: `{` --> $DIR/wrong-escape-of-curly-braces.rs:3:17 | LL | let bad = "\{it is wrong\}"; @@ -6,7 +6,7 @@ LL | let bad = "\{it is wrong\}"; | = help: if used in a formatting string, curly braces are escaped with `{{` and `}}` -error: unknown character escape: } +error: unknown character escape: `}` --> $DIR/wrong-escape-of-curly-braces.rs:3:30 | LL | let bad = "\{it is wrong\}";