@@ -34,6 +34,7 @@ use std::iter;
34
34
35
35
use crate :: traits:: query:: evaluate_obligation:: InferCtxtExt as _;
36
36
use crate :: traits:: query:: normalize:: AtExt as _;
37
+ use crate :: traits:: specialize:: to_pretty_impl_header;
37
38
use on_unimplemented:: InferCtxtExt as _;
38
39
use suggestions:: InferCtxtExt as _;
39
40
@@ -241,6 +242,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
241
242
let mut span = obligation. cause . span ;
242
243
243
244
let mut err = match * error {
245
+ SelectionError :: Ambiguous ( ref impls) => {
246
+ let mut err = self . tcx . sess . struct_span_err (
247
+ obligation. cause . span ,
248
+ & format ! ( "multiple applicable `impl`s for `{}`" , obligation. predicate) ,
249
+ ) ;
250
+ self . annotate_source_of_ambiguity ( & mut err, impls, obligation. predicate ) ;
251
+ err. emit ( ) ;
252
+ return ;
253
+ }
244
254
SelectionError :: Unimplemented => {
245
255
// If this obligation was generated as a result of well-formedness checking, see if we
246
256
// can get a better error message by performing HIR-based well-formedness checking.
@@ -1138,6 +1148,13 @@ trait InferCtxtPrivExt<'tcx> {
1138
1148
obligation : & PredicateObligation < ' tcx > ,
1139
1149
) ;
1140
1150
1151
+ fn annotate_source_of_ambiguity (
1152
+ & self ,
1153
+ err : & mut DiagnosticBuilder < ' tcx > ,
1154
+ impls : & [ DefId ] ,
1155
+ predicate : ty:: Predicate < ' tcx > ,
1156
+ ) ;
1157
+
1141
1158
fn maybe_suggest_unsized_generics (
1142
1159
& self ,
1143
1160
err : & mut DiagnosticBuilder < ' tcx > ,
@@ -1549,11 +1566,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
1549
1566
?predicate, ?obligation. cause. code,
1550
1567
) ;
1551
1568
1552
- // Ambiguity errors are often caused as fallout from earlier
1553
- // errors. So just ignore them if this infcx is tainted.
1554
- if self . is_tainted_by_errors ( ) {
1555
- return ;
1556
- }
1569
+ // Ambiguity errors are often caused as fallout from earlier errors.
1570
+ // We ignore them if this `infcx` is tainted in some cases below.
1557
1571
1558
1572
let bound_predicate = predicate. kind ( ) ;
1559
1573
let mut err = match bound_predicate. skip_binder ( ) {
@@ -1601,10 +1615,19 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
1601
1615
// check upstream for type errors and don't add the obligations to
1602
1616
// begin with in those cases.
1603
1617
if self . tcx . lang_items ( ) . sized_trait ( ) == Some ( trait_ref. def_id ( ) ) {
1604
- self . emit_inference_failure_err ( body_id, span, subst, vec ! [ ] , ErrorCode :: E0282 )
1618
+ if !self . is_tainted_by_errors ( ) {
1619
+ self . emit_inference_failure_err (
1620
+ body_id,
1621
+ span,
1622
+ subst,
1623
+ vec ! [ ] ,
1624
+ ErrorCode :: E0282 ,
1625
+ )
1605
1626
. emit ( ) ;
1627
+ }
1606
1628
return ;
1607
1629
}
1630
+
1608
1631
let impl_candidates = self . find_similar_impl_candidates ( trait_ref) ;
1609
1632
let mut err = self . emit_inference_failure_err (
1610
1633
body_id,
@@ -1613,7 +1636,29 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
1613
1636
impl_candidates,
1614
1637
ErrorCode :: E0283 ,
1615
1638
) ;
1616
- err. note ( & format ! ( "cannot satisfy `{}`" , predicate) ) ;
1639
+
1640
+ let obligation = Obligation :: new (
1641
+ obligation. cause . clone ( ) ,
1642
+ obligation. param_env ,
1643
+ trait_ref. to_poly_trait_predicate ( ) ,
1644
+ ) ;
1645
+ let mut selcx = SelectionContext :: with_query_mode (
1646
+ & self ,
1647
+ crate :: traits:: TraitQueryMode :: Standard ,
1648
+ ) ;
1649
+ match selcx. select_from_obligation ( & obligation) {
1650
+ Err ( SelectionError :: Ambiguous ( impls) ) if impls. len ( ) > 1 => {
1651
+ self . annotate_source_of_ambiguity ( & mut err, & impls, predicate) ;
1652
+ }
1653
+ _ => {
1654
+ if self . is_tainted_by_errors ( ) {
1655
+ err. cancel ( ) ;
1656
+ return ;
1657
+ }
1658
+ err. note ( & format ! ( "cannot satisfy `{}`" , predicate) ) ;
1659
+ }
1660
+ }
1661
+
1617
1662
if let ObligationCauseCode :: ItemObligation ( def_id) = obligation. cause . code {
1618
1663
self . suggest_fully_qualified_path ( & mut err, def_id, span, trait_ref. def_id ( ) ) ;
1619
1664
} else if let (
@@ -1674,15 +1719,21 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
1674
1719
ty:: PredicateKind :: WellFormed ( arg) => {
1675
1720
// Same hacky approach as above to avoid deluging user
1676
1721
// with error messages.
1677
- if arg. references_error ( ) || self . tcx . sess . has_errors ( ) {
1722
+ if arg. references_error ( )
1723
+ || self . tcx . sess . has_errors ( )
1724
+ || self . is_tainted_by_errors ( )
1725
+ {
1678
1726
return ;
1679
1727
}
1680
1728
1681
1729
self . emit_inference_failure_err ( body_id, span, arg, vec ! [ ] , ErrorCode :: E0282 )
1682
1730
}
1683
1731
1684
1732
ty:: PredicateKind :: Subtype ( data) => {
1685
- if data. references_error ( ) || self . tcx . sess . has_errors ( ) {
1733
+ if data. references_error ( )
1734
+ || self . tcx . sess . has_errors ( )
1735
+ || self . is_tainted_by_errors ( )
1736
+ {
1686
1737
// no need to overload user in such cases
1687
1738
return ;
1688
1739
}
@@ -1694,7 +1745,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
1694
1745
ty:: PredicateKind :: Projection ( data) => {
1695
1746
let self_ty = data. projection_ty . self_ty ( ) ;
1696
1747
let ty = data. ty ;
1697
- if predicate. references_error ( ) {
1748
+ if predicate. references_error ( ) || self . is_tainted_by_errors ( ) {
1698
1749
return ;
1699
1750
}
1700
1751
if self_ty. needs_infer ( ) && ty. needs_infer ( ) {
@@ -1722,7 +1773,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
1722
1773
}
1723
1774
1724
1775
_ => {
1725
- if self . tcx . sess . has_errors ( ) {
1776
+ if self . tcx . sess . has_errors ( ) || self . is_tainted_by_errors ( ) {
1726
1777
return ;
1727
1778
}
1728
1779
let mut err = struct_span_err ! (
@@ -1740,6 +1791,96 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
1740
1791
err. emit ( ) ;
1741
1792
}
1742
1793
1794
+ fn annotate_source_of_ambiguity (
1795
+ & self ,
1796
+ err : & mut DiagnosticBuilder < ' tcx > ,
1797
+ impls : & [ DefId ] ,
1798
+ predicate : ty:: Predicate < ' tcx > ,
1799
+ ) {
1800
+ let mut spans = vec ! [ ] ;
1801
+ let mut crates = vec ! [ ] ;
1802
+ let mut post = vec ! [ ] ;
1803
+ for def_id in impls {
1804
+ match self . tcx . span_of_impl ( * def_id) {
1805
+ Ok ( span) => spans. push ( self . tcx . sess . source_map ( ) . guess_head_span ( span) ) ,
1806
+ Err ( name) => {
1807
+ crates. push ( name) ;
1808
+ if let Some ( header) = to_pretty_impl_header ( self . tcx , * def_id) {
1809
+ post. push ( header) ;
1810
+ }
1811
+ }
1812
+ }
1813
+ }
1814
+ let msg = format ! ( "multiple `impl`s satisfying `{}` found" , predicate) ;
1815
+ let mut crate_names: Vec < _ > = crates. iter ( ) . map ( |n| format ! ( "`{}`" , n) ) . collect ( ) ;
1816
+ crate_names. sort ( ) ;
1817
+ crate_names. dedup ( ) ;
1818
+ post. sort ( ) ;
1819
+ post. dedup ( ) ;
1820
+
1821
+ if self . is_tainted_by_errors ( )
1822
+ && crate_names. len ( ) == 1
1823
+ && crate_names[ 0 ] == "`core`"
1824
+ && spans. len ( ) == 0
1825
+ {
1826
+ // Avoid complaining about other inference issues for expressions like
1827
+ // `42 >> 1`, where the types are still `{integer}`, but we want to
1828
+ // Do we need `trait_ref.skip_binder().self_ty().is_numeric() &&` too?
1829
+ err. cancel ( ) ;
1830
+ return ;
1831
+ }
1832
+ let post = if post. len ( ) > 4 {
1833
+ format ! (
1834
+ ":\n {}\n and {} more" ,
1835
+ post. iter( ) . map( |p| format!( "- {}" , p) ) . take( 4 ) . collect:: <Vec <_>>( ) . join( "\n " ) ,
1836
+ post. len( ) - 4 ,
1837
+ )
1838
+ } else if post. len ( ) > 1 || ( post. len ( ) == 1 && post[ 0 ] . contains ( "\n " ) ) {
1839
+ format ! ( ":\n {}" , post. iter( ) . map( |p| format!( "- {}" , p) ) . collect:: <Vec <_>>( ) . join( "\n " ) , )
1840
+ } else if post. len ( ) == 1 {
1841
+ format ! ( ": `{}`" , post[ 0 ] )
1842
+ } else {
1843
+ String :: new ( )
1844
+ } ;
1845
+
1846
+ match ( spans. len ( ) , crates. len ( ) , crate_names. len ( ) ) {
1847
+ ( 0 , 0 , 0 ) => {
1848
+ err. note ( & format ! ( "cannot satisfy `{}`" , predicate) ) ;
1849
+ }
1850
+ ( 0 , _, 1 ) => {
1851
+ err. note ( & format ! ( "{} in the `{}` crate{}" , msg, crates[ 0 ] , post, ) ) ;
1852
+ }
1853
+ ( 0 , _, _) => {
1854
+ err. note ( & format ! (
1855
+ "{} in the following crates: {}{}" ,
1856
+ msg,
1857
+ crate_names. join( ", " ) ,
1858
+ post,
1859
+ ) ) ;
1860
+ }
1861
+ ( _, 0 , 0 ) => {
1862
+ let span: MultiSpan = spans. into ( ) ;
1863
+ err. span_note ( span, & msg) ;
1864
+ }
1865
+ ( _, 1 , 1 ) => {
1866
+ let span: MultiSpan = spans. into ( ) ;
1867
+ err. span_note ( span, & msg) ;
1868
+ err. note (
1869
+ & format ! ( "and another `impl` found in the `{}` crate{}" , crates[ 0 ] , post, ) ,
1870
+ ) ;
1871
+ }
1872
+ _ => {
1873
+ let span: MultiSpan = spans. into ( ) ;
1874
+ err. span_note ( span, & msg) ;
1875
+ err. note ( & format ! (
1876
+ "and more `impl`s found in the following crates: {}{}" ,
1877
+ crate_names. join( ", " ) ,
1878
+ post,
1879
+ ) ) ;
1880
+ }
1881
+ }
1882
+ }
1883
+
1743
1884
/// Returns `true` if the trait predicate may apply for *some* assignment
1744
1885
/// to the type parameters.
1745
1886
fn predicate_can_apply (
0 commit comments