@@ -33,7 +33,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
33
33
let mut result = match instance {
34
34
ty:: InstanceDef :: Item ( ..) => bug ! ( "item {:?} passed to make_shim" , instance) ,
35
35
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) )
37
37
}
38
38
ty:: InstanceDef :: FnPtrShim ( def_id, ty) => {
39
39
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<'
42
42
Some ( ty:: ClosureKind :: FnMut | ty:: ClosureKind :: Fn ) => Adjustment :: Deref ,
43
43
None => bug ! ( "fn pointer {:?} is not an fn" , ty) ,
44
44
} ;
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) )
55
47
}
56
48
// We are generating a call back to our def-id, which the
57
49
// codegen backend knows to turn to an actual call, be it
58
50
// a virtual call, or a direct call to a function for which
59
51
// indirect calls must be codegen'd differently than direct ones
60
52
// (such as `#[track_caller]`).
61
53
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) )
63
55
}
64
56
ty:: InstanceDef :: ClosureOnceShim { call_once : _ } => {
65
57
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<'
70
62
. unwrap ( )
71
63
. def_id ;
72
64
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) )
80
66
}
81
67
ty:: InstanceDef :: DropGlue ( def_id, ty) => build_drop_shim ( tcx, def_id, ty) ,
82
68
ty:: InstanceDef :: CloneShim ( def_id, ty) => build_clone_shim ( tcx, def_id, ty) ,
@@ -641,29 +627,45 @@ impl CloneShimBuilder<'tcx> {
641
627
}
642
628
}
643
629
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`.
650
632
fn build_call_shim < ' tcx > (
651
633
tcx : TyCtxt < ' tcx > ,
652
634
instance : ty:: InstanceDef < ' tcx > ,
653
635
rcvr_adjustment : Option < Adjustment > ,
654
636
call_kind : CallKind < ' tcx > ,
655
- untuple_args : Option < & [ Ty < ' tcx > ] > ,
656
637
) -> Body < ' tcx > {
657
638
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
661
641
) ;
662
642
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
+
663
660
let def_id = instance. def_id ( ) ;
664
661
let sig = tcx. fn_sig ( def_id) ;
665
662
let mut sig = tcx. erase_late_bound_regions ( & sig) ;
666
663
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
+
667
669
if let CallKind :: Indirect ( fnty) = call_kind {
668
670
// `sig` determines our local decls, and thus the callee type in the `Call` terminator. This
669
671
// can only be an `FnDef` or `FnPtr`, but currently will be `Self` since the types come from
0 commit comments