Rollup merge of #37695 - estebank:unescaped-curly, r=alexcrichton
On fmt string with unescaped `{` note how to escape On cases of malformed format strings where a `{` hasn't been properly escaped, like `println!("{");`, present a NOTE explaining how to escape the `{` char. Fix #34300.
This commit is contained in:
commit
048daa6224
@ -139,7 +139,7 @@ pub struct Parser<'a> {
|
||||
input: &'a str,
|
||||
cur: iter::Peekable<str::CharIndices<'a>>,
|
||||
/// Error messages accumulated during parsing
|
||||
pub errors: Vec<string::String>,
|
||||
pub errors: Vec<(string::String, Option<string::String>)>,
|
||||
/// Current position of implicit positional argument pointer
|
||||
curarg: usize,
|
||||
}
|
||||
@ -165,7 +165,9 @@ impl<'a> Iterator for Parser<'a> {
|
||||
if self.consume('}') {
|
||||
Some(String(self.string(pos + 1)))
|
||||
} else {
|
||||
self.err("unmatched `}` found");
|
||||
self.err_with_note("unmatched `}` found",
|
||||
"if you intended to print `}`, \
|
||||
you can escape it using `}}`");
|
||||
None
|
||||
}
|
||||
}
|
||||
@ -192,7 +194,14 @@ impl<'a> Parser<'a> {
|
||||
/// String, but I think it does when this eventually uses conditions so it
|
||||
/// might as well start using it now.
|
||||
fn err(&mut self, msg: &str) {
|
||||
self.errors.push(msg.to_owned());
|
||||
self.errors.push((msg.to_owned(), None));
|
||||
}
|
||||
|
||||
/// Notifies of an error. The message doesn't actually need to be of type
|
||||
/// String, but I think it does when this eventually uses conditions so it
|
||||
/// might as well start using it now.
|
||||
fn err_with_note(&mut self, msg: &str, note: &str) {
|
||||
self.errors.push((msg.to_owned(), Some(note.to_owned())));
|
||||
}
|
||||
|
||||
/// Optionally consumes the specified character. If the character is not at
|
||||
@ -222,7 +231,13 @@ impl<'a> Parser<'a> {
|
||||
self.err(&format!("expected `{:?}`, found `{:?}`", c, maybe));
|
||||
}
|
||||
} else {
|
||||
self.err(&format!("expected `{:?}` but string was terminated", c));
|
||||
let msg = &format!("expected `{:?}` but string was terminated", c);
|
||||
if c == '}' {
|
||||
self.err_with_note(msg,
|
||||
"if you intended to print `{`, you can escape it using `{{`");
|
||||
} else {
|
||||
self.err(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -756,8 +756,12 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt,
|
||||
}
|
||||
|
||||
if !parser.errors.is_empty() {
|
||||
cx.ecx.span_err(cx.fmtsp,
|
||||
&format!("invalid format string: {}", parser.errors.remove(0)));
|
||||
let (err, note) = parser.errors.remove(0);
|
||||
let mut e = cx.ecx.struct_span_err(cx.fmtsp, &format!("invalid format string: {}", err));
|
||||
if let Some(note) = note {
|
||||
e.note(¬e);
|
||||
}
|
||||
e.emit();
|
||||
return DummyResult::raw_expr(sp);
|
||||
}
|
||||
if !cx.literal.is_empty() {
|
||||
|
16
src/test/ui/fmt/format-string-error.rs
Normal file
16
src/test/ui/fmt/format-string-error.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
fn main() {
|
||||
println!("{");
|
||||
println!("{{}}");
|
||||
println!("}");
|
||||
}
|
||||
|
20
src/test/ui/fmt/format-string-error.stderr
Normal file
20
src/test/ui/fmt/format-string-error.stderr
Normal file
@ -0,0 +1,20 @@
|
||||
error: invalid format string: expected `'}'` but string was terminated
|
||||
--> $DIR/format-string-error.rs:12:5
|
||||
|
|
||||
12 | println!("{");
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: if you intended to print `{`, you can escape it using `{{`
|
||||
= note: this error originates in a macro outside of the current crate
|
||||
|
||||
error: invalid format string: unmatched `}` found
|
||||
--> $DIR/format-string-error.rs:14:5
|
||||
|
|
||||
14 | println!("}");
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: if you intended to print `}`, you can escape it using `}}`
|
||||
= note: this error originates in a macro outside of the current crate
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user