@@ -1940,52 +1940,55 @@ fn slice_pat_covered_by_const<'tcx>(
1940
1940
// This has a single call site that can be hot
1941
1941
#[ inline( always) ]
1942
1942
fn constructor_intersects_pattern < ' p , ' tcx > (
1943
- tcx : TyCtxt < ' tcx > ,
1944
- param_env : ty:: ParamEnv < ' tcx > ,
1943
+ cx : & MatchCheckCtxt < ' _ , ' tcx > ,
1945
1944
ctor : & Constructor < ' tcx > ,
1946
1945
pat : & ' p Pat < ' tcx > ,
1947
1946
) -> Option < PatStack < ' p , ' tcx > > {
1948
1947
trace ! ( "constructor_intersects_pattern {:#?}, {:#?}" , ctor, pat) ;
1949
- if let Single = ctor {
1950
- Some ( PatStack :: default ( ) )
1951
- } else if let IntRange ( ctor) = ctor {
1952
- let pat = match * pat. kind {
1953
- PatKind :: Constant { value } => IntRange :: from_const ( tcx, param_env, value) ?,
1954
- PatKind :: Range ( PatRange { lo, hi, end } ) => {
1955
- IntRange :: from_range ( tcx, param_env, lo, hi, & end) ?
1956
- }
1957
- _ => bug ! ( "`constructor_intersects_pattern` called with {:?}" , pat) ,
1958
- } ;
1948
+ match ctor {
1949
+ Single => Some ( PatStack :: default ( ) ) ,
1950
+ IntRange ( ctor) => {
1951
+ let pat = match * pat. kind {
1952
+ PatKind :: Constant { value } => IntRange :: from_const ( cx . tcx , cx . param_env , value) ?,
1953
+ PatKind :: Range ( PatRange { lo, hi, end } ) => {
1954
+ IntRange :: from_range ( cx . tcx , cx . param_env , lo, hi, & end) ?
1955
+ }
1956
+ _ => bug ! ( "`constructor_intersects_pattern` called with {:?}" , pat) ,
1957
+ } ;
1959
1958
1960
- ctor. intersection ( tcx, & pat) ?;
1961
-
1962
- // Constructor splitting should ensure that all intersections we encounter are actually
1963
- // inclusions.
1964
- let ( pat_lo, pat_hi) = pat. range . into_inner ( ) ;
1965
- let ( ctor_lo, ctor_hi) = ctor. range . clone ( ) . into_inner ( ) ;
1966
- assert ! ( pat_lo <= ctor_lo && ctor_hi <= pat_hi) ;
1967
-
1968
- Some ( PatStack :: default ( ) )
1969
- } else {
1970
- // Fallback for non-ranges and ranges that involve floating-point numbers, which are not
1971
- // conveniently handled by `IntRange`. For these cases, the constructor may not be a range
1972
- // so intersection actually devolves into being covered by the pattern.
1973
- let ( pat_from, pat_to, pat_end) = match * pat. kind {
1974
- PatKind :: Constant { value } => ( value, value, RangeEnd :: Included ) ,
1975
- PatKind :: Range ( PatRange { lo, hi, end } ) => ( lo, hi, end) ,
1976
- _ => bug ! ( "`constructor_intersects_pattern` called with {:?}" , pat) ,
1977
- } ;
1978
- let ( ctor_from, ctor_to, ctor_end) = match * ctor {
1979
- ConstantValue ( value) => ( value, value, RangeEnd :: Included ) ,
1980
- ConstantRange ( from, to, range_end) => ( from, to, range_end) ,
1981
- _ => bug ! ( "`constructor_intersects_pattern` called with {:?}" , ctor) ,
1982
- } ;
1983
- let order_to = compare_const_vals ( tcx, ctor_to, pat_to, param_env, pat_from. ty ) ?;
1984
- let order_from = compare_const_vals ( tcx, ctor_from, pat_from, param_env, pat_from. ty ) ?;
1985
- let included = ( order_from != Ordering :: Less )
1986
- && ( ( order_to == Ordering :: Less )
1987
- || ( pat_end == ctor_end && order_to == Ordering :: Equal ) ) ;
1988
- if included { Some ( PatStack :: default ( ) ) } else { None }
1959
+ ctor. intersection ( cx. tcx , & pat) ?;
1960
+
1961
+ // Constructor splitting should ensure that all intersections we encounter are actually
1962
+ // inclusions.
1963
+ let ( pat_lo, pat_hi) = pat. range . into_inner ( ) ;
1964
+ let ( ctor_lo, ctor_hi) = ctor. range . clone ( ) . into_inner ( ) ;
1965
+ assert ! ( pat_lo <= ctor_lo && ctor_hi <= pat_hi) ;
1966
+
1967
+ Some ( PatStack :: default ( ) )
1968
+ }
1969
+ ConstantValue ( ..) | ConstantRange ( ..) => {
1970
+ // Fallback for non-ranges and ranges that involve floating-point numbers, which are
1971
+ // not conveniently handled by `IntRange`. For these cases, the constructor may not be
1972
+ // a range so intersection actually devolves into being covered by the pattern.
1973
+ let ( pat_from, pat_to, pat_end) = match * pat. kind {
1974
+ PatKind :: Constant { value } => ( value, value, RangeEnd :: Included ) ,
1975
+ PatKind :: Range ( PatRange { lo, hi, end } ) => ( lo, hi, end) ,
1976
+ _ => bug ! ( "`constructor_intersects_pattern` called with {:?}" , pat) ,
1977
+ } ;
1978
+ let ( ctor_from, ctor_to, ctor_end) = match * ctor {
1979
+ ConstantValue ( value) => ( value, value, RangeEnd :: Included ) ,
1980
+ ConstantRange ( from, to, range_end) => ( from, to, range_end) ,
1981
+ _ => bug ! ( ) ,
1982
+ } ;
1983
+ let order_to = compare_const_vals ( cx. tcx , ctor_to, pat_to, cx. param_env , pat_from. ty ) ?;
1984
+ let order_from =
1985
+ compare_const_vals ( cx. tcx , ctor_from, pat_from, cx. param_env , pat_from. ty ) ?;
1986
+ let included = ( order_from != Ordering :: Less )
1987
+ && ( ( order_to == Ordering :: Less )
1988
+ || ( pat_end == ctor_end && order_to == Ordering :: Equal ) ) ;
1989
+ if included { Some ( PatStack :: default ( ) ) } else { None }
1990
+ }
1991
+ _ => bug ! ( "`constructor_intersects_pattern` called with {:?}" , ctor) ,
1989
1992
}
1990
1993
}
1991
1994
@@ -2122,9 +2125,11 @@ fn specialize_one_pattern<'p, 'a: 'p, 'p2: 'p, 'tcx>(
2122
2125
// If the constructor is a:
2123
2126
// - Single value: add a row if the pattern contains the constructor.
2124
2127
// - Range: add a row if the constructor intersects the pattern.
2125
- constructor_intersects_pattern ( cx. tcx , cx. param_env , constructor, pat)
2126
- . into_iter ( )
2127
- . collect ( )
2128
+ if let Some ( ps) = constructor_intersects_pattern ( cx, constructor, pat) {
2129
+ smallvec ! [ ps]
2130
+ } else {
2131
+ smallvec ! [ ]
2132
+ }
2128
2133
}
2129
2134
2130
2135
PatKind :: Array { ref prefix, ref slice, ref suffix }
0 commit comments