@@ -33,7 +33,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
3333 let mut result = match instance {
3434 ty:: InstanceDef :: Item ( ..) => bug ! ( "item {:?} passed to make_shim" , instance) ,
3535 ty:: InstanceDef :: VtableShim ( def_id) => {
36- build_call_shim ( tcx, instance, Some ( Adjustment :: Deref ) , CallKind :: Direct ( def_id) , None )
36+ build_call_shim ( tcx, instance, Some ( Adjustment :: Deref ) , CallKind :: Direct ( def_id) )
3737 }
3838 ty:: InstanceDef :: FnPtrShim ( def_id, ty) => {
3939 let trait_ = tcx. trait_of_item ( def_id) . unwrap ( ) ;
@@ -42,24 +42,16 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
4242 Some ( ty:: ClosureKind :: FnMut | ty:: ClosureKind :: Fn ) => Adjustment :: Deref ,
4343 None => bug ! ( "fn pointer {:?} is not an fn" , ty) ,
4444 } ;
45- // HACK: we need the "real" argument types for the MIR,
46- // but because our substs are (Self, Args), where Args
47- // is a tuple, we must include the *concrete* argument
48- // types in the MIR. They will be substituted again with
49- // the param-substs, but because they are concrete, this
50- // will not do any harm.
51- let sig = tcx. erase_late_bound_regions ( & ty. fn_sig ( tcx) ) ;
52- let arg_tys = sig. inputs ( ) ;
53-
54- build_call_shim ( tcx, instance, Some ( adjustment) , CallKind :: Indirect ( ty) , Some ( arg_tys) )
45+
46+ build_call_shim ( tcx, instance, Some ( adjustment) , CallKind :: Indirect ( ty) )
5547 }
5648 // We are generating a call back to our def-id, which the
5749 // codegen backend knows to turn to an actual call, be it
5850 // a virtual call, or a direct call to a function for which
5951 // indirect calls must be codegen'd differently than direct ones
6052 // (such as `#[track_caller]`).
6153 ty:: InstanceDef :: ReifyShim ( def_id) => {
62- build_call_shim ( tcx, instance, None , CallKind :: Direct ( def_id) , None )
54+ build_call_shim ( tcx, instance, None , CallKind :: Direct ( def_id) )
6355 }
6456 ty:: InstanceDef :: ClosureOnceShim { call_once : _ } => {
6557 let fn_mut = tcx. require_lang_item ( LangItem :: FnMut , None ) ;
@@ -70,13 +62,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
7062 . unwrap ( )
7163 . def_id ;
7264
73- build_call_shim (
74- tcx,
75- instance,
76- Some ( Adjustment :: RefMut ) ,
77- CallKind :: Direct ( call_mut) ,
78- None ,
79- )
65+ build_call_shim ( tcx, instance, Some ( Adjustment :: RefMut ) , CallKind :: Direct ( call_mut) )
8066 }
8167 ty:: InstanceDef :: DropGlue ( def_id, ty) => build_drop_shim ( tcx, def_id, ty) ,
8268 ty:: InstanceDef :: CloneShim ( def_id, ty) => build_clone_shim ( tcx, def_id, ty) ,
@@ -641,29 +627,45 @@ impl CloneShimBuilder<'tcx> {
641627 }
642628}
643629
644- /// Builds a "call" shim for `instance`. The shim calls the
645- /// function specified by `call_kind`, first adjusting its first
646- /// argument according to `rcvr_adjustment`.
647- ///
648- /// If `untuple_args` is a vec of types, the second argument of the
649- /// function will be untupled as these types.
630+ /// Builds a "call" shim for `instance`. The shim calls the function specified by `call_kind`,
631+ /// first adjusting its first argument according to `rcvr_adjustment`.
650632fn build_call_shim < ' tcx > (
651633 tcx : TyCtxt < ' tcx > ,
652634 instance : ty:: InstanceDef < ' tcx > ,
653635 rcvr_adjustment : Option < Adjustment > ,
654636 call_kind : CallKind < ' tcx > ,
655- untuple_args : Option < & [ Ty < ' tcx > ] > ,
656637) -> Body < ' tcx > {
657638 debug ! (
658- "build_call_shim(instance={:?}, rcvr_adjustment={:?}, \
659- call_kind={:?}, untuple_args={:?})",
660- instance, rcvr_adjustment, call_kind, untuple_args
639+ "build_call_shim(instance={:?}, rcvr_adjustment={:?}, call_kind={:?})" ,
640+ instance, rcvr_adjustment, call_kind
661641 ) ;
662642
643+ // `FnPtrShim` contains the fn pointer type that a call shim is being built for - this is used
644+ // to substitute into the signature of the shim. It is not necessary for users of this
645+ // MIR body to perform further substitutions (see `InstanceDef::has_polymorphic_mir_body`).
646+ let ( sig_substs, untuple_args) = if let ty:: InstanceDef :: FnPtrShim ( _, ty) = instance {
647+ let sig = tcx. erase_late_bound_regions ( & ty. fn_sig ( tcx) ) ;
648+
649+ let untuple_args = sig. inputs ( ) ;
650+
651+ // Create substitutions for the `Self` and `Args` generic parameters of the shim body.
652+ let arg_tup = tcx. mk_tup ( untuple_args. iter ( ) ) ;
653+ let sig_substs = tcx. mk_substs_trait ( ty, & [ ty:: subst:: GenericArg :: from ( arg_tup) ] ) ;
654+
655+ ( Some ( sig_substs) , Some ( untuple_args) )
656+ } else {
657+ ( None , None )
658+ } ;
659+
663660 let def_id = instance. def_id ( ) ;
664661 let sig = tcx. fn_sig ( def_id) ;
665662 let mut sig = tcx. erase_late_bound_regions ( & sig) ;
666663
664+ assert_eq ! ( sig_substs. is_some( ) , !instance. has_polymorphic_mir_body( ) ) ;
665+ if let Some ( sig_substs) = sig_substs {
666+ sig = sig. subst ( tcx, sig_substs) ;
667+ }
668+
667669 if let CallKind :: Indirect ( fnty) = call_kind {
668670 // `sig` determines our local decls, and thus the callee type in the `Call` terminator. This
669671 // can only be an `FnDef` or `FnPtr`, but currently will be `Self` since the types come from
0 commit comments