[[package]]
name = "fmt_macros"
version = "0.0.0"
+dependencies = [
+ "syntax 0.0.0",
+]
[[package]]
name = "fnv"
name = "fmt_macros"
path = "lib.rs"
crate-type = ["dylib"]
+
+[dependencies]
+syntax = { path = "../libsyntax" }
pub use self::Flag::*;
pub use self::Count::*;
+extern crate syntax;
+
use std::str;
use std::string;
use std::iter;
pub errors: Vec<ParseError>,
/// Current position of implicit positional argument pointer
curarg: usize,
+ /// The style of the string (raw or not), used to position spans correctly
+ style: syntax::ast::StrStyle,
+ /// How many newlines have been seen in the string so far, to adjust the error spans
+ seen_newlines: usize,
}
impl<'a> Iterator for Parser<'a> {
type Item = Piece<'a>;
fn next(&mut self) -> Option<Piece<'a>> {
+ let raw = match self.style {
+ syntax::ast::StrStyle::Raw(raw) => raw as usize + self.seen_newlines,
+ _ => 0,
+ };
if let Some(&(pos, c)) = self.cur.peek() {
match c {
'{' => {
+ let pos = pos + raw + 1;
self.cur.next();
if self.consume('{') {
- Some(String(self.string(pos + 1)))
+ Some(String(self.string(pos)))
} else {
let ret = Some(NextArgument(self.argument()));
self.must_consume('}');
}
}
'}' => {
+ let pos = pos + raw + 1;
self.cur.next();
- let pos = pos + 1;
if self.consume('}') {
Some(String(self.string(pos)))
} else {
None
}
}
+ '\n' => {
+ self.seen_newlines += 1;
+ Some(String(self.string(pos)))
+ }
_ => Some(String(self.string(pos))),
}
} else {
impl<'a> Parser<'a> {
/// Creates a new parser for the given format string
- pub fn new(s: &'a str) -> Parser<'a> {
+ pub fn new(s: &'a str, style: syntax::ast::StrStyle) -> Parser<'a> {
Parser {
input: s,
cur: s.char_indices().peekable(),
errors: vec![],
curarg: 0,
+ style,
+ seen_newlines: 0,
}
}
/// found, an error is emitted.
fn must_consume(&mut self, c: char) {
self.ws();
+ let raw = match self.style {
+ syntax::ast::StrStyle::Raw(raw) => raw as usize,
+ _ => 0,
+ };
+ let padding = raw + self.seen_newlines;
if let Some(&(pos, maybe)) = self.cur.peek() {
if c == maybe {
self.cur.next();
} else {
self.err(format!("expected `{:?}`, found `{:?}`", c, maybe),
format!("expected `{}`", c),
- pos + 1,
- pos + 1);
+ pos + padding + 1,
+ pos + padding + 1);
}
} else {
let msg = format!("expected `{:?}` but string was terminated", c);
self.err_with_note(msg,
format!("expected `{:?}`", c),
"if you intended to print `{`, you can escape it using `{{`",
- pos,
- pos);
+ pos + padding,
+ pos + padding);
} else {
self.err(msg, format!("expected `{:?}`", c), pos, pos);
}
use super::*;
fn same(fmt: &'static str, p: &[Piece<'static>]) {
- let parser = Parser::new(fmt);
+ let parser = Parser::new(fmt, syntax::ast::StrStyle::Cooked);
assert!(parser.collect::<Vec<Piece<'static>>>() == p);
}
}
fn musterr(s: &str) {
- let mut p = Parser::new(s);
+ let mut p = Parser::new(fmt, syntax::ast::StrStyle::Cooked);
p.next();
assert!(!p.errors.is_empty());
}
use util::common::ErrorReported;
use util::nodemap::FxHashMap;
-use syntax::ast::{MetaItem, NestedMetaItem};
+use syntax::ast::{self, MetaItem, NestedMetaItem};
use syntax::attr;
use syntax_pos::Span;
use syntax_pos::symbol::LocalInternedString;
{
let name = tcx.item_name(trait_def_id);
let generics = tcx.generics_of(trait_def_id);
- let parser = Parser::new(&self.0);
+ let parser = Parser::new(&self.0, ast::StrStyle::Cooked);
let mut result = Ok(());
for token in parser {
match token {
Some((name, value))
}).collect::<FxHashMap<String, String>>();
- let parser = Parser::new(&self.0);
+ let parser = Parser::new(&self.0, ast::StrStyle::Cooked);
parser.map(|p| {
match p {
Piece::String(s) => s,
};
let fmt_str = &*fmt.node.0.as_str();
- let mut parser = parse::Parser::new(fmt_str);
+ let mut parser = parse::Parser::new(fmt_str, fmt.node.1);
let mut pieces = vec![];
while let Some(mut piece) = parser.next() {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+// ignore-tidy-tab
+
fn main() {
println!("{");
//~^ ERROR invalid format string: expected `'}'` but string was terminated
//~^ ERROR invalid format string: unmatched `}` found
let _ = format!("{\\}");
//~^ ERROR invalid format string: expected `'}'`, found `'\\'`
+ let _ = format!("\n\n\n{\n\n\n");
+ //~^ ERROR invalid format string
+ let _ = format!(r###"
+
+
+
+ {"###);
+ //~^ ERROR invalid format string
+ let _ = format!(r###"
+
+
+
+ {
+
+"###);
+ //~^^ ERROR invalid format string
+ let _ = format!(r###"
+
+
+
+ }
+
+"###);
+ //~^^^ ERROR invalid format string
+ let _ = format!(r###"
+
+
+
+ }
+
+"###);
+ //~^^^ ERROR invalid format string: unmatched `}` found
}
error: invalid format string: expected `'}'` but string was terminated
- --> $DIR/format-string-error.rs:12:16
+ --> $DIR/format-string-error.rs:14:16
|
LL | println!("{");
| ^ expected `'}'` in format string
= note: if you intended to print `{`, you can escape it using `{{`
error: invalid format string: unmatched `}` found
- --> $DIR/format-string-error.rs:15:15
+ --> $DIR/format-string-error.rs:17:15
|
LL | println!("}");
| ^ unmatched `}` in format string
= note: if you intended to print `}`, you can escape it using `}}`
error: invalid format string: invalid argument name `_foo`
- --> $DIR/format-string-error.rs:17:23
+ --> $DIR/format-string-error.rs:19:23
|
LL | let _ = format!("{_foo}", _foo = 6usize);
| ^^^^ invalid argument name in format string
= note: argument names cannot start with an underscore
error: invalid format string: invalid argument name `_`
- --> $DIR/format-string-error.rs:19:23
+ --> $DIR/format-string-error.rs:21:23
|
LL | let _ = format!("{_}", _ = 6usize);
| ^ invalid argument name in format string
= note: argument names cannot start with an underscore
error: invalid format string: expected `'}'` but string was terminated
- --> $DIR/format-string-error.rs:21:23
+ --> $DIR/format-string-error.rs:23:23
|
LL | let _ = format!("{");
| ^ expected `'}'` in format string
= note: if you intended to print `{`, you can escape it using `{{`
error: invalid format string: unmatched `}` found
- --> $DIR/format-string-error.rs:23:22
+ --> $DIR/format-string-error.rs:25:22
|
LL | let _ = format!("}");
| ^ unmatched `}` in format string
= note: if you intended to print `}`, you can escape it using `}}`
error: invalid format string: expected `'}'`, found `'/'`
- --> $DIR/format-string-error.rs:25:23
+ --> $DIR/format-string-error.rs:27:23
|
LL | let _ = format!("{/}");
| ^ expected `}` in format string
-error: aborting due to 7 previous errors
+error: invalid format string: expected `'}'` but string was terminated
+ --> $DIR/format-string-error.rs:29:29
+ |
+LL | let _ = format!("/n/n/n{/n/n/n");
+ | ^ expected `'}'` in format string
+ |
+ = note: if you intended to print `{`, you can escape it using `{{`
+
+error: invalid format string: expected `'}'` but string was terminated
+ --> $DIR/format-string-error.rs:35:3
+ |
+LL | {"###);
+ | ^ expected `'}'` in format string
+ |
+ = note: if you intended to print `{`, you can escape it using `{{`
+
+error: invalid format string: expected `'}'` but string was terminated
+ --> $DIR/format-string-error.rs:42:1
+ |
+LL |
+ | ^ expected `'}'` in format string
+ |
+ = note: if you intended to print `{`, you can escape it using `{{`
+
+error: invalid format string: unmatched `}` found
+ --> $DIR/format-string-error.rs:49:2
+ |
+LL | }
+ | ^ 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.rs:57:9
+ |
+LL | }
+ | ^ unmatched `}` in format string
+ |
+ = note: if you intended to print `}`, you can escape it using `}}`
+
+error: aborting due to 12 previous errors