@@ -85,15 +85,7 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> {
85
85
86
86
fn insert ( & mut self , id : ItemId , reason : Reason ) -> ConstrainResult {
87
87
trace ! ( "inserting {:?} into the cannot_derive_partialeq_or_partialord because {:?}" , id, reason) ;
88
-
89
- let _was_not_already_in_set = self . cannot_derive_partialeq_or_partialord . insert ( id, reason) ;
90
- // assert!(
91
- // was_not_already_in_set.is_none(),
92
- // "We shouldn't try and insert {:?} twice because if it was \
93
- // already in the set, `constrain` should have exited early.",
94
- // id
95
- // );
96
-
88
+ self . cannot_derive_partialeq_or_partialord . insert ( id, reason) ;
97
89
ConstrainResult :: Changed
98
90
}
99
91
}
@@ -286,42 +278,34 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
286
278
}
287
279
}
288
280
289
- let bases_cannot_derive =
290
- info. base_members ( ) . iter ( ) . any ( |base| {
291
- !self . ctx . whitelisted_items ( ) . contains ( & base. ty ) ||
292
- self . cannot_derive_partialeq_or_partialord . contains_key ( & base. ty )
293
- } ) ;
294
- if bases_cannot_derive {
281
+ let bases_cannot_derive: Vec < Reason > =
282
+ info. base_members ( ) . iter ( ) . filter_map ( |base| {
283
+ if !self . ctx . whitelisted_items ( ) . contains ( & base. ty ) {
284
+ return Some ( Reason :: Other ) ;
285
+ }
286
+ self . cannot_derive_partialeq_or_partialord . get (
287
+ & base. ty
288
+ ) . cloned ( )
289
+ } ) . collect ( ) ;
290
+ if let Some ( reason) = choose_reason ( & bases_cannot_derive) {
295
291
trace ! (
296
292
" base members cannot derive PartialEq or PartialOrd, so we can't \
297
293
either"
298
294
) ;
299
- let arrays_too_large = info. base_members ( ) . iter ( ) . all ( |base| {
300
- self . cannot_derive_partialeq_or_partialord
301
- . get ( & base. ty )
302
- . map_or ( true , |r| * r == Reason :: ArrayTooLarge )
303
- } ) ;
304
- let reason = if arrays_too_large {
305
- Reason :: ArrayTooLarge
306
- } else {
307
- Reason :: Other
308
- } ;
309
295
return self . insert ( id, reason) ;
310
296
}
311
297
312
- let fields_cannot_derive_reasons = info. fields ( ) . iter ( ) . filter_map ( |f| match * f {
298
+ let fields_cannot_derive_reasons: Vec < Reason > =
299
+ info. fields ( ) . iter ( ) . filter_map ( |f| match * f {
313
300
Field :: DataMember ( ref data) => {
314
301
if !self . ctx . whitelisted_items ( ) . contains (
315
302
& data. ty ( ) ,
316
303
) {
317
- Some ( Reason :: Other )
318
- } else if let Some ( reason) = self . cannot_derive_partialeq_or_partialord . get (
319
- & data. ty ( ) ,
320
- ) {
321
- Some ( * reason)
322
- } else {
323
- None
304
+ return Some ( Reason :: Other ) ;
324
305
}
306
+ self . cannot_derive_partialeq_or_partialord . get (
307
+ & data. ty ( ) ,
308
+ ) . cloned ( )
325
309
}
326
310
Field :: Bitfields ( ref bfu) => {
327
311
if bfu. layout ( ) . align > RUST_DERIVE_IN_ARRAY_LIMIT {
@@ -331,45 +315,23 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
331
315
) ;
332
316
return Some ( Reason :: Other ) ;
333
317
}
334
- let p = bfu. bitfields ( ) . iter ( ) . filter_map ( |b| {
318
+ let p: Vec < Reason > = bfu. bitfields ( ) . iter ( ) . filter_map ( |b| {
335
319
if !self . ctx . whitelisted_items ( ) . contains (
336
320
& b. ty ( ) ,
337
321
) {
338
- Some ( Reason :: Other )
339
- } else if let Some ( reason) = self . cannot_derive_partialeq_or_partialord . get (
340
- & b. ty ( ) ,
341
- ) {
342
- Some ( * reason)
343
- } else {
344
- None
345
- }
346
- } ) . collect :: < Vec < _ > > ( ) ;
347
- if !p. is_empty ( ) {
348
- let all_is_too_large = p
349
- . iter ( )
350
- . all ( |r| * r == Reason :: ArrayTooLarge ) ;
351
- if all_is_too_large {
352
- Some ( Reason :: ArrayTooLarge )
353
- } else {
354
- Some ( Reason :: Other )
322
+ return Some ( Reason :: Other ) ;
355
323
}
356
- } else {
357
- None
358
- }
324
+ self . cannot_derive_partialeq_or_partialord . get (
325
+ & b. ty ( ) ,
326
+ ) . cloned ( )
327
+ } ) . collect ( ) ;
328
+ choose_reason ( & p)
359
329
}
360
- } ) . collect :: < Vec < _ > > ( ) ;
361
- if !fields_cannot_derive_reasons . is_empty ( ) {
330
+ } ) . collect ( ) ;
331
+ if let Some ( reason ) = choose_reason ( & fields_cannot_derive_reasons ) {
362
332
trace ! (
363
333
" fields cannot derive PartialEq or PartialOrd, so we can't either"
364
334
) ;
365
- let all_is_too_large = fields_cannot_derive_reasons
366
- . iter ( )
367
- . all ( |r| * r == Reason :: ArrayTooLarge ) ;
368
- let reason = if all_is_too_large {
369
- Reason :: ArrayTooLarge
370
- } else {
371
- Reason :: Other
372
- } ;
373
335
return self . insert ( id, reason) ;
374
336
}
375
337
@@ -378,28 +340,20 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
378
340
}
379
341
380
342
TypeKind :: TemplateInstantiation ( ref template) => {
381
- let args_cannot_derive_reasons = template
343
+ let args_cannot_derive_reasons: Vec < Reason > = template
382
344
. template_arguments ( )
383
345
. iter ( )
384
346
. filter_map ( |arg| {
385
347
self . cannot_derive_partialeq_or_partialord
386
348
. get ( & arg)
387
349
. cloned ( )
388
350
} )
389
- . collect :: < Vec < _ > > ( ) ;
390
- if !args_cannot_derive_reasons . is_empty ( ) {
351
+ . collect ( ) ;
352
+ if let Some ( reason ) = choose_reason ( & args_cannot_derive_reasons ) {
391
353
trace ! (
392
354
" template args cannot derive PartialEq or PartialOrd, so \
393
355
insantiation can't either"
394
356
) ;
395
- let all_is_too_large = args_cannot_derive_reasons
396
- . iter ( )
397
- . all ( |r| * r == Reason :: ArrayTooLarge ) ;
398
- let reason = if all_is_too_large {
399
- Reason :: ArrayTooLarge
400
- } else {
401
- Reason :: Other
402
- } ;
403
357
return self . insert ( id, reason) ;
404
358
}
405
359
@@ -450,3 +404,19 @@ impl<'ctx> From<CannotDerivePartialEqOrPartialOrd<'ctx>> for HashMap<ItemId, Rea
450
404
analysis. cannot_derive_partialeq_or_partialord
451
405
}
452
406
}
407
+
408
+ /// Chooses the most appropriate Reason from provided list.
409
+ /// Returns None if list is empty.
410
+ fn choose_reason ( reasons : & [ Reason ] ) -> Option < Reason > {
411
+ if reasons. is_empty ( ) {
412
+ return None ;
413
+ }
414
+ let all_is_too_large = reasons
415
+ . iter ( )
416
+ . all ( |r| * r == Reason :: ArrayTooLarge ) ;
417
+ Some ( if all_is_too_large {
418
+ Reason :: ArrayTooLarge
419
+ } else {
420
+ Reason :: Other
421
+ } )
422
+ }
0 commit comments