@@ -3192,6 +3192,8 @@ impl<'tcx> TraitDef<'tcx> {
3192
3192
}
3193
3193
}
3194
3194
3195
+ /// Iterate over every impl that could possibly match the
3196
+ /// self-type `self_ty`.
3195
3197
pub fn for_each_relevant_impl < F : FnMut ( DefId ) > ( & self ,
3196
3198
tcx : & ctxt < ' tcx > ,
3197
3199
self_ty : Ty < ' tcx > ,
@@ -3203,7 +3205,19 @@ impl<'tcx> TraitDef<'tcx> {
3203
3205
f ( impl_def_id) ;
3204
3206
}
3205
3207
3206
- if let Some ( simp) = fast_reject:: simplify_type ( tcx, self_ty, false ) {
3208
+ // simplify_type(.., false) basically replaces type parameters and
3209
+ // projections with infer-variables. This is, of course, done on
3210
+ // the impl trait-ref when it is instantiated, but not on the
3211
+ // predicate trait-ref which is passed here.
3212
+ //
3213
+ // for example, if we match `S: Copy` against an impl like
3214
+ // `impl<T:Copy> Copy for Option<T>`, we replace the type variable
3215
+ // in `Option<T>` with an infer variable, to `Option<_>` (this
3216
+ // doesn't actually change fast_reject output), but we don't
3217
+ // replace `S` with anything - this impl of course can't be
3218
+ // selected, and as there are hundreds of similar impls,
3219
+ // considering them would significantly harm performance.
3220
+ if let Some ( simp) = fast_reject:: simplify_type ( tcx, self_ty, true ) {
3207
3221
if let Some ( impls) = self . nonblanket_impls . borrow ( ) . get ( & simp) {
3208
3222
for & impl_def_id in impls {
3209
3223
f ( impl_def_id) ;
0 commit comments