@@ -435,14 +435,16 @@ pub(crate) fn codegen_terminator_call<'tcx>(
435435 destination : Option < ( Place < ' tcx > , BasicBlock ) > ,
436436) {
437437 let fn_ty = fx. monomorphize ( & func. ty ( fx. mir , fx. tcx ) ) ;
438- let sig = fx
438+ let fn_sig = fx
439439 . tcx
440440 . normalize_erasing_late_bound_regions ( ParamEnv :: reveal_all ( ) , & fn_ty. fn_sig ( fx. tcx ) ) ;
441441
442- let destination = destination
443- . map ( |( place, bb) | ( trans_place ( fx, place) , bb) ) ;
442+ // FIXME mark the current block as cold when calling a `#[cold]` function.
443+
444+ let destination = destination. map ( |( place, bb) | ( trans_place ( fx, place) , bb) ) ;
444445
445- if let ty:: FnDef ( def_id, substs) = fn_ty. kind {
446+ // Handle special calls like instrinsics and empty drop glue.
447+ let instance = if let ty:: FnDef ( def_id, substs) = fn_ty. kind {
446448 let instance =
447449 ty:: Instance :: resolve ( fx. tcx , ty:: ParamEnv :: reveal_all ( ) , def_id, substs) . unwrap ( ) ;
448450
@@ -469,24 +471,29 @@ pub(crate) fn codegen_terminator_call<'tcx>(
469471 fx. bcx . ins ( ) . jump ( ret_block, & [ ] ) ;
470472 return ;
471473 }
472- _ => { }
474+ _ => Some ( instance )
473475 }
474- }
476+ } else {
477+ None
478+ } ;
475479
476480 // Unpack arguments tuple for closures
477- let args = if sig . abi == Abi :: RustCall {
481+ let args = if fn_sig . abi == Abi :: RustCall {
478482 assert_eq ! ( args. len( ) , 2 , "rust-call abi requires two arguments" ) ;
479483 let self_arg = trans_operand ( fx, & args[ 0 ] ) ;
480484 let pack_arg = trans_operand ( fx, & args[ 1 ] ) ;
481- let mut args = Vec :: new ( ) ;
482- args. push ( self_arg) ;
483- match pack_arg. layout ( ) . ty . kind {
485+
486+ let tupled_arguments = match pack_arg. layout ( ) . ty . kind {
484487 ty:: Tuple ( ref tupled_arguments) => {
485- for ( i, _) in tupled_arguments. iter ( ) . enumerate ( ) {
486- args. push ( pack_arg. value_field ( fx, mir:: Field :: new ( i) ) ) ;
487- }
488+ tupled_arguments
488489 }
489490 _ => bug ! ( "argument to function with \" rust-call\" ABI is not a tuple" ) ,
491+ } ;
492+
493+ let mut args = Vec :: with_capacity ( 1 + tupled_arguments. len ( ) ) ;
494+ args. push ( self_arg) ;
495+ for i in 0 ..tupled_arguments. len ( ) {
496+ args. push ( pack_arg. value_field ( fx, mir:: Field :: new ( i) ) ) ;
490497 }
491498 args
492499 } else {
@@ -495,18 +502,6 @@ pub(crate) fn codegen_terminator_call<'tcx>(
495502 . collect :: < Vec < _ > > ( )
496503 } ;
497504
498- // FIXME mark the current block as cold when calling a `#[cold]` function.
499- let fn_sig = fx
500- . tcx
501- . normalize_erasing_late_bound_regions ( ParamEnv :: reveal_all ( ) , & fn_ty. fn_sig ( fx. tcx ) ) ;
502-
503- let instance = match fn_ty. kind {
504- ty:: FnDef ( def_id, substs) => {
505- Some ( Instance :: resolve ( fx. tcx , ParamEnv :: reveal_all ( ) , def_id, substs) . unwrap ( ) )
506- }
507- _ => None ,
508- } ;
509-
510505 // | indirect call target
511506 // | | the first argument to be passed
512507 // v v v virtual calls are special cased below
0 commit comments