@@ -465,14 +465,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
465465 if candidates. len ( ) > 1 {
466466 let mut i = 0 ;
467467 while i < candidates. len ( ) {
468- let is_dup = ( 0 ..candidates. len ( ) ) . filter ( |& j| i != j) . any ( |j| {
468+ let should_drop_i = ( 0 ..candidates. len ( ) ) . filter ( |& j| i != j) . any ( |j| {
469469 self . candidate_should_be_dropped_in_favor_of (
470470 & candidates[ i] ,
471471 & candidates[ j] ,
472472 needs_infer,
473- )
473+ ) == DropVictim :: Yes
474474 } ) ;
475- if is_dup {
475+ if should_drop_i {
476476 debug ! ( candidate = ?candidates[ i] , "Dropping candidate #{}/{}" , i, candidates. len( ) ) ;
477477 candidates. swap_remove ( i) ;
478478 } else {
@@ -1842,15 +1842,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
18421842 ProjectionMatchesProjection :: No
18431843 }
18441844 }
1845+ }
18451846
1846- ///////////////////////////////////////////////////////////////////////////
1847- // WINNOW
1848- //
1849- // Winnowing is the process of attempting to resolve ambiguity by
1850- // probing further. During the winnowing process, we unify all
1851- // type variables and then we also attempt to evaluate recursive
1852- // bounds to see if they are satisfied.
1847+ #[ derive( Debug , Copy , Clone , PartialEq , Eq ) ]
1848+ enum DropVictim {
1849+ Yes ,
1850+ No ,
1851+ }
18531852
1853+ /// ## Winnowing
1854+ ///
1855+ /// Winnowing is the process of attempting to resolve ambiguity by
1856+ /// probing further. During the winnowing process, we unify all
1857+ /// type variables and then we also attempt to evaluate recursive
1858+ /// bounds to see if they are satisfied.
1859+ impl < ' tcx > SelectionContext < ' _ , ' tcx > {
18541860 /// Returns `true` if `victim` should be dropped in favor of
18551861 /// `other`. Generally speaking we will drop duplicate
18561862 /// candidates and prefer where-clause candidates.
@@ -1861,9 +1867,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
18611867 victim : & EvaluatedCandidate < ' tcx > ,
18621868 other : & EvaluatedCandidate < ' tcx > ,
18631869 needs_infer : bool ,
1864- ) -> bool {
1870+ ) -> DropVictim {
18651871 if victim. candidate == other. candidate {
1866- return true ;
1872+ return DropVictim :: Yes ;
18671873 }
18681874
18691875 // Check if a bound would previously have been removed when normalizing
@@ -1887,11 +1893,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
18871893 }
18881894
18891895 // FIXME(@jswrenn): this should probably be more sophisticated
1890- ( TransmutabilityCandidate , _) | ( _, TransmutabilityCandidate ) => false ,
1896+ ( TransmutabilityCandidate , _) | ( _, TransmutabilityCandidate ) => DropVictim :: No ,
18911897
18921898 // (*)
1893- ( BuiltinCandidate { has_nested : false } | ConstDestructCandidate ( _) , _) => true ,
1894- ( _, BuiltinCandidate { has_nested : false } | ConstDestructCandidate ( _) ) => false ,
1899+ ( BuiltinCandidate { has_nested : false } | ConstDestructCandidate ( _) , _) => {
1900+ DropVictim :: Yes
1901+ }
1902+ ( _, BuiltinCandidate { has_nested : false } | ConstDestructCandidate ( _) ) => {
1903+ DropVictim :: No
1904+ }
18951905
18961906 ( ParamCandidate ( other) , ParamCandidate ( victim) ) => {
18971907 let same_except_bound_vars = other. skip_binder ( ) . trait_ref
@@ -1905,28 +1915,27 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
19051915 // or the current one if tied (they should both evaluate to the same answer). This is
19061916 // probably best characterized as a "hack", since we might prefer to just do our
19071917 // best to *not* create essentially duplicate candidates in the first place.
1908- other. bound_vars ( ) . len ( ) <= victim. bound_vars ( ) . len ( )
1918+ if other. bound_vars ( ) . len ( ) <= victim. bound_vars ( ) . len ( ) {
1919+ DropVictim :: Yes
1920+ } else {
1921+ DropVictim :: No
1922+ }
19091923 } else if other. skip_binder ( ) . trait_ref == victim. skip_binder ( ) . trait_ref
19101924 && victim. skip_binder ( ) . constness == ty:: BoundConstness :: NotConst
19111925 && other. skip_binder ( ) . polarity == victim. skip_binder ( ) . polarity
19121926 {
19131927 // Drop otherwise equivalent non-const candidates in favor of const candidates.
1914- true
1928+ DropVictim :: Yes
19151929 } else {
1916- false
1930+ DropVictim :: No
19171931 }
19181932 }
19191933
19201934 // Drop otherwise equivalent non-const fn pointer candidates
1921- ( FnPointerCandidate { .. } , FnPointerCandidate { is_const : false } ) => true ,
1935+ ( FnPointerCandidate { .. } , FnPointerCandidate { is_const : false } ) => DropVictim :: Yes ,
19221936
1923- // Global bounds from the where clause should be ignored
1924- // here (see issue #50825). Otherwise, we have a where
1925- // clause so don't go around looking for impls.
1926- // Arbitrarily give param candidates priority
1927- // over projection and object candidates.
19281937 (
1929- ParamCandidate ( ref cand ) ,
1938+ ParamCandidate ( ref other_cand ) ,
19301939 ImplCandidate ( ..)
19311940 | ClosureCandidate { .. }
19321941 | GeneratorCandidate
@@ -1939,11 +1948,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
19391948 | TraitAliasCandidate
19401949 | ObjectCandidate ( _)
19411950 | ProjectionCandidate ( ..) ,
1942- ) => !is_global ( cand) ,
1943- ( ObjectCandidate ( _) | ProjectionCandidate ( ..) , ParamCandidate ( ref cand) ) => {
1951+ ) => {
1952+ if is_global ( other_cand) {
1953+ DropVictim :: No
1954+ } else {
1955+ // We have a where clause so don't go around looking
1956+ // for impls. Arbitrarily give param candidates priority
1957+ // over projection and object candidates.
1958+ //
1959+ // Global bounds from the where clause should be ignored
1960+ // here (see issue #50825).
1961+ DropVictim :: Yes
1962+ }
1963+ }
1964+ ( ObjectCandidate ( _) | ProjectionCandidate ( ..) , ParamCandidate ( ref victim_cand) ) => {
19441965 // Prefer these to a global where-clause bound
19451966 // (see issue #50825).
1946- is_global ( cand )
1967+ if is_global ( victim_cand ) { DropVictim :: Yes } else { DropVictim :: No }
19471968 }
19481969 (
19491970 ImplCandidate ( _)
@@ -1956,18 +1977,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
19561977 | TraitUpcastingUnsizeCandidate ( _)
19571978 | BuiltinCandidate { has_nested : true }
19581979 | TraitAliasCandidate ,
1959- ParamCandidate ( ref cand ) ,
1980+ ParamCandidate ( ref victim_cand ) ,
19601981 ) => {
19611982 // Prefer these to a global where-clause bound
19621983 // (see issue #50825).
1963- is_global ( cand) && other. evaluation . must_apply_modulo_regions ( )
1984+ if is_global ( victim_cand) && other. evaluation . must_apply_modulo_regions ( ) {
1985+ DropVictim :: Yes
1986+ } else {
1987+ DropVictim :: No
1988+ }
19641989 }
19651990
19661991 ( ProjectionCandidate ( i, _) , ProjectionCandidate ( j, _) )
19671992 | ( ObjectCandidate ( i) , ObjectCandidate ( j) ) => {
19681993 // Arbitrarily pick the lower numbered candidate for backwards
19691994 // compatibility reasons. Don't let this affect inference.
1970- i < j && !needs_infer
1995+ if i < j && !needs_infer { DropVictim :: Yes } else { DropVictim :: No }
19711996 }
19721997 ( ObjectCandidate ( _) , ProjectionCandidate ( ..) )
19731998 | ( ProjectionCandidate ( ..) , ObjectCandidate ( _) ) => {
@@ -1987,7 +2012,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
19872012 | TraitUpcastingUnsizeCandidate ( _)
19882013 | BuiltinCandidate { .. }
19892014 | TraitAliasCandidate ,
1990- ) => true ,
2015+ ) => DropVictim :: Yes ,
19912016
19922017 (
19932018 ImplCandidate ( ..)
@@ -2001,7 +2026,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
20012026 | BuiltinCandidate { .. }
20022027 | TraitAliasCandidate ,
20032028 ObjectCandidate ( _) | ProjectionCandidate ( ..) ,
2004- ) => false ,
2029+ ) => DropVictim :: No ,
20052030
20062031 ( & ImplCandidate ( other_def) , & ImplCandidate ( victim_def) ) => {
20072032 // See if we can toss out `victim` based on specialization.
@@ -2014,7 +2039,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
20142039 let tcx = self . tcx ( ) ;
20152040 if other. evaluation . must_apply_modulo_regions ( ) {
20162041 if tcx. specializes ( ( other_def, victim_def) ) {
2017- return true ;
2042+ return DropVictim :: Yes ;
20182043 }
20192044 }
20202045
@@ -2060,13 +2085,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
20602085 // will then correctly report an inference error, since the
20612086 // existence of multiple marker trait impls tells us nothing
20622087 // about which one should actually apply.
2063- ! needs_infer
2088+ if needs_infer { DropVictim :: No } else { DropVictim :: Yes }
20642089 }
2065- Some ( _) => true ,
2066- None => false ,
2090+ Some ( _) => DropVictim :: Yes ,
2091+ None => DropVictim :: No ,
20672092 }
20682093 } else {
2069- false
2094+ DropVictim :: No
20702095 }
20712096 }
20722097
@@ -2092,10 +2117,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
20922117 | TraitUpcastingUnsizeCandidate ( _)
20932118 | BuiltinCandidate { has_nested : true }
20942119 | TraitAliasCandidate ,
2095- ) => false ,
2120+ ) => DropVictim :: No ,
20962121 }
20972122 }
2123+ }
20982124
2125+ impl < ' tcx > SelectionContext < ' _ , ' tcx > {
20992126 fn sized_conditions (
21002127 & mut self ,
21012128 obligation : & TraitObligation < ' tcx > ,
0 commit comments