]> git.lizzy.rs Git - rust.git/commitdiff
Refactor to remove explicit integer type matching
authorvarkor <github@varkor.com>
Tue, 22 May 2018 17:23:30 +0000 (18:23 +0100)
committervarkor <github@varkor.com>
Thu, 16 Aug 2018 19:09:05 +0000 (20:09 +0100)
src/librustc_mir/hair/pattern/_match.rs

index 3f483dfee55b539bb2b48f818865d4290bae66e2..281dc624a62aabeacecb89f80d9ed3c2b90f80c9 100644 (file)
@@ -138,7 +138,6 @@ fn from_iter<T: IntoIterator<Item=Vec<&'a Pattern<'tcx>>>>(iter: T) -> Self
     }
 }
 
-//NOTE: appears to be the only place other then InferCtxt to contain a ParamEnv
 pub struct MatchCheckCtxt<'a, 'tcx: 'a> {
     pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
     /// The module in which the match occurs. This is necessary for
@@ -470,48 +469,24 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
                 ConstantRange(endpoint('\u{E000}'), endpoint('\u{10FFFF}'), RangeEnd::Included),
             ]
         }
-        ty::TyInt(int_ty) if exhaustive_integer_patterns => {
-            use syntax::ast::IntTy::*;
-            let min_max_ty = |sty| {
-                let size = cx.tcx.layout_of(ty::ParamEnv::reveal_all().and(sty))
-                                  .unwrap().size.bits() as i128;
-                let min = (1i128 << (size - 1)).wrapping_neg();
-                let max = (1i128 << (size - 1)).wrapping_sub(1);
-                (min as u128, max as u128, sty)
-            };
-            let (min, max, ty) = match int_ty {
-                Isize => min_max_ty(cx.tcx.types.isize),
-                I8    => min_max_ty(cx.tcx.types.i8),
-                I16   => min_max_ty(cx.tcx.types.i16),
-                I32   => min_max_ty(cx.tcx.types.i32),
-                I64   => min_max_ty(cx.tcx.types.i64),
-                I128  => min_max_ty(cx.tcx.types.i128),
-            };
+        ty::TyInt(_) if exhaustive_integer_patterns => {
+            let size = cx.tcx.layout_of(ty::ParamEnv::reveal_all().and(pcx.ty))
+                             .unwrap().size.bits() as i128;
+            let min = (1i128 << (size - 1)).wrapping_neg();
+            let max = (1i128 << (size - 1)).wrapping_sub(1);
             value_constructors = true;
-            vec![ConstantRange(ty::Const::from_bits(cx.tcx, minty),
-                               ty::Const::from_bits(cx.tcx, maxty),
+            vec![ConstantRange(ty::Const::from_bits(cx.tcx, min as u128, pcx.ty),
+                               ty::Const::from_bits(cx.tcx, max as u128, pcx.ty),
                                RangeEnd::Included)]
         }
-        ty::TyUint(uint_ty) if exhaustive_integer_patterns => {
-            use syntax::ast::UintTy::*;
-            let min_max_ty = |sty| {
-                let size = cx.tcx.layout_of(ty::ParamEnv::reveal_all().and(sty))
-                                  .unwrap().size.bits() as u32;
-                let shift = 1u128.overflowing_shl(size);
-                let max = shift.0.wrapping_sub(1 + (shift.1 as u128));
-                (0u128, max as u128, sty)
-            };
-            let (min, max, ty) = match uint_ty {
-                Usize => min_max_ty(cx.tcx.types.usize),
-                U8    => min_max_ty(cx.tcx.types.u8),
-                U16   => min_max_ty(cx.tcx.types.u16),
-                U32   => min_max_ty(cx.tcx.types.u32),
-                U64   => min_max_ty(cx.tcx.types.u64),
-                U128  => min_max_ty(cx.tcx.types.u128),
-            };
+        ty::TyUint(_) if exhaustive_integer_patterns => {
+            let size = cx.tcx.layout_of(ty::ParamEnv::reveal_all().and(pcx.ty))
+                             .unwrap().size.bits() as u32;
+            let shift = 1u128.overflowing_shl(size);
+            let max = shift.0.wrapping_sub(1 + (shift.1 as u128));
             value_constructors = true;
-            vec![ConstantRange(ty::Const::from_bits(cx.tcx, min, ty),
-                               ty::Const::from_bits(cx.tcx, maxty),
+            vec![ConstantRange(ty::Const::from_bits(cx.tcx, 0u128, pcx.ty),
+                               ty::Const::from_bits(cx.tcx, max as u128, pcx.ty),
                                RangeEnd::Included)]
         }
         _ => {
@@ -643,7 +618,7 @@ fn from_ctor(ctor: &Constructor<'tcx>) -> Option<Interval<'tcx>> {
                     if let Some(hi) = hi.assert_bits(ty) {
                         // Perform a shift if the underlying types are signed,
                         // which makes the interval arithmetic simpler.
-                        let (lo, hi) = Interval::offset_sign(ty, (lo, hi), true);
+                        let (lo, hi) = Interval::offset_sign(ty, lo..=hi, true);
                         // Make sure the interval is well-formed.
                         return if lo > hi || lo == hi && *end == RangeEnd::Excluded {
                             None
@@ -665,7 +640,8 @@ fn from_ctor(ctor: &Constructor<'tcx>) -> Option<Interval<'tcx>> {
         }
     }
 
-    fn offset_sign(ty: Ty<'tcx>, (lo, hi): (u128, u128), forwards: bool) -> (u128, u128) {
+    fn offset_sign(ty: Ty<'tcx>, range: RangeInclusive<u128>, forwards: bool) -> (u128, u128) {
+        let (lo, hi) = range.into_inner();
         use syntax::ast::IntTy::*;
         match ty.sty {
             ty::TyInt(int_ty) => {
@@ -720,23 +696,23 @@ fn ranges_subtract_pattern<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
             if pat_interval_lo > subrange_hi || subrange_lo > pat_interval_hi  {
                 // The pattern doesn't intersect with the subrange at all,
                 // so the subrange remains untouched.
-                remaining_ranges.push((subrange_lo, subrange_hi));
+                remaining_ranges.push(subrange_lo..=subrange_hi);
             } else {
                 if pat_interval_lo > subrange_lo {
                     // The pattern intersects an upper section of the
                     // subrange, so a lower section will remain.
-                    remaining_ranges.push((subrange_lo, pat_interval_lo - 1));
+                    remaining_ranges.push(subrange_lo..=(pat_interval_lo - 1));
                 }
                 if pat_interval_hi < subrange_hi {
                     // The pattern intersects a lower section of the
                     // subrange, so an upper section will remain.
-                    remaining_ranges.push((pat_interval_hi + 1, subrange_hi));
+                    remaining_ranges.push((pat_interval_hi + 1)..=subrange_hi);
                 }
             }
         }
         // Convert the remaining ranges from pairs to inclusive `ConstantRange`s.
-        remaining_ranges.into_iter().map(|(lo, hi)| {
-            let (lo, hi) = Interval::offset_sign(ty, (lo, hi), false);
+        remaining_ranges.into_iter().map(|r| {
+            let (lo, hi) = Interval::offset_sign(ty, r, false);
             ConstantRange(ty::Const::from_bits(cx.tcx, lo, ty),
                           ty::Const::from_bits(cx.tcx, hi, ty),
                           RangeEnd::Included)