Rollup merge of #47914 - etaoins:improve-char-escape-in-lexer-msg, r=petrochenkov Improve char escaping in lexer messages Currently ', " and \ are escaped as \', \" and \\ respectively. This leads to confusing messages such as error: unknown start of token: \\
when encountering a single backslash. Fix by emitting printable ASCII characters directly. This will still escape \r, \n, \t and Unicode characters. Fixes #47902
This commit is contained in:
commit
b4b73a1d95
3 changed files with 33 additions and 13 deletions
|
@ -246,14 +246,27 @@ impl<'a> StringReader<'a> {
|
|||
self.err_span(self.mk_sp(from_pos, to_pos), m)
|
||||
}
|
||||
|
||||
/// Pushes a character to a message string for error reporting
|
||||
fn push_escaped_char_for_msg(m: &mut String, c: char) {
|
||||
match c {
|
||||
'\u{20}'...'\u{7e}' => {
|
||||
// Don't escape \, ' or " for user-facing messages
|
||||
m.push(c);
|
||||
}
|
||||
_ => {
|
||||
for c in c.escape_default() {
|
||||
m.push(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Report a lexical error spanning [`from_pos`, `to_pos`), appending an
|
||||
/// escaped character to the error message
|
||||
fn fatal_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char) -> FatalError {
|
||||
let mut m = m.to_string();
|
||||
m.push_str(": ");
|
||||
for c in c.escape_default() {
|
||||
m.push(c)
|
||||
}
|
||||
Self::push_escaped_char_for_msg(&mut m, c);
|
||||
self.fatal_span_(from_pos, to_pos, &m[..])
|
||||
}
|
||||
fn struct_fatal_span_char(&self,
|
||||
|
@ -264,9 +277,7 @@ impl<'a> StringReader<'a> {
|
|||
-> DiagnosticBuilder<'a> {
|
||||
let mut m = m.to_string();
|
||||
m.push_str(": ");
|
||||
for c in c.escape_default() {
|
||||
m.push(c)
|
||||
}
|
||||
Self::push_escaped_char_for_msg(&mut m, c);
|
||||
self.sess.span_diagnostic.struct_span_fatal(self.mk_sp(from_pos, to_pos), &m[..])
|
||||
}
|
||||
|
||||
|
@ -275,9 +286,7 @@ impl<'a> StringReader<'a> {
|
|||
fn err_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char) {
|
||||
let mut m = m.to_string();
|
||||
m.push_str(": ");
|
||||
for c in c.escape_default() {
|
||||
m.push(c)
|
||||
}
|
||||
Self::push_escaped_char_for_msg(&mut m, c);
|
||||
self.err_span_(from_pos, to_pos, &m[..]);
|
||||
}
|
||||
fn struct_err_span_char(&self,
|
||||
|
@ -288,9 +297,7 @@ impl<'a> StringReader<'a> {
|
|||
-> DiagnosticBuilder<'a> {
|
||||
let mut m = m.to_string();
|
||||
m.push_str(": ");
|
||||
for c in c.escape_default() {
|
||||
m.push(c)
|
||||
}
|
||||
Self::push_escaped_char_for_msg(&mut m, c);
|
||||
self.sess.span_diagnostic.struct_span_err(self.mk_sp(from_pos, to_pos), &m[..])
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
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
|
||||
'
|
||||
|
|
13
src/test/parse-fail/lex-stray-backslash.rs
Normal file
13
src/test/parse-fail/lex-stray-backslash.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: -Z parse-only
|
||||
|
||||
\ //~ ERROR: unknown start of token: \
|
Loading…
Add table
Reference in a new issue