@@ -95,6 +95,93 @@ fn root_import(
95
95
}
96
96
}
97
97
98
+ bitflags ! {
99
+ struct DerivableTraits : u16 {
100
+ const DEBUG = 1 << 0 ;
101
+ const DEFAULT = 1 << 1 ;
102
+ const COPY = 1 << 2 ;
103
+ const CLONE = 1 << 3 ;
104
+ const HASH = 1 << 4 ;
105
+ const PARTIAL_ORD = 1 << 5 ;
106
+ const ORD = 1 << 6 ;
107
+ const PARTIAL_EQ = 1 << 7 ;
108
+ const EQ = 1 << 8 ;
109
+ }
110
+ }
111
+
112
+ fn derives_of_item ( item : & Item , ctx : & BindgenContext ) -> DerivableTraits {
113
+ let mut derivable_traits = DerivableTraits :: empty ( ) ;
114
+
115
+ if item. can_derive_debug ( ctx) {
116
+ derivable_traits |= DerivableTraits :: DEBUG ;
117
+ }
118
+
119
+ if item. can_derive_default ( ctx) {
120
+ derivable_traits |= DerivableTraits :: DEFAULT ;
121
+ }
122
+
123
+ let all_template_params = item. all_template_params ( ctx) ;
124
+
125
+ if item. can_derive_copy ( ctx) && !item. annotations ( ) . disallow_copy ( ) {
126
+ derivable_traits |= DerivableTraits :: COPY ;
127
+
128
+ if ctx. options ( ) . rust_features ( ) . builtin_clone_impls ||
129
+ !all_template_params. is_empty ( )
130
+ {
131
+ // FIXME: This requires extra logic if you have a big array in a
132
+ // templated struct. The reason for this is that the magic:
133
+ // fn clone(&self) -> Self { *self }
134
+ // doesn't work for templates.
135
+ //
136
+ // It's not hard to fix though.
137
+ derivable_traits |= DerivableTraits :: CLONE ;
138
+ }
139
+ }
140
+
141
+ if item. can_derive_hash ( ctx) {
142
+ derivable_traits |= DerivableTraits :: HASH ;
143
+ }
144
+
145
+ if item. can_derive_partialord ( ctx) {
146
+ derivable_traits |= DerivableTraits :: PARTIAL_ORD ;
147
+ }
148
+
149
+ if item. can_derive_ord ( ctx) {
150
+ derivable_traits |= DerivableTraits :: ORD ;
151
+ }
152
+
153
+ if item. can_derive_partialeq ( ctx) {
154
+ derivable_traits |= DerivableTraits :: PARTIAL_EQ ;
155
+ }
156
+
157
+ if item. can_derive_eq ( ctx) {
158
+ derivable_traits |= DerivableTraits :: EQ ;
159
+ }
160
+
161
+ derivable_traits
162
+ }
163
+
164
+ impl From < DerivableTraits > for Vec < & ' static str > {
165
+ fn from ( derivable_traits : DerivableTraits ) -> Vec < & ' static str > {
166
+ [
167
+ ( DerivableTraits :: DEBUG , "Debug" ) ,
168
+ ( DerivableTraits :: DEFAULT , "Default" ) ,
169
+ ( DerivableTraits :: COPY , "Copy" ) ,
170
+ ( DerivableTraits :: CLONE , "Clone" ) ,
171
+ ( DerivableTraits :: HASH , "Hash" ) ,
172
+ ( DerivableTraits :: PARTIAL_ORD , "PartialOrd" ) ,
173
+ ( DerivableTraits :: ORD , "Ord" ) ,
174
+ ( DerivableTraits :: PARTIAL_EQ , "PartialEq" ) ,
175
+ ( DerivableTraits :: EQ , "Eq" ) ,
176
+ ]
177
+ . iter ( )
178
+ . filter_map ( |& ( flag, derive) | {
179
+ Some ( derive) . filter ( |_| derivable_traits. contains ( flag) )
180
+ } )
181
+ . collect ( )
182
+ }
183
+ }
184
+
98
185
struct CodegenResult < ' a > {
99
186
items : Vec < proc_macro2:: TokenStream > ,
100
187
@@ -793,8 +880,17 @@ impl CodeGenerator for Type {
793
880
"repr_transparent feature is required to use {:?}" ,
794
881
alias_style
795
882
) ;
883
+
884
+ let mut attributes =
885
+ vec ! [ attributes:: repr( "transparent" ) ] ;
886
+ let derivable_traits = derives_of_item ( item, ctx) ;
887
+ if !derivable_traits. is_empty ( ) {
888
+ let derives: Vec < _ > = derivable_traits. into ( ) ;
889
+ attributes. push ( attributes:: derives ( & derives) )
890
+ }
891
+
796
892
quote ! {
797
- #[ repr ( transparent ) ]
893
+ #( #attributes ) *
798
894
pub struct #rust_name
799
895
}
800
896
}
@@ -1787,66 +1883,33 @@ impl CodeGenerator for CompInfo {
1787
1883
}
1788
1884
}
1789
1885
1790
- let mut derives = vec ! [ ] ;
1791
- if item. can_derive_debug ( ctx) {
1792
- derives. push ( "Debug" ) ;
1793
- } else {
1886
+ let derivable_traits = derives_of_item ( item, ctx) ;
1887
+ if !derivable_traits. contains ( DerivableTraits :: DEBUG ) {
1794
1888
needs_debug_impl =
1795
1889
ctx. options ( ) . derive_debug && ctx. options ( ) . impl_debug
1796
1890
}
1797
1891
1798
- if item. can_derive_default ( ctx) {
1799
- derives. push ( "Default" ) ;
1800
- } else {
1892
+ if !derivable_traits. contains ( DerivableTraits :: DEFAULT ) {
1801
1893
needs_default_impl =
1802
1894
ctx. options ( ) . derive_default && !self . is_forward_declaration ( ) ;
1803
1895
}
1804
1896
1805
1897
let all_template_params = item. all_template_params ( ctx) ;
1806
1898
1807
- if item. can_derive_copy ( ctx) && !item. annotations ( ) . disallow_copy ( ) {
1808
- derives. push ( "Copy" ) ;
1809
-
1810
- if ctx. options ( ) . rust_features ( ) . builtin_clone_impls ||
1811
- !all_template_params. is_empty ( )
1812
- {
1813
- // FIXME: This requires extra logic if you have a big array in a
1814
- // templated struct. The reason for this is that the magic:
1815
- // fn clone(&self) -> Self { *self }
1816
- // doesn't work for templates.
1817
- //
1818
- // It's not hard to fix though.
1819
- derives. push ( "Clone" ) ;
1820
- } else {
1821
- needs_clone_impl = true ;
1822
- }
1823
- }
1824
-
1825
- if item. can_derive_hash ( ctx) {
1826
- derives. push ( "Hash" ) ;
1827
- }
1828
-
1829
- if item. can_derive_partialord ( ctx) {
1830
- derives. push ( "PartialOrd" ) ;
1831
- }
1832
-
1833
- if item. can_derive_ord ( ctx) {
1834
- derives. push ( "Ord" ) ;
1899
+ if derivable_traits. contains ( DerivableTraits :: COPY ) &&
1900
+ !derivable_traits. contains ( DerivableTraits :: CLONE )
1901
+ {
1902
+ needs_clone_impl = true ;
1835
1903
}
1836
1904
1837
- if item. can_derive_partialeq ( ctx) {
1838
- derives. push ( "PartialEq" ) ;
1839
- } else {
1905
+ if !derivable_traits. contains ( DerivableTraits :: PARTIAL_EQ ) {
1840
1906
needs_partialeq_impl = ctx. options ( ) . derive_partialeq &&
1841
1907
ctx. options ( ) . impl_partialeq &&
1842
1908
ctx. lookup_can_derive_partialeq_or_partialord ( item. id ( ) ) ==
1843
1909
CanDerive :: Manually ;
1844
1910
}
1845
1911
1846
- if item. can_derive_eq ( ctx) {
1847
- derives. push ( "Eq" ) ;
1848
- }
1849
-
1912
+ let mut derives: Vec < _ > = derivable_traits. into ( ) ;
1850
1913
derives. extend ( item. annotations ( ) . derives ( ) . iter ( ) . map ( String :: as_str) ) ;
1851
1914
1852
1915
if !derives. is_empty ( ) {
0 commit comments