@@ -652,8 +652,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
652652 let is_dup =
653653 ( 0 ..candidates. len ( ) )
654654 . 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] ,
657656 & candidates[ j] ) ) ;
658657 if is_dup {
659658 debug ! ( "Dropping candidate #{}/{}: {}" ,
@@ -1235,31 +1234,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12351234 self . evaluate_predicates_recursively ( stack, selection. iter_nested ( ) )
12361235 }
12371236
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.
12611240 fn candidate_should_be_dropped_in_favor_of < ' o > ( & mut self ,
1262- stack : & TraitObligationStack < ' o , ' tcx > ,
12631241 candidate_i : & SelectionCandidate < ' tcx > ,
12641242 candidate_j : & SelectionCandidate < ' tcx > )
12651243 -> bool
@@ -1269,37 +1247,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12691247 }
12701248
12711249 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.
13031260 true
13041261 }
13051262 ( & ProjectionCandidate , & ParamCandidate ( _) ) => {
0 commit comments