@@ -461,7 +461,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
461461 . flat_map ( Result :: transpose)
462462 . collect :: < Result < Vec < _ > , _ > > ( ) ?;
463463
464- debug ! ( ?stack, ?candidates, "winnowed to {} candidates" , candidates. len( ) ) ;
464+ debug ! ( ?stack, ?candidates, "{} potentially applicable candidates" , candidates. len( ) ) ;
465465 // If there are *NO* candidates, then there are no impls --
466466 // that we know of, anyway. Note that in the case where there
467467 // are unbound type variables within the obligation, it might
@@ -1896,7 +1896,33 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
18961896 }
18971897 }
18981898 if let Some ( ( def_id, _evaluation) ) = impl_candidate {
1899- return Some ( ImplCandidate ( def_id) ) ;
1899+ // Don't use impl candidates which overlap with other candidates.
1900+ // This should pretty much only ever happen with malformed impls.
1901+ if candidates. iter ( ) . all ( |c| match c. candidate {
1902+ BuiltinCandidate { has_nested : _ }
1903+ | TransmutabilityCandidate
1904+ | AutoImplCandidate
1905+ | ClosureCandidate { .. }
1906+ | AsyncClosureCandidate
1907+ | AsyncFnKindHelperCandidate
1908+ | CoroutineCandidate
1909+ | FutureCandidate
1910+ | IteratorCandidate
1911+ | AsyncIteratorCandidate
1912+ | FnPointerCandidate
1913+ | TraitAliasCandidate
1914+ | TraitUpcastingUnsizeCandidate ( _)
1915+ | BuiltinObjectCandidate
1916+ | BuiltinUnsizeCandidate => false ,
1917+ // Non-global param candidates have already been handled, global
1918+ // where-bounds get ignored.
1919+ ParamCandidate ( _) | ImplCandidate ( _) => true ,
1920+ ProjectionCandidate ( _) | ObjectCandidate ( _) => unreachable ! ( ) ,
1921+ } ) {
1922+ return Some ( ImplCandidate ( def_id) ) ;
1923+ } else {
1924+ return None ;
1925+ }
19001926 }
19011927
19021928 // Also try ignoring all global where-bounds and check whether we end
0 commit comments