@@ -458,7 +458,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
458
458
. flat_map ( Result :: transpose)
459
459
. collect :: < Result < Vec < _ > , _ > > ( ) ?;
460
460
461
- debug ! ( ?stack, ?candidates, "winnowed to {} candidates" , candidates. len( ) ) ;
461
+ debug ! ( ?stack, ?candidates, "{} potentially applicable candidates" , candidates. len( ) ) ;
462
462
// If there are *NO* candidates, then there are no impls --
463
463
// that we know of, anyway. Note that in the case where there
464
464
// are unbound type variables within the obligation, it might
@@ -1883,7 +1883,33 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
1883
1883
}
1884
1884
}
1885
1885
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
+ }
1887
1913
}
1888
1914
1889
1915
// Also try ignoring all global where-bounds and check whether we end
0 commit comments