@@ -49,6 +49,9 @@ struct Context<'a, 'b> {
49
49
name_types : HashMap < String , ArgumentType > ,
50
50
name_ordering : Vec < String > ,
51
51
52
+ /// The latest consecutive literal strings
53
+ literal : Option < String > ,
54
+
52
55
/// Collection of the compiled `rt::Piece` structures
53
56
pieces : Vec < Gc < ast:: Expr > > ,
54
57
name_positions : HashMap < String , uint > ,
@@ -362,17 +365,29 @@ impl<'a, 'b> Context<'a, 'b> {
362
365
}
363
366
}
364
367
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
+
365
381
/// 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 > > {
367
383
let sp = self . fmtsp ;
368
384
match * piece {
369
385
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
376
391
}
377
392
parse:: Argument ( ref arg) => {
378
393
// Translate the position
@@ -430,7 +445,7 @@ impl<'a, 'b> Context<'a, 'b> {
430
445
let s = self . ecx . expr_struct ( sp, path, vec ! (
431
446
self . ecx. field_imm( sp, self . ecx. ident_of( "position" ) , pos) ,
432
447
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) ) )
434
449
}
435
450
}
436
451
}
@@ -694,6 +709,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
694
709
name_ordering : name_ordering,
695
710
nest_level : 0 ,
696
711
next_arg : 0 ,
712
+ literal : None ,
697
713
pieces : Vec :: new ( ) ,
698
714
method_statics : Vec :: new ( ) ,
699
715
fmtsp : sp,
@@ -712,8 +728,14 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
712
728
Some ( piece) => {
713
729
if parser. errors . len ( ) > 0 { break }
714
730
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
+ }
717
739
}
718
740
None => break
719
741
}
@@ -727,6 +749,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span,
727
749
}
728
750
None => { }
729
751
}
752
+ cx. trans_literal_string ( ) . map ( |piece| cx. pieces . push ( piece) ) ;
730
753
731
754
// Make sure that all arguments were used and all arguments have types.
732
755
for ( i, ty) in cx. arg_types . iter ( ) . enumerate ( ) {
0 commit comments