@@ -15,6 +15,7 @@ use crate::check::{
1515use crate :: structured_errors:: StructuredDiagnostic ;
1616
1717use rustc_ast as ast;
18+ use rustc_data_structures:: fx:: FxHashSet ;
1819use rustc_errors:: { pluralize, Applicability , Diagnostic , DiagnosticId , MultiSpan } ;
1920use rustc_hir as hir;
2021use rustc_hir:: def:: { CtorOf , DefKind , Res } ;
@@ -1612,24 +1613,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16121613 & self ,
16131614 errors : & mut Vec < traits:: FulfillmentError < ' tcx > > ,
16141615 ) {
1616+ let mut remap_cause = FxHashSet :: default ( ) ;
1617+ let mut not_adjusted = vec ! [ ] ;
1618+
16151619 for error in errors {
1616- self . adjust_fulfillment_error_for_expr_obligation ( error) ;
1620+ let before_span = error. obligation . cause . span ;
1621+ if self . adjust_fulfillment_error_for_expr_obligation ( error) {
1622+ remap_cause. insert ( (
1623+ before_span,
1624+ error. obligation . predicate ,
1625+ error. obligation . cause . clone ( ) ,
1626+ ) ) ;
1627+ remap_cause. insert ( (
1628+ before_span,
1629+ error. obligation . predicate . without_const ( self . tcx ) ,
1630+ error. obligation . cause . clone ( ) ,
1631+ ) ) ;
1632+ } else {
1633+ not_adjusted. push ( error) ;
1634+ }
1635+ }
1636+
1637+ for error in not_adjusted {
1638+ for ( span, predicate, cause) in & remap_cause {
1639+ if * predicate == error. obligation . predicate
1640+ && span. contains ( error. obligation . cause . span )
1641+ {
1642+ error. obligation . cause = cause. clone ( ) ;
1643+ continue ;
1644+ }
1645+ }
16171646 }
16181647 }
16191648
16201649 fn adjust_fulfillment_error_for_expr_obligation (
16211650 & self ,
16221651 error : & mut traits:: FulfillmentError < ' tcx > ,
1623- ) {
1652+ ) -> bool {
16241653 let ( traits:: ExprItemObligation ( def_id, hir_id, idx) | traits:: ExprBindingObligation ( def_id, _, hir_id, idx) )
1625- = * error. obligation . cause . code ( ) . peel_derives ( ) else { return ; } ;
1654+ = * error. obligation . cause . code ( ) . peel_derives ( ) else { return false ; } ;
16261655
16271656 // Skip over mentioning async lang item
16281657 if Some ( def_id) == self . tcx . lang_items ( ) . from_generator_fn ( )
16291658 && error. obligation . cause . span . desugaring_kind ( )
16301659 == Some ( rustc_span:: DesugaringKind :: Async )
16311660 {
1632- return ;
1661+ return false ;
16331662 }
16341663 // Skip over closure arg mismatch, which has a better heuristic
16351664 // to determine what span to point at.
@@ -1638,11 +1667,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16381667 ) = error. code
16391668 && let ty:: Closure ( ..) | ty:: Generator ( ..) = expected. skip_binder ( ) . self_ty ( ) . kind ( )
16401669 {
1641- return ;
1670+ return false ;
16421671 }
16431672
16441673 let Some ( unsubstituted_pred) =
1645- self . tcx . predicates_of ( def_id) . instantiate_identity ( self . tcx ) . predicates . into_iter ( ) . nth ( idx) else { return ; } ;
1674+ self . tcx . predicates_of ( def_id) . instantiate_identity ( self . tcx ) . predicates . into_iter ( ) . nth ( idx)
1675+ else { return false ; } ;
16461676
16471677 let generics = self . tcx . generics_of ( def_id) ;
16481678 let predicate_substs = match unsubstituted_pred. kind ( ) . skip_binder ( ) {
@@ -1709,67 +1739,69 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17091739 {
17101740 if let Some ( param_to_point_at) = param_to_point_at
17111741 && self . point_at_args_if_possible ( error, def_id, param_to_point_at, * call_hir_id, callee. span , args) {
1712- return ;
1742+ return true ;
17131743 }
17141744
17151745 if let Some ( fallback_param_to_point_at) = fallback_param_to_point_at
17161746 && self . point_at_args_if_possible ( error, def_id, fallback_param_to_point_at, * call_hir_id, callee. span , args)
17171747 {
1718- return ;
1748+ return true ;
17191749 }
17201750
17211751 if let Some ( self_param_to_point_at) = self_param_to_point_at
17221752 && self . point_at_args_if_possible ( error, def_id, self_param_to_point_at, * call_hir_id, callee. span , args)
17231753 {
1724- return ;
1754+ return true ;
17251755 }
17261756
17271757 if let hir:: QPath :: Resolved ( _, path) = qpath
17281758 && let Some ( param_to_point_at) = param_to_point_at
17291759 && let Some ( segment) = path. segments . last ( )
17301760 && self . point_at_generics_if_possible ( error, def_id, param_to_point_at, segment)
17311761 {
1732- return ;
1762+ return true ;
17331763 }
17341764
17351765 if let hir:: QPath :: TypeRelative ( _, segment) = qpath
17361766 && let Some ( param_to_point_at) = param_to_point_at
17371767 && self . point_at_generics_if_possible ( error, def_id, param_to_point_at, segment)
17381768 {
1739- return ;
1769+ return true ;
17401770 }
17411771 }
17421772 }
17431773 hir:: Node :: Expr ( hir:: Expr { kind : hir:: ExprKind :: MethodCall ( segment, args, ..) , .. } ) => {
17441774 if let Some ( param_to_point_at) = param_to_point_at
17451775 && self . point_at_args_if_possible ( error, def_id, param_to_point_at, hir_id, segment. ident . span , args)
17461776 {
1747- return ;
1777+ return true ;
17481778 }
17491779
17501780 if let Some ( fallback_param_to_point_at) = fallback_param_to_point_at
17511781 && self . point_at_args_if_possible ( error, def_id, fallback_param_to_point_at, hir_id, segment. ident . span , args)
17521782 {
1753- return ;
1783+ return true ;
17541784 }
17551785
17561786 if let Some ( self_param_to_point_at) = self_param_to_point_at
17571787 && self . point_at_args_if_possible ( error, def_id, self_param_to_point_at, hir_id, segment. ident . span , args)
17581788 {
1759- return ;
1789+ return true ;
17601790 }
17611791
17621792 if let Some ( param_to_point_at) = param_to_point_at
17631793 && self . point_at_generics_if_possible ( error, def_id, param_to_point_at, segment)
17641794 {
1765- return ;
1795+ return true ;
17661796 }
17671797 }
17681798 hir:: Node :: Expr ( hir:: Expr { kind : hir:: ExprKind :: Struct ( ..) , .. } ) => {
17691799 // fixme
17701800 }
17711801 _ => { }
17721802 }
1803+
1804+ false
17731805 }
17741806
17751807 fn find_ambiguous_parameter_in < T : TypeVisitable < ' tcx > > (
0 commit comments