@@ -49,6 +49,9 @@ struct Context<'a, 'b> {
4949 name_types : HashMap < String , ArgumentType > ,
5050 name_ordering : Vec < String > ,
5151
52+ /// The latest consecutive literal strings
53+ literal : Option < String > ,
54+
5255 /// Collection of the compiled `rt::Piece` structures
5356 pieces : Vec < Gc < ast:: Expr > > ,
5457 name_positions : HashMap < String , uint > ,
@@ -362,17 +365,29 @@ impl<'a, 'b> Context<'a, 'b> {
362365 }
363366 }
364367
368+ /// Translate the accumulated string literals to a static `rt::Piece`
369+ fn trans_literal_string ( & mut self ) -> Option < Gc < ast:: Expr > > {
370+ let sp = self . fmtsp ;
371+ self . literal . take ( ) . map ( |s| {
372+ let s = token:: intern_and_get_ident ( s. as_slice ( ) ) ;
373+ self . ecx . expr_call_global ( sp,
374+ self . rtpath ( "String" ) ,
375+ vec ! (
376+ self . ecx. expr_str( sp, s)
377+ ) )
378+ } )
379+ }
380+
365381 /// Translate a `parse::Piece` to a static `rt::Piece`
366- fn trans_piece ( & mut self , piece : & parse:: Piece ) -> Gc < ast:: Expr > {
382+ fn trans_piece ( & mut self , piece : & parse:: Piece ) -> Option < Gc < ast:: Expr > > {
367383 let sp = self . fmtsp ;
368384 match * piece {
369385 parse:: String ( s) => {
370- let s = token:: intern_and_get_ident ( s) ;
371- self . ecx . expr_call_global ( sp,
372- self . rtpath ( "String" ) ,
373- vec ! (
374- self . ecx. expr_str( sp, s)
375- ) )
386+ match self . literal {
387+ Some ( ref mut sb) => sb. push_str ( s) ,
388+ ref mut empty => * empty = Some ( String :: from_str ( s) ) ,
389+ }
390+ None
376391 }
377392 parse:: Argument ( ref arg) => {
378393 // Translate the position
@@ -430,7 +445,7 @@ impl<'a, 'b> Context<'a, 'b> {
430445 let s = self . ecx . expr_struct ( sp, path, vec ! (
431446 self . ecx. field_imm( sp, self . ecx. ident_of( "position" ) , pos) ,
432447 self . ecx. field_imm( sp, self . ecx. ident_of( "format" ) , fmt) ) ) ;
433- self . ecx . expr_call_global ( sp, self . rtpath ( "Argument" ) , vec ! ( s) )
448+ Some ( self . ecx . expr_call_global ( sp, self . rtpath ( "Argument" ) , vec ! ( s) ) )
434449 }
435450 }
436451 }
@@ -694,6 +709,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
694709 name_ordering : name_ordering,
695710 nest_level : 0 ,
696711 next_arg : 0 ,
712+ literal : None ,
697713 pieces : Vec :: new ( ) ,
698714 method_statics : Vec :: new ( ) ,
699715 fmtsp : sp,
@@ -712,8 +728,14 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
712728 Some ( piece) => {
713729 if parser. errors . len ( ) > 0 { break }
714730 cx. verify_piece ( & piece) ;
715- let piece = cx. trans_piece ( & piece) ;
716- cx. pieces . push ( piece) ;
731+ match cx. trans_piece ( & piece) {
732+ Some ( piece) => {
733+ cx. trans_literal_string ( ) . map ( |piece|
734+ cx. pieces . push ( piece) ) ;
735+ cx. pieces . push ( piece) ;
736+ }
737+ None => { }
738+ }
717739 }
718740 None => break
719741 }
@@ -727,6 +749,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
727749 }
728750 None => { }
729751 }
752+ cx. trans_literal_string ( ) . map ( |piece| cx. pieces . push ( piece) ) ;
730753
731754 // Make sure that all arguments were used and all arguments have types.
732755 for ( i, ty) in cx. arg_types . iter ( ) . enumerate ( ) {
0 commit comments