@@ -2339,6 +2339,76 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for LayoutError<'tcx> {
23392339 }
23402340}
23412341
2342+
2343+ impl < ' tcx > ty:: Instance < ' tcx > {
2344+ // NOTE(eddyb) this is private to avoid using it from outside of
2345+ // `FnAbi::of_instance` - any other uses are either too high-level
2346+ // for `Instance` (e.g. typeck would use `Ty::fn_sig` instead),
2347+ // or should go through `FnAbi` instead, to avoid losing any
2348+ // adjustments `FnAbi::of_instance` might be performing.
2349+ fn fn_sig_for_fn_abi ( & self , tcx : TyCtxt < ' tcx > ) -> ty:: PolyFnSig < ' tcx > {
2350+ let ty = self . ty ( tcx) ;
2351+ match ty. kind {
2352+ ty:: FnDef ( ..) |
2353+ // Shims currently have type FnPtr. Not sure this should remain.
2354+ ty:: FnPtr ( _) => {
2355+ let mut sig = ty. fn_sig ( tcx) ;
2356+ if let ty:: InstanceDef :: VtableShim ( ..) = self . def {
2357+ // Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`.
2358+ sig = sig. map_bound ( |mut sig| {
2359+ let mut inputs_and_output = sig. inputs_and_output . to_vec ( ) ;
2360+ inputs_and_output[ 0 ] = tcx. mk_mut_ptr ( inputs_and_output[ 0 ] ) ;
2361+ sig. inputs_and_output = tcx. intern_type_list ( & inputs_and_output) ;
2362+ sig
2363+ } ) ;
2364+ }
2365+ sig
2366+ }
2367+ ty:: Closure ( def_id, substs) => {
2368+ let sig = substs. as_closure ( ) . sig ( def_id, tcx) ;
2369+
2370+ let env_ty = tcx. closure_env_ty ( def_id, substs) . unwrap ( ) ;
2371+ sig. map_bound ( |sig| tcx. mk_fn_sig (
2372+ iter:: once ( * env_ty. skip_binder ( ) ) . chain ( sig. inputs ( ) . iter ( ) . cloned ( ) ) ,
2373+ sig. output ( ) ,
2374+ sig. c_variadic ,
2375+ sig. unsafety ,
2376+ sig. abi
2377+ ) )
2378+ }
2379+ ty:: Generator ( def_id, substs, _) => {
2380+ let sig = substs. as_generator ( ) . poly_sig ( def_id, tcx) ;
2381+
2382+ let env_region = ty:: ReLateBound ( ty:: INNERMOST , ty:: BrEnv ) ;
2383+ let env_ty = tcx. mk_mut_ref ( tcx. mk_region ( env_region) , ty) ;
2384+
2385+ let pin_did = tcx. lang_items ( ) . pin_type ( ) . unwrap ( ) ;
2386+ let pin_adt_ref = tcx. adt_def ( pin_did) ;
2387+ let pin_substs = tcx. intern_substs ( & [ env_ty. into ( ) ] ) ;
2388+ let env_ty = tcx. mk_adt ( pin_adt_ref, pin_substs) ;
2389+
2390+ sig. map_bound ( |sig| {
2391+ let state_did = tcx. lang_items ( ) . gen_state ( ) . unwrap ( ) ;
2392+ let state_adt_ref = tcx. adt_def ( state_did) ;
2393+ let state_substs = tcx. intern_substs ( & [
2394+ sig. yield_ty . into ( ) ,
2395+ sig. return_ty . into ( ) ,
2396+ ] ) ;
2397+ let ret_ty = tcx. mk_adt ( state_adt_ref, state_substs) ;
2398+
2399+ tcx. mk_fn_sig ( iter:: once ( env_ty) ,
2400+ ret_ty,
2401+ false ,
2402+ hir:: Unsafety :: Normal ,
2403+ rustc_target:: spec:: abi:: Abi :: Rust
2404+ )
2405+ } )
2406+ }
2407+ _ => bug ! ( "unexpected type {:?} in Instance::fn_sig" , ty)
2408+ }
2409+ }
2410+ }
2411+
23422412pub trait FnAbiExt < ' tcx , C >
23432413where
23442414 C : LayoutOf < Ty = Ty < ' tcx > , TyLayout = TyLayout < ' tcx > >
@@ -2371,7 +2441,7 @@ where
23712441 }
23722442
23732443 fn of_instance ( cx : & C , instance : ty:: Instance < ' tcx > , extra_args : & [ Ty < ' tcx > ] ) -> Self {
2374- let sig = instance. fn_sig ( cx. tcx ( ) ) ;
2444+ let sig = instance. fn_sig_for_fn_abi ( cx. tcx ( ) ) ;
23752445
23762446 call:: FnAbi :: new_internal ( cx, sig, extra_args, |ty, arg_idx| {
23772447 let mut layout = cx. layout_of ( ty) ;
0 commit comments