@@ -559,9 +559,43 @@ impl<'a, 'b> Context<'a, 'b> {
559
559
// Now create a vector containing all the arguments
560
560
let args = locals. into_iter ( ) . chain ( names. into_iter ( ) . map ( |a| a. unwrap ( ) ) ) ;
561
561
562
- // Now create the fmt::Arguments struct with all our locals we created.
563
- let args_slice = self . ecx . expr_vec_slice ( self . fmtsp , args. collect ( ) ) ;
562
+ let args_array = self . ecx . expr_vec ( self . fmtsp , args. collect ( ) ) ;
563
+
564
+ // Constructs an AST equivalent to:
565
+ //
566
+ // match (&arg0, &arg1) {
567
+ // (tmp0, tmp1) => args_array
568
+ // }
569
+ //
570
+ // It was:
571
+ //
572
+ // let tmp0 = &arg0;
573
+ // let tmp1 = &arg1;
574
+ // args_array
575
+ //
576
+ // Because of #11585 the new temporary lifetime rule, the enclosing
577
+ // statements for these temporaries become the let's themselves.
578
+ // If one or more of them are RefCell's, RefCell borrow() will also
579
+ // end there; they don't last long enough for args_array to use them.
580
+ // The match expression solves the scope problem.
581
+ //
582
+ // Note, it may also very well be transformed to:
583
+ //
584
+ // match arg0 {
585
+ // ref tmp0 => {
586
+ // match arg1 => {
587
+ // ref tmp1 => args_array } } }
588
+ //
589
+ // But the nested match expression is proved to perform not as well
590
+ // as series of let's; the first approach does.
591
+ let pat = self . ecx . pat_tuple ( self . fmtsp , pats) ;
592
+ let arm = self . ecx . arm ( self . fmtsp , vec ! ( pat) , args_array) ;
593
+ let head = self . ecx . expr ( self . fmtsp , ast:: ExprTup ( heads) ) ;
594
+ let result = self . ecx . expr_match ( self . fmtsp , head, vec ! ( arm) ) ;
595
+
596
+ let args_slice = self . ecx . expr_addr_of ( self . fmtsp , result) ;
564
597
598
+ // Now create the fmt::Arguments struct with all our locals we created.
565
599
let ( fn_name, fn_args) = if self . all_pieces_simple {
566
600
( "new" , vec ! [ pieces, args_slice] )
567
601
} else {
@@ -582,58 +616,26 @@ impl<'a, 'b> Context<'a, 'b> {
582
616
( "with_placeholders" , vec ! [ pieces, fmt, args_slice] )
583
617
} ;
584
618
585
- let result = self . ecx . expr_call_global ( self . fmtsp , vec ! (
619
+ let body = self . ecx . expr_call_global ( self . fmtsp , vec ! (
586
620
self . ecx. ident_of( "std" ) ,
587
621
self . ecx. ident_of( "fmt" ) ,
588
622
self . ecx. ident_of( "Arguments" ) ,
589
623
self . ecx. ident_of( fn_name) ) , fn_args) ;
590
624
591
- let body = match invocation {
625
+ match invocation {
592
626
Call ( e) => {
593
627
let span = e. span ;
594
628
self . ecx . expr_call ( span, e, vec ! [
595
- self . ecx. expr_addr_of( span, result )
629
+ self . ecx. expr_addr_of( span, body )
596
630
] )
597
631
}
598
632
MethodCall ( e, m) => {
599
633
let span = e. span ;
600
634
self . ecx . expr_method_call ( span, e, m, vec ! [
601
- self . ecx. expr_addr_of( span, result )
635
+ self . ecx. expr_addr_of( span, body )
602
636
] )
603
637
}
604
- } ;
605
-
606
- // Constructs an AST equivalent to:
607
- //
608
- // match (&arg0, &arg1) {
609
- // (tmp0, tmp1) => body
610
- // }
611
- //
612
- // It was:
613
- //
614
- // let tmp0 = &arg0;
615
- // let tmp1 = &arg1;
616
- // body
617
- //
618
- // Because of #11585 the new temporary lifetime rule, the enclosing
619
- // statements for these temporaries become the let's themselves.
620
- // If one or more of them are RefCell's, RefCell borrow() will also
621
- // end there; they don't last long enough for body to use them. The
622
- // match expression solves the scope problem.
623
- //
624
- // Note, it may also very well be transformed to:
625
- //
626
- // match arg0 {
627
- // ref tmp0 => {
628
- // match arg1 => {
629
- // ref tmp1 => body } } }
630
- //
631
- // But the nested match expression is proved to perform not as well
632
- // as series of let's; the first approach does.
633
- let pat = self . ecx . pat_tuple ( self . fmtsp , pats) ;
634
- let arm = self . ecx . arm ( self . fmtsp , vec ! ( pat) , body) ;
635
- let head = self . ecx . expr ( self . fmtsp , ast:: ExprTup ( heads) ) ;
636
- self . ecx . expr_match ( self . fmtsp , head, vec ! ( arm) )
638
+ }
637
639
}
638
640
639
641
fn format_arg ( ecx : & ExtCtxt , sp : Span ,
0 commit comments