@@ -211,7 +211,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
211
211
pub fn new ( infcx : & ' cx InferCtxt < ' tcx > ) -> SelectionContext < ' cx , ' tcx > {
212
212
SelectionContext {
213
213
infcx,
214
- freshener : infcx. freshener_keep_static ( ) ,
214
+ freshener : infcx. freshener ( ) ,
215
215
intercrate_ambiguity_causes : None ,
216
216
query_mode : TraitQueryMode :: Standard ,
217
217
}
@@ -769,14 +769,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
769
769
}
770
770
771
771
ty:: PredicateKind :: Clause ( ty:: Clause :: TypeOutlives ( pred) ) => {
772
- // A global type with no late-bound regions can only
773
- // contain the "'static" lifetime (any other lifetime
774
- // would either be late-bound or local), so it is guaranteed
775
- // to outlive any other lifetime
776
- if pred . 0 . is_global ( ) && ! pred. 0 . has_late_bound_vars ( ) {
777
- Ok ( EvaluatedToOk )
778
- } else {
772
+ // A global type with no free lifetimes or generic parameters
773
+ // outlives anything.
774
+ if pred . 0 . has_free_regions ( )
775
+ || pred . 0 . has_late_bound_regions ( )
776
+ || pred. 0 . has_non_region_infer ( )
777
+ || pred . 0 . has_non_region_infer ( )
778
+ {
779
779
Ok ( EvaluatedToOkModuloRegions )
780
+ } else {
781
+ Ok ( EvaluatedToOk )
780
782
}
781
783
}
782
784
@@ -1824,6 +1826,12 @@ enum DropVictim {
1824
1826
No ,
1825
1827
}
1826
1828
1829
+ impl DropVictim {
1830
+ fn drop_if ( should_drop : bool ) -> DropVictim {
1831
+ if should_drop { DropVictim :: Yes } else { DropVictim :: No }
1832
+ }
1833
+ }
1834
+
1827
1835
/// ## Winnowing
1828
1836
///
1829
1837
/// Winnowing is the process of attempting to resolve ambiguity by
@@ -1889,11 +1897,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
1889
1897
// or the current one if tied (they should both evaluate to the same answer). This is
1890
1898
// probably best characterized as a "hack", since we might prefer to just do our
1891
1899
// best to *not* create essentially duplicate candidates in the first place.
1892
- if other. bound_vars ( ) . len ( ) <= victim. bound_vars ( ) . len ( ) {
1893
- DropVictim :: Yes
1894
- } else {
1895
- DropVictim :: No
1896
- }
1900
+ DropVictim :: drop_if ( other. bound_vars ( ) . len ( ) <= victim. bound_vars ( ) . len ( ) )
1897
1901
} else if other. skip_binder ( ) . trait_ref == victim. skip_binder ( ) . trait_ref
1898
1902
&& victim. skip_binder ( ) . constness == ty:: BoundConstness :: NotConst
1899
1903
&& other. skip_binder ( ) . polarity == victim. skip_binder ( ) . polarity
@@ -1923,17 +1927,13 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
1923
1927
| ObjectCandidate ( _)
1924
1928
| ProjectionCandidate ( ..) ,
1925
1929
) => {
1926
- if is_global ( other_cand) {
1927
- DropVictim :: No
1928
- } else {
1929
- // We have a where clause so don't go around looking
1930
- // for impls. Arbitrarily give param candidates priority
1931
- // over projection and object candidates.
1932
- //
1933
- // Global bounds from the where clause should be ignored
1934
- // here (see issue #50825).
1935
- DropVictim :: Yes
1936
- }
1930
+ // We have a where clause so don't go around looking
1931
+ // for impls. Arbitrarily give param candidates priority
1932
+ // over projection and object candidates.
1933
+ //
1934
+ // Global bounds from the where clause should be ignored
1935
+ // here (see issue #50825).
1936
+ DropVictim :: drop_if ( !is_global ( other_cand) )
1937
1937
}
1938
1938
( ObjectCandidate ( _) | ProjectionCandidate ( ..) , ParamCandidate ( ref victim_cand) ) => {
1939
1939
// Prefer these to a global where-clause bound
@@ -1955,18 +1955,16 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
1955
1955
) => {
1956
1956
// Prefer these to a global where-clause bound
1957
1957
// (see issue #50825).
1958
- if is_global ( victim_cand) && other. evaluation . must_apply_modulo_regions ( ) {
1959
- DropVictim :: Yes
1960
- } else {
1961
- DropVictim :: No
1962
- }
1958
+ DropVictim :: drop_if (
1959
+ is_global ( victim_cand) && other. evaluation . must_apply_modulo_regions ( ) ,
1960
+ )
1963
1961
}
1964
1962
1965
1963
( ProjectionCandidate ( i, _) , ProjectionCandidate ( j, _) )
1966
1964
| ( ObjectCandidate ( i) , ObjectCandidate ( j) ) => {
1967
1965
// Arbitrarily pick the lower numbered candidate for backwards
1968
1966
// compatibility reasons. Don't let this affect inference.
1969
- if i < j && !needs_infer { DropVictim :: Yes } else { DropVictim :: No }
1967
+ DropVictim :: drop_if ( i < j && !needs_infer)
1970
1968
}
1971
1969
( ObjectCandidate ( _) , ProjectionCandidate ( ..) )
1972
1970
| ( ProjectionCandidate ( ..) , ObjectCandidate ( _) ) => {
@@ -2017,55 +2015,65 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
2017
2015
}
2018
2016
}
2019
2017
2020
- if other. evaluation . must_apply_considering_regions ( ) {
2021
- match tcx. impls_are_allowed_to_overlap ( other_def, victim_def) {
2022
- Some ( ty:: ImplOverlapKind :: Permitted { marker : true } ) => {
2023
- // Subtle: If the predicate we are evaluating has inference
2024
- // variables, do *not* allow discarding candidates due to
2025
- // marker trait impls.
2026
- //
2027
- // Without this restriction, we could end up accidentally
2028
- // constraining inference variables based on an arbitrarily
2029
- // chosen trait impl.
2030
- //
2031
- // Imagine we have the following code:
2032
- //
2033
- // ```rust
2034
- // #[marker] trait MyTrait {}
2035
- // impl MyTrait for u8 {}
2036
- // impl MyTrait for bool {}
2037
- // ```
2038
- //
2039
- // And we are evaluating the predicate `<_#0t as MyTrait>`.
2040
- //
2041
- // During selection, we will end up with one candidate for each
2042
- // impl of `MyTrait`. If we were to discard one impl in favor
2043
- // of the other, we would be left with one candidate, causing
2044
- // us to "successfully" select the predicate, unifying
2045
- // _#0t with (for example) `u8`.
2046
- //
2047
- // However, we have no reason to believe that this unification
2048
- // is correct - we've essentially just picked an arbitrary
2049
- // *possibility* for _#0t, and required that this be the *only*
2050
- // possibility.
2051
- //
2052
- // Eventually, we will either:
2053
- // 1) Unify all inference variables in the predicate through
2054
- // some other means (e.g. type-checking of a function). We will
2055
- // then be in a position to drop marker trait candidates
2056
- // without constraining inference variables (since there are
2057
- // none left to constrain)
2058
- // 2) Be left with some unconstrained inference variables. We
2059
- // will then correctly report an inference error, since the
2060
- // existence of multiple marker trait impls tells us nothing
2061
- // about which one should actually apply.
2062
- if needs_infer { DropVictim :: No } else { DropVictim :: Yes }
2063
- }
2064
- Some ( _) => DropVictim :: Yes ,
2065
- None => DropVictim :: No ,
2018
+ match tcx. impls_are_allowed_to_overlap ( other_def, victim_def) {
2019
+ // For #33140 the impl headers must be exactly equal, the trait must not have
2020
+ // any associated items and there are no where-clauses.
2021
+ //
2022
+ // We can just arbitrarily drop one of the impls.
2023
+ Some ( ty:: ImplOverlapKind :: Issue33140 ) => {
2024
+ assert_eq ! ( other. evaluation, victim. evaluation) ;
2025
+ DropVictim :: Yes
2066
2026
}
2067
- } else {
2068
- DropVictim :: No
2027
+ // For candidates which already reference errors it doesn't really
2028
+ // matter what we do 🤷
2029
+ Some ( ty:: ImplOverlapKind :: Permitted { marker : false } ) => {
2030
+ DropVictim :: drop_if ( other. evaluation . must_apply_considering_regions ( ) )
2031
+ }
2032
+ Some ( ty:: ImplOverlapKind :: Permitted { marker : true } ) => {
2033
+ // Subtle: If the predicate we are evaluating has inference
2034
+ // variables, do *not* allow discarding candidates due to
2035
+ // marker trait impls.
2036
+ //
2037
+ // Without this restriction, we could end up accidentally
2038
+ // constraining inference variables based on an arbitrarily
2039
+ // chosen trait impl.
2040
+ //
2041
+ // Imagine we have the following code:
2042
+ //
2043
+ // ```rust
2044
+ // #[marker] trait MyTrait {}
2045
+ // impl MyTrait for u8 {}
2046
+ // impl MyTrait for bool {}
2047
+ // ```
2048
+ //
2049
+ // And we are evaluating the predicate `<_#0t as MyTrait>`.
2050
+ //
2051
+ // During selection, we will end up with one candidate for each
2052
+ // impl of `MyTrait`. If we were to discard one impl in favor
2053
+ // of the other, we would be left with one candidate, causing
2054
+ // us to "successfully" select the predicate, unifying
2055
+ // _#0t with (for example) `u8`.
2056
+ //
2057
+ // However, we have no reason to believe that this unification
2058
+ // is correct - we've essentially just picked an arbitrary
2059
+ // *possibility* for _#0t, and required that this be the *only*
2060
+ // possibility.
2061
+ //
2062
+ // Eventually, we will either:
2063
+ // 1) Unify all inference variables in the predicate through
2064
+ // some other means (e.g. type-checking of a function). We will
2065
+ // then be in a position to drop marker trait candidates
2066
+ // without constraining inference variables (since there are
2067
+ // none left to constrain)
2068
+ // 2) Be left with some unconstrained inference variables. We
2069
+ // will then correctly report an inference error, since the
2070
+ // existence of multiple marker trait impls tells us nothing
2071
+ // about which one should actually apply.
2072
+ DropVictim :: drop_if (
2073
+ !needs_infer && other. evaluation . must_apply_considering_regions ( ) ,
2074
+ )
2075
+ }
2076
+ None => DropVictim :: No ,
2069
2077
}
2070
2078
}
2071
2079
0 commit comments