@@ -559,9 +559,43 @@ impl<'a, 'b> Context<'a, 'b> {
559559 // Now create a vector containing all the arguments
560560 let args = locals. into_iter ( ) . chain ( names. into_iter ( ) . map ( |a| a. unwrap ( ) ) ) ;
561561
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) ;
564597
598+ // Now create the fmt::Arguments struct with all our locals we created.
565599 let ( fn_name, fn_args) = if self . all_pieces_simple {
566600 ( "new" , vec ! [ pieces, args_slice] )
567601 } else {
@@ -582,58 +616,26 @@ impl<'a, 'b> Context<'a, 'b> {
582616 ( "with_placeholders" , vec ! [ pieces, fmt, args_slice] )
583617 } ;
584618
585- let result = self . ecx . expr_call_global ( self . fmtsp , vec ! (
619+ let body = self . ecx . expr_call_global ( self . fmtsp , vec ! (
586620 self . ecx. ident_of( "std" ) ,
587621 self . ecx. ident_of( "fmt" ) ,
588622 self . ecx. ident_of( "Arguments" ) ,
589623 self . ecx. ident_of( fn_name) ) , fn_args) ;
590624
591- let body = match invocation {
625+ match invocation {
592626 Call ( e) => {
593627 let span = e. span ;
594628 self . ecx . expr_call ( span, e, vec ! [
595- self . ecx. expr_addr_of( span, result )
629+ self . ecx. expr_addr_of( span, body )
596630 ] )
597631 }
598632 MethodCall ( e, m) => {
599633 let span = e. span ;
600634 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 )
602636 ] )
603637 }
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+ }
637639 }
638640
639641 fn format_arg ( ecx : & ExtCtxt , sp : Span ,
0 commit comments