@@ -1551,57 +1551,61 @@ impl CodeGenerator for CompInfo {
1551
1551
//
1552
1552
// Also, we need to generate the vtable in such a way it "inherits" from
1553
1553
// the parent too.
1554
+ let is_opaque = item. is_opaque ( ctx, & ( ) ) ;
1554
1555
let mut fields = vec ! [ ] ;
1555
1556
let mut struct_layout =
1556
1557
StructLayoutTracker :: new ( ctx, self , & canonical_name) ;
1557
- if self . needs_explicit_vtable ( ctx, item) {
1558
- let vtable =
1559
- Vtable :: new ( item. id ( ) , self . methods ( ) , self . base_members ( ) ) ;
1560
- vtable. codegen ( ctx, result, item) ;
1561
1558
1562
- let vtable_type = vtable
1563
- . try_to_rust_ty ( ctx, & ( ) )
1564
- . expect ( "vtable to Rust type conversion is infallible" )
1565
- . to_ptr ( true , ctx. span ( ) ) ;
1559
+ if !is_opaque {
1560
+ if self . needs_explicit_vtable ( ctx, item) {
1561
+ let vtable =
1562
+ Vtable :: new ( item. id ( ) , self . methods ( ) , self . base_members ( ) ) ;
1563
+ vtable. codegen ( ctx, result, item) ;
1566
1564
1567
- let vtable_field = StructFieldBuilder :: named ( "vtable_" )
1568
- . pub_ ( )
1569
- . build_ty ( vtable_type) ;
1565
+ let vtable_type = vtable
1566
+ . try_to_rust_ty ( ctx, & ( ) )
1567
+ . expect ( "vtable to Rust type conversion is infallible" )
1568
+ . to_ptr ( true , ctx. span ( ) ) ;
1570
1569
1571
- struct_layout. saw_vtable ( ) ;
1570
+ let vtable_field = StructFieldBuilder :: named ( "vtable_" )
1571
+ . pub_ ( )
1572
+ . build_ty ( vtable_type) ;
1572
1573
1573
- fields. push ( vtable_field) ;
1574
- }
1574
+ struct_layout. saw_vtable ( ) ;
1575
1575
1576
- for ( i, base) in self . base_members ( ) . iter ( ) . enumerate ( ) {
1577
- // Virtual bases are already taken into account by the vtable
1578
- // pointer.
1579
- //
1580
- // FIXME(emilio): Is this always right?
1581
- if base. is_virtual ( ) {
1582
- continue ;
1576
+ fields. push ( vtable_field) ;
1583
1577
}
1584
1578
1585
- let base_ty = ctx. resolve_type ( base. ty ) ;
1586
- // NB: We won't include unsized types in our base chain because they
1587
- // would contribute to our size given the dummy field we insert for
1588
- // unsized types.
1589
- if base_ty. is_unsized ( ctx, & base. ty ) {
1590
- continue ;
1591
- }
1579
+ for ( i, base) in self . base_members ( ) . iter ( ) . enumerate ( ) {
1580
+ // Virtual bases are already taken into account by the vtable
1581
+ // pointer.
1582
+ //
1583
+ // FIXME(emilio): Is this always right?
1584
+ if base. is_virtual ( ) {
1585
+ continue ;
1586
+ }
1592
1587
1593
- let inner = base. ty . to_rust_ty_or_opaque ( ctx, & ( ) ) ;
1594
- let field_name = if i == 0 {
1595
- "_base" . into ( )
1596
- } else {
1597
- format ! ( "_base_{}" , i)
1598
- } ;
1588
+ let base_ty = ctx. resolve_type ( base. ty ) ;
1589
+ // NB: We won't include unsized types in our base chain because they
1590
+ // would contribute to our size given the dummy field we insert for
1591
+ // unsized types.
1592
+ if base_ty. is_unsized ( ctx, & base. ty ) {
1593
+ continue ;
1594
+ }
1599
1595
1600
- struct_layout. saw_base ( base_ty) ;
1596
+ let inner = base. ty . to_rust_ty_or_opaque ( ctx, & ( ) ) ;
1597
+ let field_name = if i == 0 {
1598
+ "_base" . into ( )
1599
+ } else {
1600
+ format ! ( "_base_{}" , i)
1601
+ } ;
1602
+
1603
+ struct_layout. saw_base ( base_ty) ;
1601
1604
1602
- let field =
1603
- StructFieldBuilder :: named ( field_name) . pub_ ( ) . build_ty ( inner) ;
1604
- fields. extend ( Some ( field) ) ;
1605
+ let field =
1606
+ StructFieldBuilder :: named ( field_name) . pub_ ( ) . build_ty ( inner) ;
1607
+ fields. extend ( Some ( field) ) ;
1608
+ }
1605
1609
}
1606
1610
if is_union {
1607
1611
result. saw_union ( ) ;
@@ -1610,34 +1614,34 @@ impl CodeGenerator for CompInfo {
1610
1614
}
1611
1615
}
1612
1616
1613
- let layout = item. kind ( ) . expect_type ( ) . layout ( ctx) ;
1614
-
1615
- let fields_should_be_private =
1616
- item. annotations ( ) . private_fields ( ) . unwrap_or ( false ) ;
1617
- let struct_accessor_kind = item. annotations ( )
1618
- . accessor_kind ( )
1619
- . unwrap_or ( FieldAccessorKind :: None ) ;
1620
-
1621
1617
let mut methods = vec ! [ ] ;
1622
- let mut anon_field_names = AnonFieldNames :: default ( ) ;
1623
- let codegen_depth = item. codegen_depth ( ctx) ;
1624
- for field in self . fields ( ) {
1625
- field. codegen (
1626
- ctx,
1627
- fields_should_be_private,
1628
- codegen_depth,
1629
- struct_accessor_kind,
1630
- self ,
1631
- & mut anon_field_names,
1632
- result,
1633
- & mut struct_layout,
1634
- & mut fields,
1635
- & mut methods,
1636
- ( ) ,
1637
- ) ;
1618
+ if !is_opaque {
1619
+ let mut anon_field_names = AnonFieldNames :: default ( ) ;
1620
+ let codegen_depth = item. codegen_depth ( ctx) ;
1621
+ let fields_should_be_private =
1622
+ item. annotations ( ) . private_fields ( ) . unwrap_or ( false ) ;
1623
+ let struct_accessor_kind = item. annotations ( )
1624
+ . accessor_kind ( )
1625
+ . unwrap_or ( FieldAccessorKind :: None ) ;
1626
+ for field in self . fields ( ) {
1627
+ field. codegen (
1628
+ ctx,
1629
+ fields_should_be_private,
1630
+ codegen_depth,
1631
+ struct_accessor_kind,
1632
+ self ,
1633
+ & mut anon_field_names,
1634
+ result,
1635
+ & mut struct_layout,
1636
+ & mut fields,
1637
+ & mut methods,
1638
+ ( ) ,
1639
+ ) ;
1640
+ }
1638
1641
}
1639
1642
1640
- if is_union {
1643
+ let layout = item. kind ( ) . expect_type ( ) . layout ( ctx) ;
1644
+ if is_union && !is_opaque {
1641
1645
let layout = layout. expect ( "Unable to get layout information?" ) ;
1642
1646
let ty = helpers:: blob ( layout) ;
1643
1647
@@ -1654,11 +1658,10 @@ impl CodeGenerator for CompInfo {
1654
1658
fields. push ( field) ;
1655
1659
}
1656
1660
1657
- // Yeah, sorry about that.
1658
- let is_opaque = item. is_opaque ( ctx, & ( ) ) ;
1659
1661
if is_opaque {
1660
- fields. clear ( ) ;
1661
- methods. clear ( ) ;
1662
+ // Opaque item should not have generated methods, fields.
1663
+ debug_assert ! ( fields. is_empty( ) ) ;
1664
+ debug_assert ! ( methods. is_empty( ) ) ;
1662
1665
1663
1666
match layout {
1664
1667
Some ( l) => {
0 commit comments