@@ -30,6 +30,7 @@ use middle::ty::{self, ToPredicate, HasTypeFlags, ToPolyTraitRef, TraitRef, Ty};
30
30
use middle:: ty:: fold:: TypeFoldable ;
31
31
use util:: nodemap:: { FnvHashMap , FnvHashSet } ;
32
32
33
+ use std:: cmp;
33
34
use std:: fmt;
34
35
use syntax:: attr:: { AttributeMethods , AttrMetaMethods } ;
35
36
use syntax:: codemap:: Span ;
@@ -225,38 +226,49 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
225
226
"the trait `{}` is not implemented for the type `{}`" ,
226
227
trait_ref, trait_ref. self_ty( ) ) ;
227
228
228
- let mut counter = 1 ;
229
- infcx. tcx . sess . fileline_help (
230
- obligation. cause . span ,
231
- "the following implementations were found:" ) ;
232
- infcx. tcx . lookup_trait_def ( trait_ref. def_id ( ) ) . for_each_relevant_impl (
233
- infcx. tcx ,
234
- trait_ref. self_ty ( ) ,
235
- |impl_def_id| {
236
- match infcx. tcx . impl_trait_ref ( impl_def_id) {
237
- Some ( ref imp) => {
238
- infcx. tcx . sess . fileline_help (
239
- obligation. cause . span ,
240
- & format ! ( "implementation {}: `{}`" , counter, imp) ) ;
241
- counter += 1 ;
242
- } ,
243
- None => ( ) ,
244
- }
245
- }
246
- ) ;
247
-
248
229
// Check if it has a custom "#[rustc_on_unimplemented]"
249
230
// error message, report with that message if it does
250
231
let custom_note = report_on_unimplemented ( infcx, & trait_ref. 0 ,
251
232
obligation. cause . span ) ;
252
233
if let Some ( s) = custom_note {
253
234
err. fileline_note ( obligation. cause . span , & s) ;
235
+ } else {
236
+ let mut impl_candidates = Vec :: new ( ) ;
237
+ infcx. tcx . lookup_trait_def ( trait_ref. def_id ( ) )
238
+ . for_each_relevant_impl (
239
+ infcx. tcx ,
240
+ trait_ref. self_ty ( ) ,
241
+ |impl_def_id| {
242
+ match infcx. tcx . impl_trait_ref ( impl_def_id) {
243
+ Some ( ref imp) => {
244
+ impl_candidates. push ( format ! ( " {}" , imp) ) ;
245
+ } ,
246
+ None => ( ) ,
247
+ }
248
+ }
249
+ ) ;
250
+
251
+ if impl_candidates. len ( ) > 0 {
252
+ err. fileline_help (
253
+ obligation. cause . span ,
254
+ & format ! ( "the following implementations were found:" ) ) ;
255
+
256
+ let end = cmp:: min ( 4 , impl_candidates. len ( ) ) ;
257
+ for candidate in & impl_candidates[ 0 ..end] {
258
+ err. fileline_help ( obligation. cause . span ,
259
+ candidate) ;
260
+ }
261
+ if impl_candidates. len ( ) > 4 {
262
+ err. fileline_help ( obligation. cause . span ,
263
+ & format ! ( "and {} others" ,
264
+ impl_candidates. len( ) -4 ) ) ;
265
+ }
266
+ }
254
267
}
255
268
note_obligation_cause ( infcx, & mut err, obligation) ;
256
269
err. emit ( ) ;
257
270
}
258
- }
259
-
271
+ } ,
260
272
ty:: Predicate :: Equate ( ref predicate) => {
261
273
let predicate = infcx. resolve_type_vars_if_possible ( predicate) ;
262
274
let err = infcx. equality_predicate ( obligation. cause . span ,
0 commit comments