Skip to content

Try to improve format! error messages #9932

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 19, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 27 additions & 24 deletions src/libstd/fmt/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,7 @@ impl<'self> Iterator<Piece<'self>> for Parser<'self> {
Some((_, '{')) => {
self.cur.next();
let ret = Some(Argument(self.argument()));
if !self.consume('}') {
self.err(~"unterminated format string");
}
self.must_consume('}');
ret
}
Some((pos, '\\')) => {
Expand Down Expand Up @@ -223,6 +221,25 @@ impl<'self> Parser<'self> {
}
}

/// Forces consumption of the specified character. If the character is not
/// found, an error is emitted.
fn must_consume(&mut self, c: char) {
self.ws();
match self.cur.clone().next() {
Some((_, maybe)) if c == maybe => {
self.cur.next();
}
Some((_, other)) => {
parse_error::cond.raise(
format!("expected `{}` but found `{}`", c, other));
}
None => {
parse_error::cond.raise(
format!("expected `{}` but string was terminated", c));
}
}
}

/// Attempts to consume any amount of whitespace followed by a character
fn wsconsume(&mut self, c: char) -> bool {
self.ws(); self.consume(c)
Expand Down Expand Up @@ -386,15 +403,11 @@ impl<'self> Parser<'self> {
self.ws();
match self.word() {
"select" => {
if !self.wsconsume(',') {
self.err(~"`select` must be followed by `,`");
}
self.must_consume(',');
Some(self.select())
}
"plural" => {
if !self.wsconsume(',') {
self.err(~"`plural` must be followed by `,`");
}
self.must_consume(',');
Some(self.plural())
}
"" => {
Expand All @@ -420,15 +433,11 @@ impl<'self> Parser<'self> {
self.err(~"cannot have an empty selector");
break
}
if !self.wsconsume('{') {
self.err(~"selector must be followed by `{`");
}
self.must_consume('{');
self.depth += 1;
let pieces = self.collect();
self.depth -= 1;
if !self.wsconsume('}') {
self.err(~"selector case must be terminated by `}`");
}
self.must_consume('}');
if selector == "other" {
if !other.is_none() {
self.err(~"multiple `other` statements in `select");
Expand Down Expand Up @@ -475,9 +484,7 @@ impl<'self> Parser<'self> {
self.err(format!("expected `offset`, found `{}`",
word));
} else {
if !self.consume(':') {
self.err(~"`offset` must be followed by `:`");
}
self.must_consume(':');
match self.integer() {
Some(i) => { offset = Some(i); }
None => {
Expand Down Expand Up @@ -524,15 +531,11 @@ impl<'self> Parser<'self> {
}
}
};
if !self.wsconsume('{') {
self.err(~"selector must be followed by `{`");
}
self.must_consume('{');
self.depth += 1;
let pieces = self.collect();
self.depth -= 1;
if !self.wsconsume('}') {
self.err(~"selector case must be terminated by `}`");
}
self.must_consume('}');
if isother {
if !other.is_none() {
self.err(~"multiple `other` statements in `select");
Expand Down
10 changes: 5 additions & 5 deletions src/test/compile-fail/ifmt-bad-arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,20 @@ fn main() {

// bad syntax of the format string

format!("{"); //~ ERROR: unterminated format string
format!("{"); //~ ERROR: expected `}` but string was terminated
format!("\\ "); //~ ERROR: invalid escape
format!("\\"); //~ ERROR: expected an escape

format!("{0, }", 1); //~ ERROR: expected method
format!("{0, foo}", 1); //~ ERROR: unknown method
format!("{0, select}", "a"); //~ ERROR: must be followed by
format!("{0, plural}", 1); //~ ERROR: must be followed by
format!("{0, select}", "a"); //~ ERROR: expected `,` but found `}`
format!("{0, plural}", 1); //~ ERROR: expected `,` but found `}`

format!("{0, select, a{{}", 1); //~ ERROR: must be terminated
format!("{0, select, a{{}", 1); //~ ERROR: expected `}` but string was terminated
format!("{0, select, {} other{}}", "a"); //~ ERROR: empty selector
format!("{0, select, other{} other{}}", "a"); //~ ERROR: multiple `other`
format!("{0, plural, offset: other{}}", "a"); //~ ERROR: must be an integer
format!("{0, plural, offset 1 other{}}", "a"); //~ ERROR: be followed by `:`
format!("{0, plural, offset 1 other{}}", "a"); //~ ERROR: expected `:` but found `1`
format!("{0, plural, =a{} other{}}", "a"); //~ ERROR: followed by an integer
format!("{0, plural, a{} other{}}", "a"); //~ ERROR: unexpected plural
format!("{0, select, a{}}", "a"); //~ ERROR: must provide an `other`
Expand Down