@@ -1926,10 +1926,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1926
1926
other : bool ,
1927
1927
) -> bool {
1928
1928
let other = if other { "other " } else { "" } ;
1929
- let report = |mut candidates : Vec < TraitRef < ' tcx > > , err : & mut Diagnostic | {
1930
- candidates. sort ( ) ;
1931
- candidates. dedup ( ) ;
1932
- let len = candidates. len ( ) ;
1929
+ let report = |candidates : Vec < TraitRef < ' tcx > > , err : & mut Diagnostic | {
1933
1930
if candidates. is_empty ( ) {
1934
1931
return false ;
1935
1932
}
@@ -1958,26 +1955,31 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1958
1955
candidates. iter ( ) . map ( |c| c. print_only_trait_path ( ) . to_string ( ) ) . collect ( ) ;
1959
1956
traits. sort ( ) ;
1960
1957
traits. dedup ( ) ;
1958
+ // FIXME: this could use a better heuristic, like just checking
1959
+ // that substs[1..] is the same.
1960
+ let all_traits_equal = traits. len ( ) == 1 ;
1961
1961
1962
- let mut candidates: Vec < String > = candidates
1962
+ let candidates: Vec < String > = candidates
1963
1963
. into_iter ( )
1964
1964
. map ( |c| {
1965
- if traits . len ( ) == 1 {
1965
+ if all_traits_equal {
1966
1966
format ! ( "\n {}" , c. self_ty( ) )
1967
1967
} else {
1968
1968
format ! ( "\n {}" , c)
1969
1969
}
1970
1970
} )
1971
1971
. collect ( ) ;
1972
1972
1973
- candidates. sort ( ) ;
1974
- candidates. dedup ( ) ;
1975
1973
let end = if candidates. len ( ) <= 9 { candidates. len ( ) } else { 8 } ;
1976
1974
err. help ( format ! (
1977
1975
"the following {other}types implement trait `{}`:{}{}" ,
1978
1976
trait_ref. print_only_trait_path( ) ,
1979
1977
candidates[ ..end] . join( "" ) ,
1980
- if len > 9 { format!( "\n and {} others" , len - 8 ) } else { String :: new( ) }
1978
+ if candidates. len( ) > 9 {
1979
+ format!( "\n and {} others" , candidates. len( ) - 8 )
1980
+ } else {
1981
+ String :: new( )
1982
+ }
1981
1983
) ) ;
1982
1984
true
1983
1985
} ;
@@ -1991,7 +1993,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1991
1993
// Mentioning implementers of `Copy`, `Debug` and friends is not useful.
1992
1994
return false ;
1993
1995
}
1994
- let impl_candidates: Vec < _ > = self
1996
+ let mut impl_candidates: Vec < _ > = self
1995
1997
. tcx
1996
1998
. all_impls ( def_id)
1997
1999
// Ignore automatically derived impls and `!Trait` impls.
@@ -2018,6 +2020,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2018
2020
}
2019
2021
} )
2020
2022
. collect ( ) ;
2023
+
2024
+ impl_candidates. sort ( ) ;
2025
+ impl_candidates. dedup ( ) ;
2021
2026
return report ( impl_candidates, err) ;
2022
2027
}
2023
2028
@@ -2027,26 +2032,25 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2027
2032
//
2028
2033
// Prefer more similar candidates first, then sort lexicographically
2029
2034
// by their normalized string representation.
2030
- let mut impl_candidates = impl_candidates. to_vec ( ) ;
2035
+ let mut impl_candidates: Vec < _ > = impl_candidates
2036
+ . iter ( )
2037
+ . cloned ( )
2038
+ . map ( |mut cand| {
2039
+ // Fold the consts so that they shows up as, e.g., `10`
2040
+ // instead of `core::::array::{impl#30}::{constant#0}`.
2041
+ cand. trait_ref = cand. trait_ref . fold_with ( & mut BottomUpFolder {
2042
+ tcx : self . tcx ,
2043
+ ty_op : |ty| ty,
2044
+ lt_op : |lt| lt,
2045
+ ct_op : |ct| ct. eval ( self . tcx , ty:: ParamEnv :: empty ( ) ) ,
2046
+ } ) ;
2047
+ cand
2048
+ } )
2049
+ . collect ( ) ;
2031
2050
impl_candidates. sort_by_key ( |cand| ( cand. similarity , cand. trait_ref ) ) ;
2032
2051
impl_candidates. dedup ( ) ;
2033
2052
2034
- report (
2035
- impl_candidates
2036
- . into_iter ( )
2037
- . map ( |cand| {
2038
- // Fold the const so that it shows up as, e.g., `10`
2039
- // instead of `core::::array::{impl#30}::{constant#0}`.
2040
- cand. trait_ref . fold_with ( & mut BottomUpFolder {
2041
- tcx : self . tcx ,
2042
- ty_op : |ty| ty,
2043
- lt_op : |lt| lt,
2044
- ct_op : |ct| ct. eval ( self . tcx , ty:: ParamEnv :: empty ( ) ) ,
2045
- } )
2046
- } )
2047
- . collect ( ) ,
2048
- err,
2049
- )
2053
+ report ( impl_candidates. into_iter ( ) . map ( |cand| cand. trait_ref ) . collect ( ) , err)
2050
2054
}
2051
2055
2052
2056
fn report_similar_impl_candidates_for_root_obligation (
0 commit comments