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