@@ -435,14 +435,16 @@ pub(crate) fn codegen_terminator_call<'tcx>(
435
435
destination : Option < ( Place < ' tcx > , BasicBlock ) > ,
436
436
) {
437
437
let fn_ty = fx. monomorphize ( & func. ty ( fx. mir , fx. tcx ) ) ;
438
- let sig = fx
438
+ let fn_sig = fx
439
439
. tcx
440
440
. normalize_erasing_late_bound_regions ( ParamEnv :: reveal_all ( ) , & fn_ty. fn_sig ( fx. tcx ) ) ;
441
441
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) ) ;
444
445
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 {
446
448
let instance =
447
449
ty:: Instance :: resolve ( fx. tcx , ty:: ParamEnv :: reveal_all ( ) , def_id, substs) . unwrap ( ) ;
448
450
@@ -469,24 +471,29 @@ pub(crate) fn codegen_terminator_call<'tcx>(
469
471
fx. bcx . ins ( ) . jump ( ret_block, & [ ] ) ;
470
472
return ;
471
473
}
472
- _ => { }
474
+ _ => Some ( instance )
473
475
}
474
- }
476
+ } else {
477
+ None
478
+ } ;
475
479
476
480
// Unpack arguments tuple for closures
477
- let args = if sig . abi == Abi :: RustCall {
481
+ let args = if fn_sig . abi == Abi :: RustCall {
478
482
assert_eq ! ( args. len( ) , 2 , "rust-call abi requires two arguments" ) ;
479
483
let self_arg = trans_operand ( fx, & args[ 0 ] ) ;
480
484
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 {
484
487
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
488
489
}
489
490
_ => 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) ) ) ;
490
497
}
491
498
args
492
499
} else {
@@ -495,18 +502,6 @@ pub(crate) fn codegen_terminator_call<'tcx>(
495
502
. collect :: < Vec < _ > > ( )
496
503
} ;
497
504
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
-
510
505
// | indirect call target
511
506
// | | the first argument to be passed
512
507
// v v v virtual calls are special cased below
0 commit comments