@@ -20,7 +20,7 @@ use rustc_middle::ty::{
2020use rustc_middle:: ty:: { List , TypeFoldable } ;
2121use rustc_span:: def_id:: DefId ;
2222use rustc_target:: abi:: {
23- Abi :: Vector , FieldsShape , Integer , Layout , Primitive , Size , TagEncoding , TyAndLayout ,
23+ Abi :: Vector , FieldsShape , Integer , LayoutS , Primitive , Size , TagEncoding , TyAndLayout ,
2424 VariantIdx , Variants ,
2525} ;
2626use rustc_target:: spec:: abi:: Abi ;
@@ -327,10 +327,12 @@ impl<'tcx> GotocCtx<'tcx> {
327327 self . sig_with_untupled_args ( sig)
328328 }
329329
330- // Adapted from `fn_sig_for_fn_abi` in compiler/rustc_middle/src/ty/layout.rs
330+ // Adapted from `fn_sig_for_fn_abi` in
331+ // https://github.com/rust-lang/rust/blob/739d68a76e35b22341d9930bb6338bf202ba05ba/compiler/rustc_ty_utils/src/abi.rs#L88
331332 // Code duplication tracked here: https://github.com/model-checking/kani/issues/1365
332333 fn generator_sig (
333334 & self ,
335+ did : & DefId ,
334336 ty : Ty < ' tcx > ,
335337 substs : ty:: subst:: SubstsRef < ' tcx > ,
336338 ) -> ty:: PolyFnSig < ' tcx > {
@@ -352,10 +354,21 @@ impl<'tcx> GotocCtx<'tcx> {
352354 let env_ty = self . tcx . mk_adt ( pin_adt_ref, pin_substs) ;
353355
354356 let sig = sig. skip_binder ( ) ;
355- let state_did = self . tcx . require_lang_item ( LangItem :: GeneratorState , None ) ;
356- let state_adt_ref = self . tcx . adt_def ( state_did) ;
357- let state_substs = self . tcx . intern_substs ( & [ sig. yield_ty . into ( ) , sig. return_ty . into ( ) ] ) ;
358- let ret_ty = self . tcx . mk_adt ( state_adt_ref, state_substs) ;
357+ // The `FnSig` and the `ret_ty` here is for a generators main
358+ // `Generator::resume(...) -> GeneratorState` function in case we
359+ // have an ordinary generator, or the `Future::poll(...) -> Poll`
360+ // function in case this is a special generator backing an async construct.
361+ let ret_ty = if self . tcx . generator_is_async ( * did) {
362+ let state_did = self . tcx . require_lang_item ( LangItem :: Poll , None ) ;
363+ let state_adt_ref = self . tcx . adt_def ( state_did) ;
364+ let state_substs = self . tcx . intern_substs ( & [ sig. return_ty . into ( ) ] ) ;
365+ self . tcx . mk_adt ( state_adt_ref, state_substs)
366+ } else {
367+ let state_did = self . tcx . require_lang_item ( LangItem :: GeneratorState , None ) ;
368+ let state_adt_ref = self . tcx . adt_def ( state_did) ;
369+ let state_substs = self . tcx . intern_substs ( & [ sig. yield_ty . into ( ) , sig. return_ty . into ( ) ] ) ;
370+ self . tcx . mk_adt ( state_adt_ref, state_substs)
371+ } ;
359372 ty:: Binder :: bind_with_vars (
360373 self . tcx . mk_fn_sig (
361374 [ env_ty, sig. resume_ty ] . iter ( ) ,
@@ -380,7 +393,7 @@ impl<'tcx> GotocCtx<'tcx> {
380393 }
381394 sig
382395 }
383- ty:: Generator ( _ , substs, _) => self . generator_sig ( fntyp, substs) ,
396+ ty:: Generator ( did , substs, _) => self . generator_sig ( did , fntyp, substs) ,
384397 _ => unreachable ! ( "Can't get function signature of type: {:?}" , fntyp) ,
385398 } )
386399 }
@@ -865,10 +878,10 @@ impl<'tcx> GotocCtx<'tcx> {
865878 fn codegen_alignment_padding (
866879 & self ,
867880 size : Size ,
868- layout : & Layout ,
881+ layout : & LayoutS < VariantIdx > ,
869882 idx : usize ,
870883 ) -> Option < DatatypeComponent > {
871- let align = Size :: from_bits ( layout. align ( ) . abi . bits ( ) ) ;
884+ let align = Size :: from_bits ( layout. align . abi . bits ( ) ) ;
872885 let overhang = Size :: from_bits ( size. bits ( ) % align. bits ( ) ) ;
873886 if overhang != Size :: ZERO {
874887 self . codegen_struct_padding ( size, size + align - overhang, idx)
@@ -890,16 +903,16 @@ impl<'tcx> GotocCtx<'tcx> {
890903 fn codegen_struct_fields (
891904 & mut self ,
892905 flds : Vec < ( String , Ty < ' tcx > ) > ,
893- layout : & Layout ,
906+ layout : & LayoutS < VariantIdx > ,
894907 initial_offset : Size ,
895908 ) -> Vec < DatatypeComponent > {
896- match & layout. fields ( ) {
909+ match & layout. fields {
897910 FieldsShape :: Arbitrary { offsets, memory_index } => {
898911 assert_eq ! ( flds. len( ) , offsets. len( ) ) ;
899912 assert_eq ! ( offsets. len( ) , memory_index. len( ) ) ;
900913 let mut final_fields = Vec :: with_capacity ( flds. len ( ) ) ;
901914 let mut offset = initial_offset;
902- for idx in layout. fields ( ) . index_by_increasing_offset ( ) {
915+ for idx in layout. fields . index_by_increasing_offset ( ) {
903916 let fld_offset = offsets[ idx] ;
904917 let ( fld_name, fld_ty) = & flds[ idx] ;
905918 if let Some ( padding) =
@@ -922,7 +935,7 @@ impl<'tcx> GotocCtx<'tcx> {
922935 }
923936 // Primitives, such as NEVER, have no fields
924937 FieldsShape :: Primitive => vec ! [ ] ,
925- _ => unreachable ! ( "{}\n {:?}" , self . current_fn( ) . readable_name( ) , layout. fields( ) ) ,
938+ _ => unreachable ! ( "{}\n {:?}" , self . current_fn( ) . readable_name( ) , layout. fields) ,
926939 }
927940 }
928941
@@ -931,7 +944,7 @@ impl<'tcx> GotocCtx<'tcx> {
931944 let flds: Vec < _ > =
932945 tys. iter ( ) . enumerate ( ) . map ( |( i, t) | ( GotocCtx :: tuple_fld_name ( i) , * t) ) . collect ( ) ;
933946 // tuple cannot have other initial offset
934- self . codegen_struct_fields ( flds, & layout. layout , Size :: ZERO )
947+ self . codegen_struct_fields ( flds, & layout. layout . 0 , Size :: ZERO )
935948 }
936949
937950 /// A closure / some shims in Rust MIR takes two arguments:
@@ -1136,7 +1149,7 @@ impl<'tcx> GotocCtx<'tcx> {
11361149 }
11371150 fields. extend ( ctx. codegen_alignment_padding (
11381151 offset,
1139- & type_and_layout. layout ,
1152+ & type_and_layout. layout . 0 ,
11401153 fields. len ( ) ,
11411154 ) ) ;
11421155 fields
@@ -1338,7 +1351,7 @@ impl<'tcx> GotocCtx<'tcx> {
13381351 self . ensure_struct ( self . ty_mangled_name ( ty) , self . ty_pretty_name ( ty) , |ctx, _| {
13391352 let variant = & def. variants ( ) . raw [ 0 ] ;
13401353 let layout = ctx. layout_of ( ty) ;
1341- ctx. codegen_variant_struct_fields ( variant, subst, & layout. layout , Size :: ZERO )
1354+ ctx. codegen_variant_struct_fields ( variant, subst, & layout. layout . 0 , Size :: ZERO )
13421355 } )
13431356 }
13441357
@@ -1347,7 +1360,7 @@ impl<'tcx> GotocCtx<'tcx> {
13471360 & mut self ,
13481361 variant : & VariantDef ,
13491362 subst : & ' tcx InternalSubsts < ' tcx > ,
1350- layout : & Layout ,
1363+ layout : & LayoutS < VariantIdx > ,
13511364 initial_offset : Size ,
13521365 ) -> Vec < DatatypeComponent > {
13531366 let flds: Vec < _ > =
@@ -1430,7 +1443,7 @@ impl<'tcx> GotocCtx<'tcx> {
14301443 Some ( variant) => {
14311444 // a single enum is pretty much like a struct
14321445 let layout = gcx. layout_of ( ty) . layout ;
1433- gcx. codegen_variant_struct_fields ( variant, subst, & layout, Size :: ZERO )
1446+ gcx. codegen_variant_struct_fields ( variant, subst, & layout. 0 , Size :: ZERO )
14341447 }
14351448 }
14361449 } )
@@ -1516,9 +1529,9 @@ impl<'tcx> GotocCtx<'tcx> {
15161529 ty : Ty < ' tcx > ,
15171530 adtdef : & ' tcx AdtDef ,
15181531 subst : & ' tcx InternalSubsts < ' tcx > ,
1519- variants : & IndexVec < VariantIdx , Layout > ,
1532+ variants : & IndexVec < VariantIdx , LayoutS < VariantIdx > > ,
15201533 ) -> Type {
1521- let non_zst_count = variants. iter ( ) . filter ( |layout| layout. size ( ) . bytes ( ) > 0 ) . count ( ) ;
1534+ let non_zst_count = variants. iter ( ) . filter ( |layout| layout. size . bytes ( ) > 0 ) . count ( ) ;
15221535 let mangled_name = self . ty_mangled_name ( ty) ;
15231536 let pretty_name = self . ty_pretty_name ( ty) ;
15241537 tracing:: trace!( ?pretty_name, ?variants, ?subst, ?non_zst_count, "codegen_enum: Niche" ) ;
@@ -1535,23 +1548,20 @@ impl<'tcx> GotocCtx<'tcx> {
15351548
15361549 pub ( crate ) fn variant_min_offset (
15371550 & self ,
1538- variants : & IndexVec < VariantIdx , Layout > ,
1551+ variants : & IndexVec < VariantIdx , LayoutS < VariantIdx > > ,
15391552 ) -> Option < Size > {
15401553 variants
15411554 . iter ( )
15421555 . filter_map ( |lo| {
1543- if lo. fields ( ) . count ( ) == 0 {
1556+ if lo. fields . count ( ) == 0 {
15441557 None
15451558 } else {
15461559 // get the offset of the leftmost field, which is the one
15471560 // with the least offset since we codegen fields in a struct
15481561 // in the order of increasing offsets. Note that this is not
15491562 // necessarily the 0th field since the compiler may reorder
15501563 // fields.
1551- Some (
1552- lo. fields ( )
1553- . offset ( lo. fields ( ) . index_by_increasing_offset ( ) . next ( ) . unwrap ( ) ) ,
1554- )
1564+ Some ( lo. fields . offset ( lo. fields . index_by_increasing_offset ( ) . next ( ) . unwrap ( ) ) )
15551565 }
15561566 } )
15571567 . min ( )
@@ -1622,7 +1632,7 @@ impl<'tcx> GotocCtx<'tcx> {
16221632 pretty_name : InternedString ,
16231633 def : & ' tcx AdtDef ,
16241634 subst : & ' tcx InternalSubsts < ' tcx > ,
1625- layouts : & IndexVec < VariantIdx , Layout > ,
1635+ layouts : & IndexVec < VariantIdx , LayoutS < VariantIdx > > ,
16261636 initial_offset : Size ,
16271637 ) -> Vec < DatatypeComponent > {
16281638 def. variants ( )
@@ -1654,7 +1664,7 @@ impl<'tcx> GotocCtx<'tcx> {
16541664 pretty_name : InternedString ,
16551665 case : & VariantDef ,
16561666 subst : & ' tcx InternalSubsts < ' tcx > ,
1657- variant : & Layout ,
1667+ variant : & LayoutS < VariantIdx > ,
16581668 initial_offset : Size ,
16591669 ) -> Type {
16601670 let case_name = format ! ( "{name}::{}" , case. name) ;
0 commit comments