@@ -150,12 +150,17 @@ pub struct Parser<'a> {
150150 pub errors : Vec < ParseError > ,
151151 /// Current position of implicit positional argument pointer
152152 curarg : usize ,
153+ /// `Some(raw count)` when the string is "raw", used to position spans correctly
154+ style : Option < usize > ,
155+ /// How many newlines have been seen in the string so far, to adjust the error spans
156+ seen_newlines : usize ,
153157}
154158
155159impl < ' a > Iterator for Parser < ' a > {
156160 type Item = Piece < ' a > ;
157161
158162 fn next ( & mut self ) -> Option < Piece < ' a > > {
163+ let raw = self . style . map ( |raw| raw + self . seen_newlines ) . unwrap_or ( 0 ) ;
159164 if let Some ( & ( pos, c) ) = self . cur . peek ( ) {
160165 match c {
161166 '{' => {
@@ -170,20 +175,24 @@ impl<'a> Iterator for Parser<'a> {
170175 }
171176 '}' => {
172177 self . cur . next ( ) ;
173- let pos = pos + 1 ;
174178 if self . consume ( '}' ) {
175- Some ( String ( self . string ( pos) ) )
179+ Some ( String ( self . string ( pos + 1 ) ) )
176180 } else {
181+ let err_pos = pos + raw + 1 ;
177182 self . err_with_note (
178183 "unmatched `}` found" ,
179184 "unmatched `}`" ,
180185 "if you intended to print `}`, you can escape it using `}}`" ,
181- pos ,
182- pos ,
186+ err_pos ,
187+ err_pos ,
183188 ) ;
184189 None
185190 }
186191 }
192+ '\n' => {
193+ self . seen_newlines += 1 ;
194+ Some ( String ( self . string ( pos) ) )
195+ }
187196 _ => Some ( String ( self . string ( pos) ) ) ,
188197 }
189198 } else {
@@ -194,12 +203,14 @@ impl<'a> Iterator for Parser<'a> {
194203
195204impl < ' a > Parser < ' a > {
196205 /// Creates a new parser for the given format string
197- pub fn new ( s : & ' a str ) -> Parser < ' a > {
206+ pub fn new ( s : & ' a str , style : Option < usize > ) -> Parser < ' a > {
198207 Parser {
199208 input : s,
200209 cur : s. char_indices ( ) . peekable ( ) ,
201210 errors : vec ! [ ] ,
202211 curarg : 0 ,
212+ style,
213+ seen_newlines : 0 ,
203214 }
204215 }
205216
@@ -262,24 +273,32 @@ impl<'a> Parser<'a> {
262273 /// found, an error is emitted.
263274 fn must_consume ( & mut self , c : char ) {
264275 self . ws ( ) ;
276+ let raw = self . style . unwrap_or ( 0 ) ;
277+
278+ let padding = raw + self . seen_newlines ;
265279 if let Some ( & ( pos, maybe) ) = self . cur . peek ( ) {
266280 if c == maybe {
267281 self . cur . next ( ) ;
268282 } else {
283+ let pos = pos + padding + 1 ;
269284 self . err ( format ! ( "expected `{:?}`, found `{:?}`" , c, maybe) ,
270285 format ! ( "expected `{}`" , c) ,
271- pos + 1 ,
272- pos + 1 ) ;
286+ pos,
287+ pos) ;
273288 }
274289 } else {
275290 let msg = format ! ( "expected `{:?}` but string was terminated" , c) ;
276- let pos = self . input . len ( ) + 1 ; // point at closing `"`
291+ // point at closing `"`, unless the last char is `\n` to account for `println`
292+ let pos = match self . input . chars ( ) . last ( ) {
293+ Some ( '\n' ) => self . input . len ( ) ,
294+ _ => self . input . len ( ) + 1 ,
295+ } ;
277296 if c == '}' {
278297 self . err_with_note ( msg,
279298 format ! ( "expected `{:?}`" , c) ,
280299 "if you intended to print `{`, you can escape it using `{{`" ,
281- pos,
282- pos) ;
300+ pos + padding ,
301+ pos + padding ) ;
283302 } else {
284303 self . err ( msg, format ! ( "expected `{:?}`" , c) , pos, pos) ;
285304 }
@@ -536,7 +555,7 @@ mod tests {
536555 use super :: * ;
537556
538557 fn same ( fmt : & ' static str , p : & [ Piece < ' static > ] ) {
539- let parser = Parser :: new ( fmt) ;
558+ let parser = Parser :: new ( fmt, None ) ;
540559 assert ! ( parser. collect:: <Vec <Piece <' static >>>( ) == p) ;
541560 }
542561
@@ -552,7 +571,7 @@ mod tests {
552571 }
553572
554573 fn musterr ( s : & str ) {
555- let mut p = Parser :: new ( s) ;
574+ let mut p = Parser :: new ( s, None ) ;
556575 p. next ( ) ;
557576 assert ! ( !p. errors. is_empty( ) ) ;
558577 }
0 commit comments