diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 0fd069b76aadc6db18963786525c78f71ab94f06..11ab84a572916e76edc6f7473f6e4cb17cf74787 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -246,14 +246,27 @@ fn err_span_(&self, from_pos: BytePos, to_pos: BytePos, m: &str) { 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 @@ fn struct_fatal_span_char(&self, -> 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 @@ fn struct_fatal_span_char(&self, 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 @@ fn struct_err_span_char(&self, -> 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[..]) } diff --git a/src/test/parse-fail/bad-char-literals.rs b/src/test/parse-fail/bad-char-literals.rs index 96311d6de176c64a824e9364e06db938c7c75a74..821015ece77124acff5bd042fc7e4d21960964a4 100644 --- a/src/test/parse-fail/bad-char-literals.rs +++ b/src/test/parse-fail/bad-char-literals.rs @@ -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 ' diff --git a/src/test/parse-fail/lex-stray-backslash.rs b/src/test/parse-fail/lex-stray-backslash.rs new file mode 100644 index 0000000000000000000000000000000000000000..b6042bbdc1a2699c60729045a6763e295e0824a2 --- /dev/null +++ b/src/test/parse-fail/lex-stray-backslash.rs @@ -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 or the MIT license +// , 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: \