@@ -3510,47 +3510,65 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
35103510 if rt_args_count > 0 {
35113511 let rt_args_array_ptr_id = rt_args_slice_ptr_id. unwrap ( ) ;
35123512
3513- // Each runtime argument has 4 instructions to call one of
3513+ // Each runtime argument has A instructions to call one of
35143514 // the `fmt::rt::Argument::new_*` functions (and temporarily
3515- // store its result), and 4 instructions to copy it into
3516- // the appropriate slot in the array. The groups of 4 and 4
3517- // instructions, for all runtime args, are each separate.
3518- let copies_to_rt_args_array =
3519- try_rev_take ( rt_args_count * 4 ) . ok_or_else ( || {
3515+ // store its result), and B instructions to copy it into
3516+ // the appropriate slot in the array. The groups of A and B
3517+ // instructions, for all runtime args, are each separate,
3518+ // so the B×N later instructions are all processed first,
3519+ // before moving (backwards) to the A×N earlier instructions.
3520+
3521+ let rev_copies_to_rt_args_array_src_ptrs: SmallVec < [ _ ; 4 ] > =
3522+ ( 0 ..rt_args_count) . rev ( ) . map ( |rt_arg_idx| {
3523+ let copy_to_rt_args_array_insts = try_rev_take ( 4 ) . ok_or_else ( || {
35203524 FormatArgsNotRecognized (
3521- "[fmt::rt::Argument; N] copies : ran out of instructions" . into ( ) ,
3525+ "[fmt::rt::Argument; N] copy : ran out of instructions" . into ( ) ,
35223526 )
35233527 } ) ?;
3524- let copies_to_rt_args_array = copies_to_rt_args_array. chunks ( 4 ) ;
3525- let rt_arg_new_calls = try_rev_take ( rt_args_count * 4 ) . ok_or_else ( || {
3526- FormatArgsNotRecognized (
3527- "fmt::rt::Argument::new calls: ran out of instructions" . into ( ) ,
3528- )
3529- } ) ?;
3530- let rt_arg_new_calls = rt_arg_new_calls. chunks ( 4 ) ;
3528+ match copy_to_rt_args_array_insts[ ..] {
3529+ [
3530+ Inst :: InBoundsAccessChain ( array_slot, array_base, array_idx) ,
3531+ Inst :: InBoundsAccessChain ( dst_field_ptr, dst_base_ptr, 0 ) ,
3532+ Inst :: InBoundsAccessChain ( src_field_ptr, src_base_ptr, 0 ) ,
3533+ Inst :: CopyMemory ( copy_dst, copy_src) ,
3534+ ] if array_base == rt_args_array_ptr_id
3535+ && array_idx as usize == rt_arg_idx
3536+ && dst_base_ptr == array_slot
3537+ && ( copy_dst, copy_src) == ( dst_field_ptr, src_field_ptr) =>
3538+ {
3539+ Ok ( src_base_ptr)
3540+ }
3541+ _ => {
3542+ Err ( FormatArgsNotRecognized ( format ! (
3543+ "[fmt::rt::Argument; N] copy sequence ({copy_to_rt_args_array_insts:?})"
3544+ ) ) )
3545+ }
3546+ }
3547+ } ) . collect :: < Result < _ , _ > > ( ) ?;
35313548
3532- for ( rt_arg_idx, ( rt_arg_new_call_insts, copy_to_rt_args_array_insts) ) in
3533- rt_arg_new_calls. zip ( copies_to_rt_args_array) . enumerate ( )
3534- {
3535- let call_ret_slot_ptr = match rt_arg_new_call_insts[ ..] {
3549+ let rev_ref_arg_ids_with_ty_and_spec = ( rev_copies_to_rt_args_array_src_ptrs
3550+ . into_iter ( ) )
3551+ . map ( |copy_to_rt_args_array_src_ptr| {
3552+ let rt_arg_new_call_insts = try_rev_take ( 4 ) . ok_or_else ( || {
3553+ FormatArgsNotRecognized (
3554+ "fmt::rt::Argument::new call: ran out of instructions" . into ( ) ,
3555+ )
3556+ } ) ?;
3557+ match rt_arg_new_call_insts[ ..] {
35363558 [
35373559 Inst :: Call ( call_ret_id, callee_id, ref call_args) ,
35383560 Inst :: InBoundsAccessChain ( tmp_slot_field_ptr, tmp_slot_ptr, 0 ) ,
35393561 Inst :: CompositeExtract ( field, wrapper_newtype, 0 ) ,
35403562 Inst :: Store ( st_dst_ptr, st_val) ,
35413563 ] if wrapper_newtype == call_ret_id
3564+ && tmp_slot_ptr == copy_to_rt_args_array_src_ptr
35423565 && ( st_dst_ptr, st_val) == ( tmp_slot_field_ptr, field) =>
35433566 {
35443567 self . fmt_rt_arg_new_fn_ids_to_ty_and_spec
35453568 . borrow ( )
35463569 . get ( & callee_id)
35473570 . and_then ( |& ( ty, spec) | match call_args[ ..] {
3548- [ x] => {
3549- decoded_format_args
3550- . ref_arg_ids_with_ty_and_spec
3551- . push ( ( x, ty, spec) ) ;
3552- Some ( tmp_slot_ptr)
3553- }
3571+ [ x] => Some ( ( x, ty, spec) ) ,
35543572 _ => None ,
35553573 } )
35563574 }
@@ -3560,26 +3578,13 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
35603578 FormatArgsNotRecognized ( format ! (
35613579 "fmt::rt::Argument::new call sequence ({rt_arg_new_call_insts:?})"
35623580 ) )
3563- } ) ?;
3581+ } )
3582+ } )
3583+ . collect :: < Result < _ , _ > > ( ) ?;
35643584
3565- match copy_to_rt_args_array_insts[ ..] {
3566- [
3567- Inst :: InBoundsAccessChain ( array_slot, array_base, array_idx) ,
3568- Inst :: InBoundsAccessChain ( dst_field_ptr, dst_base_ptr, 0 ) ,
3569- Inst :: InBoundsAccessChain ( src_field_ptr, src_base_ptr, 0 ) ,
3570- Inst :: CopyMemory ( copy_dst, copy_src) ,
3571- ] if array_base == rt_args_array_ptr_id
3572- && array_idx as usize == rt_arg_idx
3573- && dst_base_ptr == array_slot
3574- && src_base_ptr == call_ret_slot_ptr
3575- && ( copy_dst, copy_src) == ( dst_field_ptr, src_field_ptr) => { }
3576- _ => {
3577- return Err ( FormatArgsNotRecognized ( format ! (
3578- "[fmt::rt::Argument; N] copies sequence ({copy_to_rt_args_array_insts:?})"
3579- ) ) ) ;
3580- }
3581- }
3582- }
3585+ decoded_format_args. ref_arg_ids_with_ty_and_spec =
3586+ rev_ref_arg_ids_with_ty_and_spec;
3587+ decoded_format_args. ref_arg_ids_with_ty_and_spec . reverse ( ) ;
35833588 }
35843589
35853590 // If the `pieces: &[&str]` slice needs a bitcast, it'll be here.
0 commit comments