@@ -1926,10 +1926,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
19261926 other : bool ,
19271927 ) -> bool {
19281928 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 | {
19331930 if candidates. is_empty ( ) {
19341931 return false ;
19351932 }
@@ -1958,26 +1955,31 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
19581955 candidates. iter ( ) . map ( |c| c. print_only_trait_path ( ) . to_string ( ) ) . collect ( ) ;
19591956 traits. sort ( ) ;
19601957 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 ;
19611961
1962- let mut candidates: Vec < String > = candidates
1962+ let candidates: Vec < String > = candidates
19631963 . into_iter ( )
19641964 . map ( |c| {
1965- if traits . len ( ) == 1 {
1965+ if all_traits_equal {
19661966 format ! ( "\n {}" , c. self_ty( ) )
19671967 } else {
19681968 format ! ( "\n {}" , c)
19691969 }
19701970 } )
19711971 . collect ( ) ;
19721972
1973- candidates. sort ( ) ;
1974- candidates. dedup ( ) ;
19751973 let end = if candidates. len ( ) <= 9 { candidates. len ( ) } else { 8 } ;
19761974 err. help ( format ! (
19771975 "the following {other}types implement trait `{}`:{}{}" ,
19781976 trait_ref. print_only_trait_path( ) ,
19791977 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+ }
19811983 ) ) ;
19821984 true
19831985 } ;
@@ -1991,7 +1993,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
19911993 // Mentioning implementers of `Copy`, `Debug` and friends is not useful.
19921994 return false ;
19931995 }
1994- let impl_candidates: Vec < _ > = self
1996+ let mut impl_candidates: Vec < _ > = self
19951997 . tcx
19961998 . all_impls ( def_id)
19971999 // Ignore automatically derived impls and `!Trait` impls.
@@ -2018,6 +2020,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
20182020 }
20192021 } )
20202022 . collect ( ) ;
2023+
2024+ impl_candidates. sort ( ) ;
2025+ impl_candidates. dedup ( ) ;
20212026 return report ( impl_candidates, err) ;
20222027 }
20232028
@@ -2027,26 +2032,25 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
20272032 //
20282033 // Prefer more similar candidates first, then sort lexicographically
20292034 // 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 ( ) ;
20312050 impl_candidates. sort_by_key ( |cand| ( cand. similarity , cand. trait_ref ) ) ;
20322051 impl_candidates. dedup ( ) ;
20332052
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)
20502054 }
20512055
20522056 fn report_similar_impl_candidates_for_root_obligation (
0 commit comments