@@ -15,6 +15,7 @@ use crate::check::{
15
15
use crate :: structured_errors:: StructuredDiagnostic ;
16
16
17
17
use rustc_ast as ast;
18
+ use rustc_data_structures:: fx:: FxHashSet ;
18
19
use rustc_errors:: { pluralize, Applicability , Diagnostic , DiagnosticId , MultiSpan } ;
19
20
use rustc_hir as hir;
20
21
use rustc_hir:: def:: { CtorOf , DefKind , Res } ;
@@ -1612,24 +1613,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1612
1613
& self ,
1613
1614
errors : & mut Vec < traits:: FulfillmentError < ' tcx > > ,
1614
1615
) {
1616
+ let mut remap_cause = FxHashSet :: default ( ) ;
1617
+ let mut not_adjusted = vec ! [ ] ;
1618
+
1615
1619
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
+ }
1617
1646
}
1618
1647
}
1619
1648
1620
1649
fn adjust_fulfillment_error_for_expr_obligation (
1621
1650
& self ,
1622
1651
error : & mut traits:: FulfillmentError < ' tcx > ,
1623
- ) {
1652
+ ) -> bool {
1624
1653
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 ; } ;
1626
1655
1627
1656
// Skip over mentioning async lang item
1628
1657
if Some ( def_id) == self . tcx . lang_items ( ) . from_generator_fn ( )
1629
1658
&& error. obligation . cause . span . desugaring_kind ( )
1630
1659
== Some ( rustc_span:: DesugaringKind :: Async )
1631
1660
{
1632
- return ;
1661
+ return false ;
1633
1662
}
1634
1663
// Skip over closure arg mismatch, which has a better heuristic
1635
1664
// to determine what span to point at.
@@ -1638,11 +1667,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1638
1667
) = error. code
1639
1668
&& let ty:: Closure ( ..) | ty:: Generator ( ..) = expected. skip_binder ( ) . self_ty ( ) . kind ( )
1640
1669
{
1641
- return ;
1670
+ return false ;
1642
1671
}
1643
1672
1644
1673
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 ; } ;
1646
1676
1647
1677
let generics = self . tcx . generics_of ( def_id) ;
1648
1678
let predicate_substs = match unsubstituted_pred. kind ( ) . skip_binder ( ) {
@@ -1709,67 +1739,69 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1709
1739
{
1710
1740
if let Some ( param_to_point_at) = param_to_point_at
1711
1741
&& self . point_at_args_if_possible ( error, def_id, param_to_point_at, * call_hir_id, callee. span , args) {
1712
- return ;
1742
+ return true ;
1713
1743
}
1714
1744
1715
1745
if let Some ( fallback_param_to_point_at) = fallback_param_to_point_at
1716
1746
&& self . point_at_args_if_possible ( error, def_id, fallback_param_to_point_at, * call_hir_id, callee. span , args)
1717
1747
{
1718
- return ;
1748
+ return true ;
1719
1749
}
1720
1750
1721
1751
if let Some ( self_param_to_point_at) = self_param_to_point_at
1722
1752
&& self . point_at_args_if_possible ( error, def_id, self_param_to_point_at, * call_hir_id, callee. span , args)
1723
1753
{
1724
- return ;
1754
+ return true ;
1725
1755
}
1726
1756
1727
1757
if let hir:: QPath :: Resolved ( _, path) = qpath
1728
1758
&& let Some ( param_to_point_at) = param_to_point_at
1729
1759
&& let Some ( segment) = path. segments . last ( )
1730
1760
&& self . point_at_generics_if_possible ( error, def_id, param_to_point_at, segment)
1731
1761
{
1732
- return ;
1762
+ return true ;
1733
1763
}
1734
1764
1735
1765
if let hir:: QPath :: TypeRelative ( _, segment) = qpath
1736
1766
&& let Some ( param_to_point_at) = param_to_point_at
1737
1767
&& self . point_at_generics_if_possible ( error, def_id, param_to_point_at, segment)
1738
1768
{
1739
- return ;
1769
+ return true ;
1740
1770
}
1741
1771
}
1742
1772
}
1743
1773
hir:: Node :: Expr ( hir:: Expr { kind : hir:: ExprKind :: MethodCall ( segment, args, ..) , .. } ) => {
1744
1774
if let Some ( param_to_point_at) = param_to_point_at
1745
1775
&& self . point_at_args_if_possible ( error, def_id, param_to_point_at, hir_id, segment. ident . span , args)
1746
1776
{
1747
- return ;
1777
+ return true ;
1748
1778
}
1749
1779
1750
1780
if let Some ( fallback_param_to_point_at) = fallback_param_to_point_at
1751
1781
&& self . point_at_args_if_possible ( error, def_id, fallback_param_to_point_at, hir_id, segment. ident . span , args)
1752
1782
{
1753
- return ;
1783
+ return true ;
1754
1784
}
1755
1785
1756
1786
if let Some ( self_param_to_point_at) = self_param_to_point_at
1757
1787
&& self . point_at_args_if_possible ( error, def_id, self_param_to_point_at, hir_id, segment. ident . span , args)
1758
1788
{
1759
- return ;
1789
+ return true ;
1760
1790
}
1761
1791
1762
1792
if let Some ( param_to_point_at) = param_to_point_at
1763
1793
&& self . point_at_generics_if_possible ( error, def_id, param_to_point_at, segment)
1764
1794
{
1765
- return ;
1795
+ return true ;
1766
1796
}
1767
1797
}
1768
1798
hir:: Node :: Expr ( hir:: Expr { kind : hir:: ExprKind :: Struct ( ..) , .. } ) => {
1769
1799
// fixme
1770
1800
}
1771
1801
_ => { }
1772
1802
}
1803
+
1804
+ false
1773
1805
}
1774
1806
1775
1807
fn find_ambiguous_parameter_in < T : TypeVisitable < ' tcx > > (
0 commit comments