@@ -834,13 +834,6 @@ enum Constructor<'tcx> {
834834}
835835
836836impl < ' tcx > Constructor < ' tcx > {
837- fn is_slice ( & self ) -> bool {
838- match self {
839- Slice ( _) => true ,
840- _ => false ,
841- }
842- }
843-
844837 fn variant_index_for_adt < ' a > (
845838 & self ,
846839 cx : & MatchCheckCtxt < ' a , ' tcx > ,
@@ -2111,7 +2104,10 @@ fn pat_constructor<'tcx>(
21112104 if let Some ( int_range) = IntRange :: from_const ( tcx, param_env, value, pat. span ) {
21122105 Some ( IntRange ( int_range) )
21132106 } else {
2114- Some ( ConstantValue ( value) )
2107+ match value. ty . kind ( ) {
2108+ ty:: Float ( _) => Some ( FloatRange ( value, value, RangeEnd :: Included ) ) ,
2109+ _ => Some ( ConstantValue ( value) ) ,
2110+ }
21152111 }
21162112 }
21172113 PatKind :: Range ( PatRange { lo, hi, end } ) => {
@@ -2443,35 +2439,6 @@ fn lint_overlapping_patterns<'tcx>(
24432439 }
24442440}
24452441
2446- fn constructor_covered_by_range < ' tcx > (
2447- tcx : TyCtxt < ' tcx > ,
2448- param_env : ty:: ParamEnv < ' tcx > ,
2449- ctor : & Constructor < ' tcx > ,
2450- pat : & Pat < ' tcx > ,
2451- ) -> Option < ( ) > {
2452- if let Single = ctor {
2453- return Some ( ( ) ) ;
2454- }
2455-
2456- let ( pat_from, pat_to, pat_end, ty) = match * pat. kind {
2457- PatKind :: Constant { value } => ( value, value, RangeEnd :: Included , value. ty ) ,
2458- PatKind :: Range ( PatRange { lo, hi, end } ) => ( lo, hi, end, lo. ty ) ,
2459- _ => bug ! ( "`constructor_covered_by_range` called with {:?}" , pat) ,
2460- } ;
2461- let ( ctor_from, ctor_to, ctor_end) = match * ctor {
2462- ConstantValue ( value) => ( value, value, RangeEnd :: Included ) ,
2463- FloatRange ( from, to, ctor_end) => ( from, to, ctor_end) ,
2464- _ => bug ! ( "`constructor_covered_by_range` called with {:?}" , ctor) ,
2465- } ;
2466- trace ! ( "constructor_covered_by_range {:#?}, {:#?}, {:#?}, {}" , ctor, pat_from, pat_to, ty) ;
2467-
2468- let to = compare_const_vals ( tcx, ctor_to, pat_to, param_env, ty) ?;
2469- let from = compare_const_vals ( tcx, ctor_from, pat_from, param_env, ty) ?;
2470- let intersects = ( from == Ordering :: Greater || from == Ordering :: Equal )
2471- && ( to == Ordering :: Less || ( pat_end == ctor_end && to == Ordering :: Equal ) ) ;
2472- if intersects { Some ( ( ) ) } else { None }
2473- }
2474-
24752442/// This is the main specialization step. It expands the pattern
24762443/// into `arity` patterns based on the constructor. For most patterns, the step is trivial,
24772444/// for instance tuple patterns are flattened and box patterns expand into their inner pattern.
@@ -2516,27 +2483,51 @@ fn specialize_one_pattern<'p, 'tcx>(
25162483
25172484 PatKind :: Deref { ref subpattern } => Some ( Fields :: from_single_pattern ( subpattern) ) ,
25182485
2519- PatKind :: Constant { value } if constructor. is_slice ( ) => {
2520- span_bug ! ( pat. span, "unexpected const-val {:?} with ctor {:?}" , value, constructor)
2521- }
2522-
25232486 PatKind :: Constant { .. } | PatKind :: Range { .. } => {
2524- // If the constructor is a:
2525- // - Single value: add a row if the pattern contains the constructor.
2526- // - Range: add a row if the constructor intersects the pattern.
2527- if let IntRange ( ctor) = constructor {
2528- let pat = IntRange :: from_pat ( cx. tcx , cx. param_env , pat) ?;
2529- ctor. intersection ( cx. tcx , & pat) ?;
2530- // Constructor splitting should ensure that all intersections we encounter
2531- // are actually inclusions.
2532- assert ! ( ctor. is_subrange( & pat) ) ;
2533- } else {
2534- // Fallback for non-ranges and ranges that involve
2535- // floating-point numbers, which are not conveniently handled
2536- // by `IntRange`. For these cases, the constructor may not be a
2537- // range so intersection actually devolves into being covered
2538- // by the pattern.
2539- constructor_covered_by_range ( cx. tcx , cx. param_env , constructor, pat) ?;
2487+ match constructor {
2488+ Single => { }
2489+ IntRange ( ctor) => {
2490+ let pat = IntRange :: from_pat ( cx. tcx , cx. param_env , pat) ?;
2491+ ctor. intersection ( cx. tcx , & pat) ?;
2492+ // Constructor splitting should ensure that all intersections we encounter
2493+ // are actually inclusions.
2494+ assert ! ( ctor. is_subrange( & pat) ) ;
2495+ }
2496+ FloatRange ( ctor_from, ctor_to, ctor_end) => {
2497+ let ( pat_from, pat_to, pat_end, ty) = match * pat. kind {
2498+ PatKind :: Constant { value } => ( value, value, RangeEnd :: Included , value. ty ) ,
2499+ PatKind :: Range ( PatRange { lo, hi, end } ) => ( lo, hi, end, lo. ty ) ,
2500+ _ => unreachable ! ( ) , // This is ensured by the branch we're in
2501+ } ;
2502+ let to = compare_const_vals ( cx. tcx , ctor_to, pat_to, cx. param_env , ty) ?;
2503+ let from = compare_const_vals ( cx. tcx , ctor_from, pat_from, cx. param_env , ty) ?;
2504+ let intersects = ( from == Ordering :: Greater || from == Ordering :: Equal )
2505+ && ( to == Ordering :: Less
2506+ || ( pat_end == * ctor_end && to == Ordering :: Equal ) ) ;
2507+ if !intersects {
2508+ return None ;
2509+ }
2510+ }
2511+ ConstantValue ( ctor_value) => {
2512+ let pat_value = match * pat. kind {
2513+ PatKind :: Constant { value } => value,
2514+ _ => span_bug ! (
2515+ pat. span,
2516+ "unexpected range pattern {:?} for constant value ctor" ,
2517+ pat
2518+ ) ,
2519+ } ;
2520+
2521+ // FIXME: there's probably a more direct way of comparing for equality
2522+ if compare_const_vals ( cx. tcx , ctor_value, pat_value, cx. param_env , pat. ty ) ?
2523+ != Ordering :: Equal
2524+ {
2525+ return None ;
2526+ }
2527+ }
2528+ _ => {
2529+ span_bug ! ( pat. span, "unexpected pattern {:?} with ctor {:?}" , pat, constructor)
2530+ }
25402531 }
25412532 Some ( Fields :: empty ( ) )
25422533 }
0 commit comments