@@ -834,13 +834,6 @@ enum Constructor<'tcx> {
834
834
}
835
835
836
836
impl < ' tcx > Constructor < ' tcx > {
837
- fn is_slice ( & self ) -> bool {
838
- match self {
839
- Slice ( _) => true ,
840
- _ => false ,
841
- }
842
- }
843
-
844
837
fn variant_index_for_adt < ' a > (
845
838
& self ,
846
839
cx : & MatchCheckCtxt < ' a , ' tcx > ,
@@ -2111,7 +2104,10 @@ fn pat_constructor<'tcx>(
2111
2104
if let Some ( int_range) = IntRange :: from_const ( tcx, param_env, value, pat. span ) {
2112
2105
Some ( IntRange ( int_range) )
2113
2106
} else {
2114
- Some ( ConstantValue ( value) )
2107
+ match value. ty . kind ( ) {
2108
+ ty:: Float ( _) => Some ( FloatRange ( value, value, RangeEnd :: Included ) ) ,
2109
+ _ => Some ( ConstantValue ( value) ) ,
2110
+ }
2115
2111
}
2116
2112
}
2117
2113
PatKind :: Range ( PatRange { lo, hi, end } ) => {
@@ -2443,35 +2439,6 @@ fn lint_overlapping_patterns<'tcx>(
2443
2439
}
2444
2440
}
2445
2441
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
-
2475
2442
/// This is the main specialization step. It expands the pattern
2476
2443
/// into `arity` patterns based on the constructor. For most patterns, the step is trivial,
2477
2444
/// for instance tuple patterns are flattened and box patterns expand into their inner pattern.
@@ -2516,27 +2483,51 @@ fn specialize_one_pattern<'p, 'tcx>(
2516
2483
2517
2484
PatKind :: Deref { ref subpattern } => Some ( Fields :: from_single_pattern ( subpattern) ) ,
2518
2485
2519
- PatKind :: Constant { value } if constructor. is_slice ( ) => {
2520
- span_bug ! ( pat. span, "unexpected const-val {:?} with ctor {:?}" , value, constructor)
2521
- }
2522
-
2523
2486
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
+ }
2540
2531
}
2541
2532
Some ( Fields :: empty ( ) )
2542
2533
}
0 commit comments