don't amplify errors in format! with bad literals

This commit is contained in:
Aleksey Kladov 2019-05-02 20:56:07 +03:00
parent bfa5f27847
commit 1835cbeb65
7 changed files with 20 additions and 35 deletions

View File

@ -998,6 +998,7 @@ pub fn expr_to_spanned_string<'a>(
Err(match expr.node {
ast::ExprKind::Lit(ref l) => match l.node {
ast::LitKind::Str(s, style) => return Ok(respan(expr.span, (s, style))),
ast::LitKind::Err(_) => None,
_ => Some(cx.struct_span_err(l.span, err_msg))
},
ast::ExprKind::Err => None,

View File

@ -33,7 +33,7 @@
pub mod classify;
pub(crate) mod unescape;
use unescape::{unescape_str, unescape_char, unescape_byte_str, unescape_byte, EscapeError};
use unescape::{unescape_str, unescape_char, unescape_byte_str, unescape_byte};
pub(crate) mod unescape_error_reporting;
@ -355,16 +355,14 @@ macro_rules! err {
token::Byte(i) => {
let lit_kind = match unescape_byte(&i.as_str()) {
Ok(c) => LitKind::Byte(c),
Err((_, EscapeError::MoreThanOneChar)) => LitKind::Err(i),
Err(_) => LitKind::Byte(0),
Err(_) => LitKind::Err(i),
};
(true, Some(lit_kind))
},
token::Char(i) => {
let lit_kind = match unescape_char(&i.as_str()) {
Ok(c) => LitKind::Char(c),
Err((_, EscapeError::MoreThanOneChar)) => LitKind::Err(i),
Err(_) => LitKind::Char('\u{FFFD}'),
Err(_) => LitKind::Err(i),
};
(true, Some(lit_kind))
},
@ -380,17 +378,22 @@ macro_rules! err {
// reuse the symbol from the Token. Otherwise, we must generate a
// new symbol because the string in the LitKind is different to the
// string in the Token.
let mut has_error = false;
let s = &sym.as_str();
if s.as_bytes().iter().any(|&c| c == b'\\' || c == b'\r') {
let mut buf = String::with_capacity(s.len());
unescape_str(s, &mut |_, unescaped_char| {
match unescaped_char {
Ok(c) => buf.push(c),
Err(_) => buf.push('\u{FFFD}'),
Err(_) => has_error = true,
}
});
if has_error {
return (true, Some(LitKind::Err(sym)));
}
sym = Symbol::intern(&buf)
}
(true, Some(LitKind::Str(sym, ast::StrStyle::Cooked)))
}
token::StrRaw(mut sym, n) => {
@ -404,12 +407,16 @@ macro_rules! err {
token::ByteStr(i) => {
let s = &i.as_str();
let mut buf = Vec::with_capacity(s.len());
let mut has_error = false;
unescape_byte_str(s, &mut |_, unescaped_byte| {
match unescaped_byte {
Ok(c) => buf.push(c),
Err(_) => buf.push(0),
Err(_) => has_error = true,
}
});
if has_error {
return (true, Some(LitKind::Err(i)));
}
buf.shrink_to_fit();
(true, Some(LitKind::ByteStr(Lrc::new(buf))))
}

View File

@ -77,7 +77,6 @@ fn main() {
println!("\x7B}\u8 {", 1);
//~^ ERROR incorrect unicode escape sequence
//~| ERROR invalid format string: expected `'}'` but string was terminated
// note: raw strings don't escape `\xFF` and `\u{FF}` sequences
println!(r#"\x7B}\u{8} {"#, 1);

View File

@ -157,18 +157,8 @@ LL | println!("\x7B}\u{8} {", 1);
|
= note: if you intended to print `{`, you can escape it using `{{`
error: invalid format string: expected `'}'` but string was terminated
--> $DIR/format-string-error-2.rs:78:27
|
LL | println!("\x7B}\u8 {", 1);
| -^ expected `'}'` in format string
| |
| because of this opening brace
|
= note: if you intended to print `{`, you can escape it using `{{`
error: invalid format string: unmatched `}` found
--> $DIR/format-string-error-2.rs:83:21
--> $DIR/format-string-error-2.rs:82:21
|
LL | println!(r#"\x7B}\u{8} {"#, 1);
| ^ unmatched `}` in format string
@ -176,12 +166,12 @@ LL | println!(r#"\x7B}\u{8} {"#, 1);
= note: if you intended to print `}`, you can escape it using `}}`
error: invalid format string: unmatched `}` found
--> $DIR/format-string-error-2.rs:86:21
--> $DIR/format-string-error-2.rs:85:21
|
LL | println!(r#"\x7B}\u8 {"#, 1);
| ^ unmatched `}` in format string
|
= note: if you intended to print `}`, you can escape it using `}}`
error: aborting due to 19 previous errors
error: aborting due to 18 previous errors

View File

@ -1,6 +1,5 @@
// run-rustfix
fn main() {
println!("{}", "●●"); //~ ERROR character literal may only contain one codepoint
//~^ ERROR format argument must be a string literal
println!("●●"); //~ ERROR character literal may only contain one codepoint
}

View File

@ -2,5 +2,4 @@
fn main() {
println!(''); //~ ERROR character literal may only contain one codepoint
//~^ ERROR format argument must be a string literal
}

View File

@ -8,15 +8,5 @@ help: if you meant to write a `str` literal, use double quotes
LL | println!("●●");
| ^^^^
error: format argument must be a string literal
--> $DIR/str-as-char.rs:4:14
|
LL | println!('●●');
| ^^^^
help: you might be missing a string literal to format with
|
LL | println!("{}", '●●');
| ^^^^^
error: aborting due to 2 previous errors
error: aborting due to previous error