@@ -8,7 +8,7 @@ use rustc_hir::lang_items::LangItem;
8
8
use rustc_middle:: mir:: { self , AssertKind , InlineAsmMacro , SwitchTargets , UnwindTerminateReason } ;
9
9
use rustc_middle:: ty:: layout:: { HasTyCtxt , LayoutOf , ValidityRequirement } ;
10
10
use rustc_middle:: ty:: print:: { with_no_trimmed_paths, with_no_visible_paths} ;
11
- use rustc_middle:: ty:: { self , Instance , Ty } ;
11
+ use rustc_middle:: ty:: { self , Instance , List , Ty } ;
12
12
use rustc_middle:: { bug, span_bug} ;
13
13
use rustc_session:: config:: OptLevel ;
14
14
use rustc_span:: source_map:: Spanned ;
@@ -827,7 +827,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
827
827
helper : & TerminatorCodegenHelper < ' tcx > ,
828
828
bx : & mut Bx ,
829
829
intrinsic : ty:: IntrinsicDef ,
830
- instance : Option < Instance < ' tcx > > ,
830
+ instance : Instance < ' tcx > ,
831
831
source_info : mir:: SourceInfo ,
832
832
target : Option < mir:: BasicBlock > ,
833
833
unwind : mir:: UnwindAction ,
@@ -837,7 +837,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
837
837
// These are intrinsics that compile to panics so that we can get a message
838
838
// which mentions the offending type, even from a const context.
839
839
if let Some ( requirement) = ValidityRequirement :: from_intrinsic ( intrinsic. name ) {
840
- let ty = instance. unwrap ( ) . args . type_at ( 0 ) ;
840
+ let ty = instance. args . type_at ( 0 ) ;
841
841
842
842
let do_panic = !bx
843
843
. tcx ( )
@@ -910,35 +910,116 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
910
910
let callee = self . codegen_operand ( bx, func) ;
911
911
912
912
let ( instance, mut llfn) = match * callee. layout . ty . kind ( ) {
913
- ty:: FnDef ( def_id, args ) => (
914
- Some ( ty:: Instance :: expect_resolve (
913
+ ty:: FnDef ( def_id, generic_args ) => {
914
+ let instance = ty:: Instance :: expect_resolve (
915
915
bx. tcx ( ) ,
916
916
bx. typing_env ( ) ,
917
917
def_id,
918
- args ,
918
+ generic_args ,
919
919
fn_span,
920
- ) ) ,
921
- None ,
922
- ) ,
920
+ ) ;
921
+
922
+ let instance = match instance. def {
923
+ // We don't need AsyncDropGlueCtorShim here because it is not `noop func`,
924
+ // it is `func returning noop future`
925
+ ty:: InstanceKind :: DropGlue ( _, None ) => {
926
+ // Empty drop glue; a no-op.
927
+ let target = target. unwrap ( ) ;
928
+ return helper. funclet_br ( self , bx, target, mergeable_succ) ;
929
+ }
930
+ ty:: InstanceKind :: Intrinsic ( def_id) => {
931
+ let intrinsic = bx. tcx ( ) . intrinsic ( def_id) . unwrap ( ) ;
932
+ if let Some ( merging_succ) = self . codegen_panic_intrinsic (
933
+ & helper,
934
+ bx,
935
+ intrinsic,
936
+ instance,
937
+ source_info,
938
+ target,
939
+ unwind,
940
+ mergeable_succ,
941
+ ) {
942
+ return merging_succ;
943
+ }
944
+
945
+ let fn_abi = bx. fn_abi_of_instance ( instance, List :: empty ( ) ) ;
946
+
947
+ let mut llargs = Vec :: with_capacity ( 1 ) ;
948
+ let ret_dest = self . make_return_dest (
949
+ bx,
950
+ destination,
951
+ & fn_abi. ret ,
952
+ & mut llargs,
953
+ Some ( intrinsic) ,
954
+ ) ;
955
+ let dest = match ret_dest {
956
+ _ if fn_abi. ret . is_indirect ( ) => llargs[ 0 ] ,
957
+ ReturnDest :: Nothing => bx. const_undef ( bx. type_ptr ( ) ) ,
958
+ ReturnDest :: IndirectOperand ( dst, _) | ReturnDest :: Store ( dst) => {
959
+ dst. val . llval
960
+ }
961
+ ReturnDest :: DirectOperand ( _) => {
962
+ bug ! ( "Cannot use direct operand with an intrinsic call" )
963
+ }
964
+ } ;
965
+
966
+ let args: Vec < _ > =
967
+ args. iter ( ) . map ( |arg| self . codegen_operand ( bx, & arg. node ) ) . collect ( ) ;
968
+
969
+ if matches ! ( intrinsic, ty:: IntrinsicDef { name: sym:: caller_location, .. } )
970
+ {
971
+ let location = self . get_caller_location (
972
+ bx,
973
+ mir:: SourceInfo { span : fn_span, ..source_info } ,
974
+ ) ;
975
+
976
+ assert_eq ! ( llargs, [ ] ) ;
977
+ if let ReturnDest :: IndirectOperand ( tmp, _) = ret_dest {
978
+ location. val . store ( bx, tmp) ;
979
+ }
980
+ self . store_return ( bx, ret_dest, & fn_abi. ret , location. immediate ( ) ) ;
981
+ return helper. funclet_br ( self , bx, target. unwrap ( ) , mergeable_succ) ;
982
+ }
983
+
984
+ match Self :: codegen_intrinsic_call ( bx, instance, fn_abi, & args, dest, span)
985
+ {
986
+ Ok ( ( ) ) => {
987
+ if let ReturnDest :: IndirectOperand ( dst, _) = ret_dest {
988
+ self . store_return ( bx, ret_dest, & fn_abi. ret , dst. val . llval ) ;
989
+ }
990
+
991
+ return if let Some ( target) = target {
992
+ helper. funclet_br ( self , bx, target, mergeable_succ)
993
+ } else {
994
+ bx. unreachable ( ) ;
995
+ MergingSucc :: False
996
+ } ;
997
+ }
998
+ Err ( instance) => {
999
+ if intrinsic. must_be_overridden {
1000
+ span_bug ! (
1001
+ span,
1002
+ "intrinsic {} must be overridden by codegen backend, but isn't" ,
1003
+ intrinsic. name,
1004
+ ) ;
1005
+ }
1006
+ instance
1007
+ }
1008
+ }
1009
+ }
1010
+ _ => instance,
1011
+ } ;
1012
+
1013
+ ( Some ( instance) , None )
1014
+ }
923
1015
ty:: FnPtr ( ..) => ( None , Some ( callee. immediate ( ) ) ) ,
924
1016
_ => bug ! ( "{} is not callable" , callee. layout. ty) ,
925
1017
} ;
926
1018
927
- let def = instance. map ( |i| i. def ) ;
928
-
929
- // We don't need AsyncDropGlueCtorShim here because it is not `noop func`,
930
- // it is `func returning noop future`
931
- if let Some ( ty:: InstanceKind :: DropGlue ( _, None ) ) = def {
932
- // Empty drop glue; a no-op.
933
- let target = target. unwrap ( ) ;
934
- return helper. funclet_br ( self , bx, target, mergeable_succ) ;
935
- }
936
-
937
1019
// FIXME(eddyb) avoid computing this if possible, when `instance` is
938
1020
// available - right now `sig` is only needed for getting the `abi`
939
1021
// and figuring out how many extra args were passed to a C-variadic `fn`.
940
1022
let sig = callee. layout . ty . fn_sig ( bx. tcx ( ) ) ;
941
- let abi = sig. abi ( ) ;
942
1023
943
1024
let extra_args = & args[ sig. inputs ( ) . skip_binder ( ) . len ( ) ..] ;
944
1025
let extra_args = bx. tcx ( ) . mk_type_list_from_iter ( extra_args. iter ( ) . map ( |op_arg| {
@@ -954,83 +1035,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
954
1035
// The arguments we'll be passing. Plus one to account for outptr, if used.
955
1036
let arg_count = fn_abi. args . len ( ) + fn_abi. ret . is_indirect ( ) as usize ;
956
1037
957
- let instance = match def {
958
- Some ( ty:: InstanceKind :: Intrinsic ( def_id) ) => {
959
- let intrinsic = bx. tcx ( ) . intrinsic ( def_id) . unwrap ( ) ;
960
- if let Some ( merging_succ) = self . codegen_panic_intrinsic (
961
- & helper,
962
- bx,
963
- intrinsic,
964
- instance,
965
- source_info,
966
- target,
967
- unwind,
968
- mergeable_succ,
969
- ) {
970
- return merging_succ;
971
- }
972
-
973
- let mut llargs = Vec :: with_capacity ( 1 ) ;
974
- let ret_dest = self . make_return_dest (
975
- bx,
976
- destination,
977
- & fn_abi. ret ,
978
- & mut llargs,
979
- Some ( intrinsic) ,
980
- ) ;
981
- let dest = match ret_dest {
982
- _ if fn_abi. ret . is_indirect ( ) => llargs[ 0 ] ,
983
- ReturnDest :: Nothing => bx. const_undef ( bx. type_ptr ( ) ) ,
984
- ReturnDest :: IndirectOperand ( dst, _) | ReturnDest :: Store ( dst) => dst. val . llval ,
985
- ReturnDest :: DirectOperand ( _) => {
986
- bug ! ( "Cannot use direct operand with an intrinsic call" )
987
- }
988
- } ;
989
-
990
- let args: Vec < _ > =
991
- args. iter ( ) . map ( |arg| self . codegen_operand ( bx, & arg. node ) ) . collect ( ) ;
992
-
993
- if matches ! ( intrinsic, ty:: IntrinsicDef { name: sym:: caller_location, .. } ) {
994
- let location = self
995
- . get_caller_location ( bx, mir:: SourceInfo { span : fn_span, ..source_info } ) ;
996
-
997
- assert_eq ! ( llargs, [ ] ) ;
998
- if let ReturnDest :: IndirectOperand ( tmp, _) = ret_dest {
999
- location. val . store ( bx, tmp) ;
1000
- }
1001
- self . store_return ( bx, ret_dest, & fn_abi. ret , location. immediate ( ) ) ;
1002
- return helper. funclet_br ( self , bx, target. unwrap ( ) , mergeable_succ) ;
1003
- }
1004
-
1005
- let instance = * instance. as_ref ( ) . unwrap ( ) ;
1006
- match Self :: codegen_intrinsic_call ( bx, instance, fn_abi, & args, dest, span) {
1007
- Ok ( ( ) ) => {
1008
- if let ReturnDest :: IndirectOperand ( dst, _) = ret_dest {
1009
- self . store_return ( bx, ret_dest, & fn_abi. ret , dst. val . llval ) ;
1010
- }
1011
-
1012
- return if let Some ( target) = target {
1013
- helper. funclet_br ( self , bx, target, mergeable_succ)
1014
- } else {
1015
- bx. unreachable ( ) ;
1016
- MergingSucc :: False
1017
- } ;
1018
- }
1019
- Err ( instance) => {
1020
- if intrinsic. must_be_overridden {
1021
- span_bug ! (
1022
- span,
1023
- "intrinsic {} must be overridden by codegen backend, but isn't" ,
1024
- intrinsic. name,
1025
- ) ;
1026
- }
1027
- Some ( instance)
1028
- }
1029
- }
1030
- }
1031
- _ => instance,
1032
- } ;
1033
-
1034
1038
let mut llargs = Vec :: with_capacity ( arg_count) ;
1035
1039
1036
1040
// We still need to call `make_return_dest` even if there's no `target`, since
@@ -1040,7 +1044,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
1040
1044
let destination = target. map ( |target| ( return_dest, target) ) ;
1041
1045
1042
1046
// Split the rust-call tupled arguments off.
1043
- let ( first_args, untuple) = if abi == ExternAbi :: RustCall
1047
+ let ( first_args, untuple) = if sig . abi ( ) == ExternAbi :: RustCall
1044
1048
&& let Some ( ( tup, args) ) = args. split_last ( )
1045
1049
{
1046
1050
( args, Some ( tup) )
@@ -1055,7 +1059,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
1055
1059
' make_args: for ( i, arg) in first_args. iter ( ) . enumerate ( ) {
1056
1060
let mut op = self . codegen_operand ( bx, & arg. node ) ;
1057
1061
1058
- if let ( 0 , Some ( ty:: InstanceKind :: Virtual ( _, idx) ) ) = ( i, def) {
1062
+ if let ( 0 , Some ( ty:: InstanceKind :: Virtual ( _, idx) ) ) = ( i, instance . map ( |i| i . def ) ) {
1059
1063
match op. val {
1060
1064
Pair ( data_ptr, meta) => {
1061
1065
// In the case of Rc<Self>, we need to explicitly pass a
0 commit comments