1
1
mod impl_debug;
2
+ mod impl_partialeq;
2
3
mod error;
3
4
mod helpers;
4
5
pub mod struct_layout;
@@ -13,7 +14,7 @@ use ir::comp::{Base, Bitfield, BitfieldUnit, CompInfo, CompKind, Field,
13
14
use ir:: context:: { BindgenContext , ItemId } ;
14
15
use ir:: derive:: { CanDeriveCopy , CanDeriveDebug , CanDeriveDefault ,
15
16
CanDeriveHash , CanDerivePartialOrd , CanDeriveOrd ,
16
- CanDerivePartialEq , CanDeriveEq } ;
17
+ CanDerivePartialEq , CanDeriveEq , CannotDeriveReason } ;
17
18
use ir:: dot;
18
19
use ir:: enum_ty:: { Enum , EnumVariant , EnumVariantValue } ;
19
20
use ir:: function:: { Abi , Function , FunctionSig } ;
@@ -1419,6 +1420,7 @@ impl CodeGenerator for CompInfo {
1419
1420
let mut needs_clone_impl = false ;
1420
1421
let mut needs_default_impl = false ;
1421
1422
let mut needs_debug_impl = false ;
1423
+ let mut needs_partialeq_impl = false ;
1422
1424
if let Some ( comment) = item. comment ( ctx) {
1423
1425
attributes. push ( attributes:: doc ( comment) ) ;
1424
1426
}
@@ -1474,6 +1476,14 @@ impl CodeGenerator for CompInfo {
1474
1476
1475
1477
if item. can_derive_partialeq ( ctx) {
1476
1478
derives. push ( "PartialEq" ) ;
1479
+ } else {
1480
+ needs_partialeq_impl =
1481
+ ctx. options ( ) . derive_partialeq &&
1482
+ ctx. options ( ) . impl_partialeq &&
1483
+ ctx. lookup_item_id_can_derive_partialeq_or_partialord ( item. id ( ) )
1484
+ . map_or ( true , |x| {
1485
+ x == CannotDeriveReason :: ArrayTooLarge
1486
+ } ) ;
1477
1487
}
1478
1488
1479
1489
if item. can_derive_eq ( ctx) {
@@ -1534,25 +1544,14 @@ impl CodeGenerator for CompInfo {
1534
1544
}
1535
1545
1536
1546
for base in self . base_members ( ) {
1537
- // Virtual bases are already taken into account by the vtable
1538
- // pointer.
1539
- //
1540
- // FIXME(emilio): Is this always right?
1541
- if base. is_virtual ( ) {
1542
- continue ;
1543
- }
1544
-
1545
- let base_ty = ctx. resolve_type ( base. ty ) ;
1546
- // NB: We won't include unsized types in our base chain because they
1547
- // would contribute to our size given the dummy field we insert for
1548
- // unsized types.
1549
- if base_ty. is_unsized ( ctx, & base. ty ) {
1547
+ if !base. requires_storage ( ctx) {
1550
1548
continue ;
1551
1549
}
1552
1550
1553
1551
let inner = base. ty . to_rust_ty_or_opaque ( ctx, & ( ) ) ;
1554
1552
let field_name = ctx. rust_ident ( & base. field_name ) ;
1555
1553
1554
+ let base_ty = ctx. resolve_type ( base. ty ) ;
1556
1555
struct_layout. saw_base ( base_ty) ;
1557
1556
1558
1557
fields. push ( quote ! {
@@ -1666,33 +1665,34 @@ impl CodeGenerator for CompInfo {
1666
1665
}
1667
1666
}
1668
1667
1669
- let mut generics = quote ! { } ;
1668
+ let mut generic_param_names = vec ! [ ] ;
1670
1669
1671
1670
if let Some ( ref params) = used_template_params {
1672
- if !params. is_empty ( ) {
1673
- let mut param_names = vec ! [ ] ;
1671
+ for ( idx, ty) in params. iter ( ) . enumerate ( ) {
1672
+ let param = ctx. resolve_type ( * ty) ;
1673
+ let name = param. name ( ) . unwrap ( ) ;
1674
+ let ident = ctx. rust_ident ( name) ;
1675
+ generic_param_names. push ( ident. clone ( ) ) ;
1674
1676
1675
- for ( idx, ty) in params. iter ( ) . enumerate ( ) {
1676
- let param = ctx. resolve_type ( * ty) ;
1677
- let name = param. name ( ) . unwrap ( ) ;
1678
- let ident = ctx. rust_ident ( name) ;
1679
- param_names. push ( ident. clone ( ) ) ;
1680
-
1681
- let prefix = ctx. trait_prefix ( ) ;
1682
- let field_name = ctx. rust_ident ( format ! ( "_phantom_{}" , idx) ) ;
1683
- fields. push ( quote ! {
1684
- pub #field_name : :: #prefix:: marker:: PhantomData <
1685
- :: #prefix:: cell:: UnsafeCell <#ident>
1686
- > ,
1687
- } ) ;
1688
- }
1689
-
1690
- generics = quote ! {
1691
- < #( #param_names ) , * >
1692
- } ;
1677
+ let prefix = ctx. trait_prefix ( ) ;
1678
+ let field_name = ctx. rust_ident ( format ! ( "_phantom_{}" , idx) ) ;
1679
+ fields. push ( quote ! {
1680
+ pub #field_name : :: #prefix:: marker:: PhantomData <
1681
+ :: #prefix:: cell:: UnsafeCell <#ident>
1682
+ > ,
1683
+ } ) ;
1693
1684
}
1694
1685
}
1695
1686
1687
+ let generics = if !generic_param_names. is_empty ( ) {
1688
+ let generic_param_names = generic_param_names. clone ( ) ;
1689
+ quote ! {
1690
+ < #( #generic_param_names ) , * >
1691
+ }
1692
+ } else {
1693
+ quote ! { }
1694
+ } ;
1695
+
1696
1696
tokens. append ( quote ! {
1697
1697
#generics {
1698
1698
#( #fields ) *
@@ -1896,6 +1896,27 @@ impl CodeGenerator for CompInfo {
1896
1896
} ) ;
1897
1897
}
1898
1898
1899
+ if needs_partialeq_impl {
1900
+ if let Some ( impl_) = impl_partialeq:: gen_partialeq_impl ( ctx, self , item, & ty_for_impl) {
1901
+
1902
+ let partialeq_bounds = if !generic_param_names. is_empty ( ) {
1903
+ let bounds = generic_param_names. iter ( ) . map ( |t| {
1904
+ quote ! { #t: PartialEq }
1905
+ } ) ;
1906
+ quote ! { where #( #bounds ) , * }
1907
+ } else {
1908
+ quote ! { }
1909
+ } ;
1910
+
1911
+ let prefix = ctx. trait_prefix ( ) ;
1912
+ result. push ( quote ! {
1913
+ impl #generics :: #prefix:: cmp:: PartialEq for #ty_for_impl #partialeq_bounds {
1914
+ #impl_
1915
+ }
1916
+ } ) ;
1917
+ }
1918
+ }
1919
+
1899
1920
if !methods. is_empty ( ) {
1900
1921
result. push ( quote ! {
1901
1922
impl #generics #ty_for_impl {
0 commit comments