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