@@ -254,8 +254,15 @@ pub trait TypeErrCtxtExt<'tcx> {
254254        found_span :  Option < Span > , 
255255        found :  ty:: PolyTraitRef < ' tcx > , 
256256        expected :  ty:: PolyTraitRef < ' tcx > , 
257+         cause :  & ObligationCauseCode < ' tcx > , 
257258    )  -> DiagnosticBuilder < ' tcx ,  ErrorGuaranteed > ; 
258259
260+     fn  note_conflicting_closure_bounds ( 
261+         & self , 
262+         cause :  & ObligationCauseCode < ' tcx > , 
263+         err :  & mut  DiagnosticBuilder < ' tcx ,  ErrorGuaranteed > , 
264+     ) ; 
265+ 
259266    fn  suggest_fully_qualified_path ( 
260267        & self , 
261268        err :  & mut  Diagnostic , 
@@ -1584,6 +1591,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
15841591        found_span :  Option < Span > , 
15851592        found :  ty:: PolyTraitRef < ' tcx > , 
15861593        expected :  ty:: PolyTraitRef < ' tcx > , 
1594+         cause :  & ObligationCauseCode < ' tcx > , 
15871595    )  -> DiagnosticBuilder < ' tcx ,  ErrorGuaranteed >  { 
15881596        pub ( crate )  fn  build_fn_sig_ty < ' tcx > ( 
15891597            infcx :  & InferCtxt < ' tcx > , 
@@ -1645,9 +1653,68 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
16451653        let  signature_kind = format ! ( "{argument_kind} signature" ) ; 
16461654        err. note_expected_found ( & signature_kind,  expected_str,  & signature_kind,  found_str) ; 
16471655
1656+         self . note_conflicting_closure_bounds ( cause,  & mut  err) ; 
1657+ 
16481658        err
16491659    } 
16501660
1661+     // Add a note if there are two `Fn`-family bounds that have conflicting argument 
1662+     // requirements, which will always cause a closure to have a type error. 
1663+     fn  note_conflicting_closure_bounds ( 
1664+         & self , 
1665+         cause :  & ObligationCauseCode < ' tcx > , 
1666+         err :  & mut  DiagnosticBuilder < ' tcx ,  ErrorGuaranteed > , 
1667+     )  { 
1668+         // First, look for an `ExprBindingObligation`, which means we can get 
1669+         // the unsubstituted predicate list of the called function. And check 
1670+         // that the predicate that we failed to satisfy is a `Fn`-like trait. 
1671+         if  let  ObligationCauseCode :: ExprBindingObligation ( def_id,  _,  _,  idx)  = cause
1672+             && let  predicates = self . tcx . predicates_of ( def_id) . instantiate_identity ( self . tcx ) 
1673+             && let  Some ( pred)  = predicates. predicates . get ( * idx) 
1674+             && let  ty:: PredicateKind :: Trait ( trait_pred)  = pred. kind ( ) . skip_binder ( ) 
1675+             && ty:: ClosureKind :: from_def_id ( self . tcx ,  trait_pred. def_id ( ) ) . is_some ( ) 
1676+         { 
1677+             let  expected_self =
1678+                 self . tcx . anonymize_late_bound_regions ( pred. kind ( ) . rebind ( trait_pred. self_ty ( ) ) ) ; 
1679+             let  expected_substs = self 
1680+                 . tcx 
1681+                 . anonymize_late_bound_regions ( pred. kind ( ) . rebind ( trait_pred. trait_ref . substs ) ) ; 
1682+ 
1683+             // Find another predicate whose self-type is equal to the expected self type, 
1684+             // but whose substs don't match. 
1685+             let  other_pred = std:: iter:: zip ( & predicates. predicates ,  & predicates. spans ) 
1686+                 . enumerate ( ) 
1687+                 . find ( |( other_idx,  ( pred,  _) ) | match  pred. kind ( ) . skip_binder ( )  { 
1688+                     ty:: PredicateKind :: Trait ( trait_pred) 
1689+                         if  ty:: ClosureKind :: from_def_id ( self . tcx ,  trait_pred. def_id ( ) ) 
1690+                             . is_some ( ) 
1691+                             && other_idx != idx
1692+                             // Make sure that the self type matches 
1693+                             // (i.e. constraining this closure) 
1694+                             && expected_self
1695+                                 == self . tcx . anonymize_late_bound_regions ( 
1696+                                     pred. kind ( ) . rebind ( trait_pred. self_ty ( ) ) , 
1697+                                 ) 
1698+                             // But the substs don't match (i.e. incompatible args) 
1699+                             && expected_substs
1700+                                 != self . tcx . anonymize_late_bound_regions ( 
1701+                                     pred. kind ( ) . rebind ( trait_pred. trait_ref . substs ) , 
1702+                                 )  =>
1703+                     { 
1704+                         true 
1705+                     } 
1706+                     _ => false , 
1707+                 } ) ; 
1708+             // If we found one, then it's very likely the cause of the error. 
1709+             if  let  Some ( ( _,  ( _,  other_pred_span) ) )  = other_pred { 
1710+                 err. span_note ( 
1711+                     * other_pred_span, 
1712+                     "closure inferred to have a different signature due to this bound" , 
1713+                 ) ; 
1714+             } 
1715+         } 
1716+     } 
1717+ 
16511718    fn  suggest_fully_qualified_path ( 
16521719        & self , 
16531720        err :  & mut  Diagnostic , 
0 commit comments