@@ -140,10 +140,10 @@ impl<'ctx> CannotDerive<'ctx> {
140
140
fn constrain_type ( & mut self , item : & Item , ty : & Type ) -> CanDerive {
141
141
if !self . ctx . whitelisted_items ( ) . contains ( & item. id ( ) ) {
142
142
trace ! (
143
- " cannot derive {} for blacklisted type" ,
143
+ " cannot derive {} for blacklisted type, but it can be implemented " ,
144
144
self . derive_trait
145
145
) ;
146
- return CanDerive :: No ;
146
+ return CanDerive :: Manually ;
147
147
}
148
148
149
149
if self . derive_trait . not_by_name ( self . ctx , & item) {
@@ -156,15 +156,18 @@ impl<'ctx> CannotDerive<'ctx> {
156
156
157
157
trace ! ( "ty: {:?}" , ty) ;
158
158
if item. is_opaque ( self . ctx , & ( ) ) {
159
- if !self . derive_trait . can_derive_union ( ) &&
160
- ty. is_union ( ) &&
159
+ if ty. is_union ( ) &&
161
160
self . ctx . options ( ) . rust_features ( ) . untagged_union
162
161
{
163
- trace ! (
164
- " cannot derive {} for Rust unions" ,
165
- self . derive_trait
166
- ) ;
167
- return CanDerive :: No ;
162
+ let can_derive = self . derive_trait . can_derive_union ( ) ;
163
+ if can_derive != CanDerive :: Yes {
164
+ trace ! (
165
+ " cannot derive {} for Rust unions ({:?})" ,
166
+ self . derive_trait,
167
+ can_derive,
168
+ ) ;
169
+ return can_derive;
170
+ }
168
171
}
169
172
170
173
let layout_can_derive =
@@ -179,7 +182,13 @@ impl<'ctx> CannotDerive<'ctx> {
179
182
self . derive_trait
180
183
) ;
181
184
}
182
- _ => {
185
+ CanDerive :: Manually => {
186
+ trace ! (
187
+ " we cannot derive {} for the layout, but it can be implemented" ,
188
+ self . derive_trait
189
+ ) ;
190
+ }
191
+ CanDerive :: No => {
183
192
trace ! (
184
193
" we cannot derive {} for the layout" ,
185
194
self . derive_trait
@@ -226,11 +235,12 @@ impl<'ctx> CannotDerive<'ctx> {
226
235
if inner_type != CanDerive :: Yes {
227
236
trace ! (
228
237
" arrays of T for which we cannot derive {} \
229
- also cannot derive {}",
238
+ also cannot derive {}, ({:?}) ",
230
239
self . derive_trait,
231
- self . derive_trait
240
+ self . derive_trait,
241
+ inner_type
232
242
) ;
233
- return CanDerive :: No ;
243
+ return inner_type ;
234
244
}
235
245
236
246
if len == 0 && !self . derive_trait . can_derive_incomplete_array ( )
@@ -308,62 +318,74 @@ impl<'ctx> CannotDerive<'ctx> {
308
318
}
309
319
310
320
if info. kind ( ) == CompKind :: Union {
311
- if self . derive_trait . can_derive_union ( ) {
312
- if self . ctx . options ( ) . rust_features ( ) . untagged_union &&
313
- // https://github.com/rust-lang/rust/issues/36640
314
- ( !info. self_template_params ( self . ctx ) . is_empty ( ) ||
315
- !item. all_template_params ( self . ctx ) . is_empty ( ) )
316
- {
317
- trace ! (
318
- " cannot derive {} for Rust union because issue 36640" , self . derive_trait
319
- ) ;
320
- return CanDerive :: No ;
321
- }
322
- // fall through to be same as non-union handling
323
- } else {
324
- if self . ctx . options ( ) . rust_features ( ) . untagged_union {
325
- trace ! (
326
- " cannot derive {} for Rust unions" ,
327
- self . derive_trait
328
- ) ;
329
- return CanDerive :: No ;
330
- }
331
-
332
- let layout_can_derive =
333
- ty. layout ( self . ctx ) . map_or ( CanDerive :: Yes , |l| {
334
- l. opaque ( )
335
- . array_size_within_derive_limit ( self . ctx )
336
- } ) ;
337
- match layout_can_derive {
338
- CanDerive :: Yes => {
321
+ match self . derive_trait . can_derive_union ( ) {
322
+ CanDerive :: Yes => {
323
+ if self . ctx . options ( ) . rust_features ( ) . untagged_union &&
324
+ // https://github.com/rust-lang/rust/issues/36640
325
+ ( !info. self_template_params ( self . ctx ) . is_empty ( ) ||
326
+ !item. all_template_params ( self . ctx ) . is_empty ( ) )
327
+ {
339
328
trace ! (
340
- " union layout can trivially derive {}" ,
341
- self . derive_trait
329
+ " cannot derive {} for Rust union because issue 36640" , self . derive_trait
342
330
) ;
331
+ return CanDerive :: No ;
343
332
}
344
- _ => {
333
+ // fall through to be same as non-union handling
334
+ }
335
+ trait_can_derive => {
336
+ if self . ctx . options ( ) . rust_features ( ) . untagged_union
337
+ {
345
338
trace ! (
346
- " union layout cannot derive {}" ,
347
- self . derive_trait
348
- ) ;
339
+ " cannot derive {} for Rust unions ({:?})" ,
340
+ self . derive_trait,
341
+ trait_can_derive,
342
+ ) ;
343
+ return trait_can_derive;
349
344
}
350
- } ;
351
- return layout_can_derive;
345
+
346
+ let layout_can_derive = ty. layout ( self . ctx ) . map_or (
347
+ CanDerive :: Yes ,
348
+ |l| {
349
+ l. opaque ( ) . array_size_within_derive_limit (
350
+ self . ctx ,
351
+ )
352
+ } ,
353
+ ) ;
354
+ match layout_can_derive {
355
+ CanDerive :: Yes => {
356
+ trace ! (
357
+ " union layout can trivially derive {}" ,
358
+ self . derive_trait
359
+ ) ;
360
+ }
361
+ _ => {
362
+ trace ! (
363
+ " union layout cannot derive {}, ({:?})" ,
364
+ self . derive_trait,
365
+ layout_can_derive,
366
+ ) ;
367
+ }
368
+ } ;
369
+ return layout_can_derive;
370
+ }
352
371
}
353
372
}
354
373
355
- if !self . derive_trait . can_derive_compound_with_vtable ( ) &&
356
- item. has_vtable ( self . ctx )
357
- {
358
- trace ! (
359
- " cannot derive {} for comp with vtable" ,
360
- self . derive_trait
361
- ) ;
362
- return CanDerive :: No ;
374
+ if item. has_vtable ( self . ctx ) {
375
+ let can_derive =
376
+ self . derive_trait . can_derive_compound_with_vtable ( ) ;
377
+ if can_derive != CanDerive :: Yes {
378
+ trace ! (
379
+ " cannot derive {} for comp with vtable ({:?})" ,
380
+ self . derive_trait,
381
+ can_derive,
382
+ ) ;
383
+ return can_derive;
384
+ }
363
385
}
364
386
365
387
let pred = self . derive_trait . consider_edge_comp ( ) ;
366
- return self . constrain_join ( item, pred) ;
388
+ self . constrain_join ( item, pred)
367
389
}
368
390
369
391
TypeKind :: ResolvedTypeRef ( ..) |
@@ -476,10 +498,11 @@ impl DeriveTrait {
476
498
}
477
499
}
478
500
479
- fn can_derive_union ( & self ) -> bool {
501
+ fn can_derive_union ( & self ) -> CanDerive {
480
502
match self {
481
- DeriveTrait :: Copy => true ,
482
- _ => false ,
503
+ DeriveTrait :: Copy => CanDerive :: Yes ,
504
+ DeriveTrait :: Default => CanDerive :: Manually ,
505
+ _ => CanDerive :: No ,
483
506
}
484
507
}
485
508
@@ -490,10 +513,10 @@ impl DeriveTrait {
490
513
}
491
514
}
492
515
493
- fn can_derive_compound_with_vtable ( & self ) -> bool {
516
+ fn can_derive_compound_with_vtable ( & self ) -> CanDerive {
494
517
match self {
495
- DeriveTrait :: Default => false ,
496
- _ => true ,
518
+ DeriveTrait :: Default => CanDerive :: Manually ,
519
+ _ => CanDerive :: Yes ,
497
520
}
498
521
}
499
522
@@ -549,8 +572,8 @@ impl DeriveTrait {
549
572
fn can_derive_pointer ( & self ) -> CanDerive {
550
573
match self {
551
574
DeriveTrait :: Default => {
552
- trace ! ( " pointer cannot derive Default" ) ;
553
- CanDerive :: No
575
+ trace ! ( " pointer cannot derive Default, but it may be implemented " ) ;
576
+ CanDerive :: Manually
554
577
}
555
578
_ => {
556
579
trace ! ( " pointer can derive {}" , self ) ;
@@ -570,8 +593,8 @@ impl DeriveTrait {
570
593
( DeriveTrait :: Default , TypeKind :: ObjCInterface ( ..) ) |
571
594
( DeriveTrait :: Default , TypeKind :: ObjCId ) |
572
595
( DeriveTrait :: Default , TypeKind :: ObjCSel ) => {
573
- trace ! ( " types that always cannot derive Default" ) ;
574
- CanDerive :: No
596
+ trace ! ( " types that always cannot derive Default, but may implement it manually " ) ;
597
+ CanDerive :: Manually
575
598
}
576
599
( DeriveTrait :: Default , TypeKind :: UnresolvedTypeRef ( ..) ) => {
577
600
unreachable ! (
0 commit comments