@@ -2339,6 +2339,76 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for LayoutError<'tcx> {
2339
2339
}
2340
2340
}
2341
2341
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
+
2342
2412
pub trait FnAbiExt < ' tcx , C >
2343
2413
where
2344
2414
C : LayoutOf < Ty = Ty < ' tcx > , TyLayout = TyLayout < ' tcx > >
@@ -2371,7 +2441,7 @@ where
2371
2441
}
2372
2442
2373
2443
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 ( ) ) ;
2375
2445
2376
2446
call:: FnAbi :: new_internal ( cx, sig, extra_args, |ty, arg_idx| {
2377
2447
let mut layout = cx. layout_of ( ty) ;
0 commit comments