@@ -27,6 +27,7 @@ use fmt_macros::{Parser, Piece, Position};
27
27
use middle:: def_id:: DefId ;
28
28
use middle:: infer:: InferCtxt ;
29
29
use middle:: ty:: { self , ToPredicate , HasTypeFlags , ToPolyTraitRef , TraitRef , Ty } ;
30
+ use middle:: ty:: fast_reject;
30
31
use middle:: ty:: fold:: TypeFoldable ;
31
32
use util:: nodemap:: { FnvHashMap , FnvHashSet } ;
32
33
@@ -233,20 +234,38 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
233
234
if let Some ( s) = custom_note {
234
235
err. fileline_note ( obligation. cause . span , & s) ;
235
236
} 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 => ( ) ,
237
+ infcx. tcx . populate_implementations_for_trait_if_necessary (
238
+ trait_ref. def_id ( ) ) ;
239
+
240
+ let trait_def = infcx. tcx . lookup_trait_def ( trait_ref. def_id ( ) ) ;
241
+ let blanket_impls = trait_def. blanket_impls . borrow ( ) ;
242
+ let impl_iter = blanket_impls. iter ( )
243
+ . filter_map ( |& id|
244
+ infcx. tcx . impl_trait_ref ( id) ) ;
245
+
246
+ let nonblanket = trait_def. nonblanket_impls . borrow ( ) ;
247
+ let nonblanket_iter = nonblanket. values ( )
248
+ . flat_map ( |ids|
249
+ ids. iter ( ) . filter_map ( |& id|
250
+ infcx. tcx . impl_trait_ref ( id) ) ) ;
251
+
252
+ let simp = fast_reject:: simplify_type ( infcx. tcx , trait_ref. self_ty ( ) , true ) ;
253
+ let nonblanket_iter = nonblanket_iter. filter ( |def| {
254
+ if let Some ( simp) = simp {
255
+ let imp_simp = fast_reject:: simplify_type ( infcx. tcx , def. self_ty ( ) , true ) ;
256
+ if let Some ( imp_simp) = imp_simp {
257
+ simp == imp_simp
258
+ } else {
259
+ false
247
260
}
261
+ } else {
262
+ true
248
263
}
249
- ) ;
264
+ } ) ;
265
+
266
+ let impl_candidates = impl_iter. chain ( nonblanket_iter)
267
+ . map ( |imp| format ! ( " {}" , imp) )
268
+ . take ( 5 ) . collect :: < Vec < _ > > ( ) ;
250
269
251
270
if impl_candidates. len ( ) > 0 {
252
271
err. fileline_help (
0 commit comments