@@ -2252,6 +2252,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2252
2252
& self ,
2253
2253
err : & mut Diagnostic ,
2254
2254
errors : Vec < FulfillmentError < ' tcx > > ,
2255
+ suggest_derive : bool ,
2255
2256
) {
2256
2257
let all_local_types_needing_impls =
2257
2258
errors. iter ( ) . all ( |e| match e. obligation . predicate . kind ( ) . skip_binder ( ) {
@@ -2322,18 +2323,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2322
2323
. iter ( )
2323
2324
. map ( |e| ( e. obligation . predicate , None , Some ( e. obligation . cause . clone ( ) ) ) )
2324
2325
. collect ( ) ;
2325
- self . suggest_derive ( err, & preds) ;
2326
+ if suggest_derive {
2327
+ self . suggest_derive ( err, & preds) ;
2328
+ } else {
2329
+ // The predicate comes from a binop where the lhs and rhs have different types.
2330
+ let _ = self . note_predicate_source_and_get_derives ( err, & preds) ;
2331
+ }
2326
2332
}
2327
2333
2328
- pub fn suggest_derive (
2334
+ fn note_predicate_source_and_get_derives (
2329
2335
& self ,
2330
2336
err : & mut Diagnostic ,
2331
2337
unsatisfied_predicates : & [ (
2332
2338
ty:: Predicate < ' tcx > ,
2333
2339
Option < ty:: Predicate < ' tcx > > ,
2334
2340
Option < ObligationCause < ' tcx > > ,
2335
2341
) ] ,
2336
- ) {
2342
+ ) -> Vec < ( String , Span , Symbol ) > {
2337
2343
let mut derives = Vec :: < ( String , Span , Symbol ) > :: new ( ) ;
2338
2344
let mut traits = Vec :: new ( ) ;
2339
2345
for ( pred, _, _) in unsatisfied_predicates {
@@ -2382,21 +2388,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2382
2388
traits. sort ( ) ;
2383
2389
traits. dedup ( ) ;
2384
2390
2385
- derives. sort ( ) ;
2386
- derives. dedup ( ) ;
2387
-
2388
- let mut derives_grouped = Vec :: < ( String , Span , String ) > :: new ( ) ;
2389
- for ( self_name, self_span, trait_name) in derives. into_iter ( ) {
2390
- if let Some ( ( last_self_name, _, ref mut last_trait_names) ) = derives_grouped. last_mut ( )
2391
- {
2392
- if last_self_name == & self_name {
2393
- last_trait_names. push_str ( format ! ( ", {trait_name}" ) . as_str ( ) ) ;
2394
- continue ;
2395
- }
2396
- }
2397
- derives_grouped. push ( ( self_name, self_span, trait_name. to_string ( ) ) ) ;
2398
- }
2399
-
2400
2391
let len = traits. len ( ) ;
2401
2392
if len > 0 {
2402
2393
let span =
@@ -2419,6 +2410,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2419
2410
) ;
2420
2411
}
2421
2412
2413
+ derives
2414
+ }
2415
+
2416
+ pub ( crate ) fn suggest_derive (
2417
+ & self ,
2418
+ err : & mut Diagnostic ,
2419
+ unsatisfied_predicates : & [ (
2420
+ ty:: Predicate < ' tcx > ,
2421
+ Option < ty:: Predicate < ' tcx > > ,
2422
+ Option < ObligationCause < ' tcx > > ,
2423
+ ) ] ,
2424
+ ) {
2425
+ let mut derives = self . note_predicate_source_and_get_derives ( err, unsatisfied_predicates) ;
2426
+ derives. sort ( ) ;
2427
+ derives. dedup ( ) ;
2428
+
2429
+ let mut derives_grouped = Vec :: < ( String , Span , String ) > :: new ( ) ;
2430
+ for ( self_name, self_span, trait_name) in derives. into_iter ( ) {
2431
+ if let Some ( ( last_self_name, _, ref mut last_trait_names) ) = derives_grouped. last_mut ( )
2432
+ {
2433
+ if last_self_name == & self_name {
2434
+ last_trait_names. push_str ( format ! ( ", {trait_name}" ) . as_str ( ) ) ;
2435
+ continue ;
2436
+ }
2437
+ }
2438
+ derives_grouped. push ( ( self_name, self_span, trait_name. to_string ( ) ) ) ;
2439
+ }
2440
+
2422
2441
for ( self_name, self_span, traits) in & derives_grouped {
2423
2442
err. span_suggestion_verbose (
2424
2443
self_span. shrink_to_lo ( ) ,
0 commit comments