@@ -1940,52 +1940,55 @@ fn slice_pat_covered_by_const<'tcx>(
19401940// This has a single call site that can be hot
19411941#[ inline( always) ]
19421942fn constructor_intersects_pattern < ' p , ' tcx > (
1943- tcx : TyCtxt < ' tcx > ,
1944- param_env : ty:: ParamEnv < ' tcx > ,
1943+ cx : & MatchCheckCtxt < ' _ , ' tcx > ,
19451944 ctor : & Constructor < ' tcx > ,
19461945 pat : & ' p Pat < ' tcx > ,
19471946) -> Option < PatStack < ' p , ' tcx > > {
19481947 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+ } ;
19591958
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) ,
19891992 }
19901993}
19911994
@@ -2122,9 +2125,11 @@ fn specialize_one_pattern<'p, 'a: 'p, 'p2: 'p, 'tcx>(
21222125 // If the constructor is a:
21232126 // - Single value: add a row if the pattern contains the constructor.
21242127 // - 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+ }
21282133 }
21292134
21302135 PatKind :: Array { ref prefix, ref slice, ref suffix }
0 commit comments