Account for \xFF and \u{FF} sequences in string format errors

This commit is contained in:
Esteban Küber 2018-12-27 10:40:06 -08:00
parent 433ef826f0
commit 7edc434b72
3 changed files with 107 additions and 1 deletions

View File

@ -808,12 +808,57 @@ fn find_skips(snippet: &str, is_raw: bool) -> Vec<usize> {
}
('\\', Some((next_pos, 'n'))) |
('\\', Some((next_pos, 't'))) |
('\\', Some((next_pos, '0'))) |
('\\', Some((next_pos, '\\'))) |
('\\', Some((next_pos, '\''))) |
('\\', Some((next_pos, '\"'))) => {
skips.push(*next_pos);
let _ = s.next();
}
('\\', Some((_, 'x'))) if !is_raw => {
for _ in 0..3 { // consume `\xAB` literal
if let Some((pos, _)) = s.next() {
skips.push(pos);
} else {
break;
}
}
}
('\\', Some((_, 'u'))) if !is_raw => {
if let Some((pos, _)) = s.next() {
skips.push(pos);
}
if let Some((next_pos, next_c)) = s.next() {
if next_c == '{' {
skips.push(next_pos);
let mut i = 0; // consume up to 6 hexanumeric chars + closing `}`
while let (Some((next_pos, c)), true) = (s.next(), i < 7) {
if c.is_digit(16) {
skips.push(next_pos);
} else if c == '}' {
skips.push(next_pos);
break;
} else {
break;
}
i += 1;
}
} else if next_c.is_digit(16) {
skips.push(next_pos);
// We suggest adding `{` and `}` when appropriate, accept it here as if it
// were correct
let mut i = 0; // consume up to 6 hexanumeric chars
while let (Some((next_pos, c)), _) = (s.next(), i < 6) {
if c.is_digit(16) {
skips.push(next_pos);
} else {
break;
}
i += 1;
}
}
}
}
_ if eat_ws => { // `take_while(|c| c.is_whitespace())`
eat_ws = false;
}

View File

@ -69,4 +69,19 @@ fn main() {
//~^^ ERROR invalid format string
println!("\t{}");
//~^ ERROR 1 positional argument in format string
// note: `\x7B` is `{`
println!("\x7B}\u{8} {", 1);
//~^ ERROR invalid format string: expected `'}'` but string was terminated
println!("\x7B}\u8 {", 1);
//~^ ERROR incorrect unicode escape sequence
//~| ERROR argument never used
// note: raw strings don't escape `\xFF` and `\u{FF}` sequences
println!(r#"\x7B}\u{8} {"#, 1);
//~^ ERROR invalid format string: unmatched `}` found
println!(r#"\x7B}\u8 {"#, 1);
//~^ ERROR invalid format string: unmatched `}` found
}

View File

@ -1,3 +1,15 @@
error: incorrect unicode escape sequence
--> $DIR/format-string-error-2.rs:77:20
|
LL | println!("/x7B}/u8 {", 1);
| ^^
|
help: format of unicode escape sequences is `/u{…}`
--> $DIR/format-string-error-2.rs:77:20
|
LL | println!("/x7B}/u8 {", 1);
| ^^
error: invalid format string: expected `'}'`, found `'a'`
--> $DIR/format-string-error-2.rs:5:5
|
@ -139,5 +151,39 @@ error: 1 positional argument in format string, but no arguments were given
LL | println!("/t{}");
| ^^
error: aborting due to 14 previous errors
error: invalid format string: expected `'}'` but string was terminated
--> $DIR/format-string-error-2.rs:74:27
|
LL | println!("/x7B}/u{8} {", 1);
| -^ expected `'}'` in format string
| |
| because of this opening brace
|
= note: if you intended to print `{`, you can escape it using `{{`
error: argument never used
--> $DIR/format-string-error-2.rs:77:28
|
LL | println!("/x7B}/u8 {", 1);
| ------------ ^ argument never used
| |
| formatting specifier missing
error: invalid format string: unmatched `}` found
--> $DIR/format-string-error-2.rs:82:21
|
LL | println!(r#"/x7B}/u{8} {"#, 1);
| ^ unmatched `}` in format string
|
= note: if you intended to print `}`, you can escape it using `}}`
error: invalid format string: unmatched `}` found
--> $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