@@ -458,7 +458,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
458458 . flat_map ( Result :: transpose)
459459 . collect :: < Result < Vec < _ > , _ > > ( ) ?;
460460
461- debug ! ( ?stack, ?candidates, "winnowed to {} candidates" , candidates. len( ) ) ;
461+ debug ! ( ?stack, ?candidates, "{} potentially applicable candidates" , candidates. len( ) ) ;
462462 // If there are *NO* candidates, then there are no impls --
463463 // that we know of, anyway. Note that in the case where there
464464 // are unbound type variables within the obligation, it might
@@ -1883,7 +1883,33 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
18831883 }
18841884 }
18851885 if let Some ( ( def_id, _evaluation) ) = impl_candidate {
1886- return Some ( ImplCandidate ( def_id) ) ;
1886+ // Don't use impl candidates which overlap with other candidates.
1887+ // This should pretty much only ever happen with malformed impls.
1888+ if candidates. iter ( ) . all ( |c| match c. candidate {
1889+ BuiltinCandidate { has_nested : _ }
1890+ | TransmutabilityCandidate
1891+ | AutoImplCandidate
1892+ | ClosureCandidate { .. }
1893+ | AsyncClosureCandidate
1894+ | AsyncFnKindHelperCandidate
1895+ | CoroutineCandidate
1896+ | FutureCandidate
1897+ | IteratorCandidate
1898+ | AsyncIteratorCandidate
1899+ | FnPointerCandidate
1900+ | TraitAliasCandidate
1901+ | TraitUpcastingUnsizeCandidate ( _)
1902+ | BuiltinObjectCandidate
1903+ | BuiltinUnsizeCandidate => false ,
1904+ // Non-global param candidates have already been handled, global
1905+ // where-bounds get ignored.
1906+ ParamCandidate ( _) | ImplCandidate ( _) => true ,
1907+ ProjectionCandidate ( _) | ObjectCandidate ( _) => unreachable ! ( ) ,
1908+ } ) {
1909+ return Some ( ImplCandidate ( def_id) ) ;
1910+ } else {
1911+ return None ;
1912+ }
18871913 }
18881914
18891915 // Also try ignoring all global where-bounds and check whether we end
0 commit comments