@@ -604,12 +604,57 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
604
604
tcx. intern_layout ( unit)
605
605
}
606
606
607
- // Tuples, generators and closures.
608
607
ty:: Generator ( def_id, ref substs, _) => {
609
- let tys = substs. field_tys ( def_id, tcx) ;
610
- univariant ( & tys. map ( |ty| self . layout_of ( ty) ) . collect :: < Result < Vec < _ > , _ > > ( ) ?,
608
+ let discr_index = substs. prefix_tys ( def_id, tcx) . count ( ) ;
609
+ let prefix_tys = substs. prefix_tys ( def_id, tcx)
610
+ . chain ( iter:: once ( substs. discr_ty ( tcx) ) ) ;
611
+ let prefix = univariant_uninterned (
612
+ & prefix_tys. map ( |ty| self . layout_of ( ty) ) . collect :: < Result < Vec < _ > , _ > > ( ) ?,
611
613
& ReprOptions :: default ( ) ,
612
- StructKind :: AlwaysSized ) ?
614
+ StructKind :: AlwaysSized ) ?;
615
+
616
+ let mut size = prefix. size ;
617
+ let mut align = prefix. align ;
618
+ let variants_tys = substs. state_tys ( def_id, tcx) ;
619
+ let variants = variants_tys. enumerate ( ) . map ( |( i, variant_tys) | {
620
+ let mut variant = univariant_uninterned (
621
+ & variant_tys. map ( |ty| self . layout_of ( ty) ) . collect :: < Result < Vec < _ > , _ > > ( ) ?,
622
+ & ReprOptions :: default ( ) ,
623
+ StructKind :: Prefixed ( prefix. size , prefix. align . abi ) ) ?;
624
+
625
+ variant. variants = Variants :: Single { index : VariantIdx :: new ( i) } ;
626
+
627
+ size = size. max ( variant. size ) ;
628
+ align = align. max ( variant. align ) ;
629
+
630
+ Ok ( variant)
631
+ } ) . collect :: < Result < IndexVec < VariantIdx , _ > , _ > > ( ) ?;
632
+
633
+ let abi = if prefix. abi . is_uninhabited ( ) ||
634
+ variants. iter ( ) . all ( |v| v. abi . is_uninhabited ( ) ) {
635
+ Abi :: Uninhabited
636
+ } else {
637
+ Abi :: Aggregate { sized : true }
638
+ } ;
639
+ let discr = match & self . layout_of ( substs. discr_ty ( tcx) ) ?. abi {
640
+ Abi :: Scalar ( s) => s. clone ( ) ,
641
+ _ => bug ! ( ) ,
642
+ } ;
643
+
644
+ let layout = tcx. intern_layout ( LayoutDetails {
645
+ variants : Variants :: Multiple {
646
+ discr,
647
+ discr_kind : DiscriminantKind :: Tag ,
648
+ discr_index,
649
+ variants,
650
+ } ,
651
+ fields : prefix. fields ,
652
+ abi,
653
+ size,
654
+ align,
655
+ } ) ;
656
+ debug ! ( "generator layout: {:#?}" , layout) ;
657
+ layout
613
658
}
614
659
615
660
ty:: Closure ( def_id, ref substs) => {
@@ -1646,6 +1691,14 @@ impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx>
1646
1691
1647
1692
fn field ( this : TyLayout < ' tcx > , cx : & C , i : usize ) -> C :: TyLayout {
1648
1693
let tcx = cx. tcx ( ) ;
1694
+ let handle_discriminant = |discr : & Scalar | -> C :: TyLayout {
1695
+ let layout = LayoutDetails :: scalar ( cx, discr. clone ( ) ) ;
1696
+ MaybeResult :: from_ok ( TyLayout {
1697
+ details : tcx. intern_layout ( layout) ,
1698
+ ty : discr. value . to_ty ( tcx)
1699
+ } )
1700
+ } ;
1701
+
1649
1702
cx. layout_of ( match this. ty . sty {
1650
1703
ty:: Bool |
1651
1704
ty:: Char |
@@ -1720,7 +1773,19 @@ impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx>
1720
1773
}
1721
1774
1722
1775
ty:: Generator ( def_id, ref substs, _) => {
1723
- substs. field_tys ( def_id, tcx) . nth ( i) . unwrap ( )
1776
+ match this. variants {
1777
+ Variants :: Single { index } => {
1778
+ substs. state_tys ( def_id, tcx)
1779
+ . nth ( index. as_usize ( ) ) . unwrap ( )
1780
+ . nth ( i) . unwrap ( )
1781
+ }
1782
+ Variants :: Multiple { ref discr, discr_index, .. } => {
1783
+ if i == discr_index {
1784
+ return handle_discriminant ( discr) ;
1785
+ }
1786
+ substs. prefix_tys ( def_id, tcx) . nth ( i) . unwrap ( )
1787
+ }
1788
+ }
1724
1789
}
1725
1790
1726
1791
ty:: Tuple ( tys) => tys[ i] ,
@@ -1740,11 +1805,7 @@ impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx>
1740
1805
// Discriminant field for enums (where applicable).
1741
1806
Variants :: Multiple { ref discr, .. } => {
1742
1807
assert_eq ! ( i, 0 ) ;
1743
- let layout = LayoutDetails :: scalar ( cx, discr. clone ( ) ) ;
1744
- return MaybeResult :: from_ok ( TyLayout {
1745
- details : tcx. intern_layout ( layout) ,
1746
- ty : discr. value . to_ty ( tcx)
1747
- } ) ;
1808
+ return handle_discriminant ( discr) ;
1748
1809
}
1749
1810
}
1750
1811
}
0 commit comments