@@ -652,8 +652,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
652
652
let is_dup =
653
653
( 0 ..candidates. len ( ) )
654
654
. filter ( |& j| i != j)
655
- . any ( |j| self . candidate_should_be_dropped_in_favor_of ( stack,
656
- & candidates[ i] ,
655
+ . any ( |j| self . candidate_should_be_dropped_in_favor_of ( & candidates[ i] ,
657
656
& candidates[ j] ) ) ;
658
657
if is_dup {
659
658
debug ! ( "Dropping candidate #{}/{}: {}" ,
@@ -1235,31 +1234,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1235
1234
self . evaluate_predicates_recursively ( stack, selection. iter_nested ( ) )
1236
1235
}
1237
1236
1238
- /// Returns true if `candidate_i` should be dropped in favor of `candidate_j`.
1239
- ///
1240
- /// This is generally true if either:
1241
- /// - candidate i and candidate j are equivalent; or,
1242
- /// - candidate i is a concrete impl and candidate j is a where clause bound,
1243
- /// and the concrete impl is applicable to the types in the where clause bound.
1244
- ///
1245
- /// The last case refers to cases where there are blanket impls (often conditional
1246
- /// blanket impls) as well as a where clause. This can come down to one of two cases:
1247
- ///
1248
- /// - The impl is truly unconditional (it has no where clauses
1249
- /// of its own), in which case the where clause is
1250
- /// unnecessary, because coherence requires that we would
1251
- /// pick that particular impl anyhow (at least so long as we
1252
- /// don't have specialization).
1253
- ///
1254
- /// - The impl is conditional, in which case we may not have winnowed it out
1255
- /// because we don't know if the conditions apply, but the where clause is basically
1256
- /// telling us that there is some impl, though not necessarily the one we see.
1257
- ///
1258
- /// In both cases we prefer to take the where clause, which is
1259
- /// essentially harmless. See issue #18453 for more details of
1260
- /// a case where doing the opposite caused us harm.
1237
+ /// Returns true if `candidate_i` should be dropped in favor of
1238
+ /// `candidate_j`. Generally speaking we will drop duplicate
1239
+ /// candidates and prefer where-clause candidates.
1261
1240
fn candidate_should_be_dropped_in_favor_of < ' o > ( & mut self ,
1262
- stack : & TraitObligationStack < ' o , ' tcx > ,
1263
1241
candidate_i : & SelectionCandidate < ' tcx > ,
1264
1242
candidate_j : & SelectionCandidate < ' tcx > )
1265
1243
-> bool
@@ -1269,37 +1247,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
1269
1247
}
1270
1248
1271
1249
match ( candidate_i, candidate_j) {
1272
- ( & ImplCandidate ( impl_def_id) , & ParamCandidate ( ref bound) ) => {
1273
- debug ! ( "Considering whether to drop param {} in favor of impl {}" ,
1274
- candidate_i. repr( self . tcx( ) ) ,
1275
- candidate_j. repr( self . tcx( ) ) ) ;
1276
-
1277
- self . infcx . probe ( |snapshot| {
1278
- let ( skol_obligation_trait_ref, skol_map) =
1279
- self . infcx ( ) . skolemize_late_bound_regions (
1280
- & stack. obligation . predicate , snapshot) ;
1281
- let impl_substs =
1282
- self . rematch_impl ( impl_def_id, stack. obligation , snapshot,
1283
- & skol_map, skol_obligation_trait_ref. trait_ref . clone ( ) ) ;
1284
- let impl_trait_ref =
1285
- ty:: impl_trait_ref ( self . tcx ( ) , impl_def_id) . unwrap ( ) ;
1286
- let impl_trait_ref =
1287
- impl_trait_ref. subst ( self . tcx ( ) , & impl_substs. value ) ;
1288
- let poly_impl_trait_ref =
1289
- ty:: Binder ( impl_trait_ref) ;
1290
- let origin =
1291
- infer:: RelateOutputImplTypes ( stack. obligation . cause . span ) ;
1292
- self . infcx
1293
- . sub_poly_trait_refs ( false , origin, poly_impl_trait_ref, bound. clone ( ) )
1294
- . is_ok ( )
1295
- } )
1296
- }
1297
- ( & BuiltinCandidate ( _) , & ParamCandidate ( _) ) => {
1298
- // If we have a where-clause like `Option<K> : Send`,
1299
- // then we wind up in a situation where there is a
1300
- // default rule (`Option<K>:Send if K:Send) and the
1301
- // where-clause that both seem applicable. Just take
1302
- // the where-clause in that case.
1250
+ ( & ImplCandidate ( ..) , & ParamCandidate ( ..) ) |
1251
+ ( & ClosureCandidate ( ..) , & ParamCandidate ( ..) ) |
1252
+ ( & FnPointerCandidate ( ..) , & ParamCandidate ( ..) ) |
1253
+ ( & BuiltinCandidate ( ..) , & ParamCandidate ( ..) ) => {
1254
+ // We basically prefer always prefer to use a
1255
+ // where-clause over another option. Where clauses
1256
+ // impose the burden of finding the exact match onto
1257
+ // the caller. Using an impl in preference of a where
1258
+ // clause can also lead us to "overspecialize", as in
1259
+ // #18453.
1303
1260
true
1304
1261
}
1305
1262
( & ProjectionCandidate , & ParamCandidate ( _) ) => {
0 commit comments