]> git.lizzy.rs Git - rust.git/commitdiff
Add support for all integer types
authorvarkor <github@varkor.com>
Sat, 19 May 2018 20:57:25 +0000 (21:57 +0100)
committervarkor <github@varkor.com>
Thu, 16 Aug 2018 19:09:04 +0000 (20:09 +0100)
src/librustc_mir/hair/pattern/_match.rs

index 4460587c614df0a8383f7ae372677cf3917b7104..670e0b1fef5e5e37eff2507f36ef0e83cb7e64a9 100644 (file)
@@ -457,13 +457,52 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
                 .map(|v| Variant(v.did))
                 .collect()
         }
-        ty::TyUint(ast::UintTy::Usize) => {
+        ty::TyChar => {
+            let (min, max) = (0u128, char::MAX as u128);
             return (vec![
-                ConstantRange(ty::Const::from_usize(cx.tcx, 0),
-                              ty::Const::from_usize(cx.tcx, 100),
-                              RangeEnd::Excluded),
+                ConstantRange(ty::Const::from_bits(cx.tcx, min, cx.tcx.types.char),
+                              ty::Const::from_bits(cx.tcx, max, cx.tcx.types.char),
+                              RangeEnd::Included),
             ], true)
         }
+        ty::TyInt(int_ty) => {
+            use syntax::ast::IntTy::*;
+            let (min, max, ty) = match int_ty {
+                Isize => (isize::MIN as i128, isize::MAX as i128, cx.tcx.types.isize),
+                I8    => (   i8::MIN as i128,    i8::MAX as i128, cx.tcx.types.i8),
+                I16   => (  i16::MIN as i128,   i16::MAX as i128, cx.tcx.types.i16),
+                I32   => (  i32::MIN as i128,   i32::MAX as i128, cx.tcx.types.i32),
+                I64   => (  i64::MIN as i128,   i64::MAX as i128, cx.tcx.types.i64),
+                I128  => ( i128::MIN as i128,  i128::MAX as i128, cx.tcx.types.i128),
+            };
+            return (vec![
+                ConstantRange(
+                    ty::Const::from_bits(cx.tcx, unsafe {
+                        transmute::<i128, u128>(min)
+                    }, ty),
+                    ty::Const::from_bits(cx.tcx, unsafe {
+                        transmute::<i128, u128>(max)
+                    }, ty),
+                    RangeEnd::Included
+                ),
+            ], true);
+        }
+        ty::TyUint(uint_ty) => {
+            use syntax::ast::UintTy::*;
+            let (min, (max, ty)) = (0u128, match uint_ty {
+                Usize => (usize::MAX as u128, cx.tcx.types.usize),
+                U8    => (   u8::MAX as u128, cx.tcx.types.u8),
+                U16   => (  u16::MAX as u128, cx.tcx.types.u16),
+                U32   => (  u32::MAX as u128, cx.tcx.types.u32),
+                U64   => (  u64::MAX as u128, cx.tcx.types.u64),
+                U128  => ( u128::MAX as u128, cx.tcx.types.u128),
+            });
+            return (vec![
+                ConstantRange(ty::Const::from_bits(cx.tcx, min, ty),
+                              ty::Const::from_bits(cx.tcx, max, ty),
+                              RangeEnd::Included),
+            ], true);
+        }
         _ => {
             if cx.is_uninhabited(pcx.ty) {
                 vec![]
@@ -666,26 +705,27 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
         let (all_ctors, _ranged) = all_constructors(cx, pcx);
         debug!("all_ctors = {:#?}", all_ctors);
 
-        fn to_inc_range_pair<'tcx>(tcx: TyCtxt<'_, '_, '_>, ctor: &Constructor<'tcx>) -> Option<(u64, u64)> {
+        fn to_inc_range_pair<'tcx>(_tcx: TyCtxt<'_, '_, '_>, ctor: &Constructor<'tcx>) -> Option<(u128, u128, Ty<'tcx>)> {
             match ctor {
                 Single | Variant(_) | Slice(_) => {
                     None
                 }
                 ConstantValue(const_) => {
-                    if let Some(val) = const_.assert_usize(tcx) {
-                        return Some((val, val));
+                    if let Some(val) = const_.assert_bits(const_.ty) {
+                        return Some((val, val, const_.ty));
                     }
                     None
                 }
                 ConstantRange(lo, hi, end) => {
-                    if let Some(lo) = lo.assert_usize(tcx) {
-                        if let Some(hi) = hi.assert_usize(tcx) {
+                    let ty = lo.ty;
+                    if let Some(lo) = lo.assert_bits(lo.ty) {
+                        if let Some(hi) = hi.assert_bits(hi.ty) {
                             if lo > hi || lo == hi && end == &RangeEnd::Excluded {
                                 return None;
                             } else if end == &RangeEnd::Included {
-                                return Some((lo, hi));
+                                return Some((lo, hi, ty));
                             } else {
-                                return Some((lo, hi - 1));
+                                return Some((lo, hi - 1, ty));
                             }
                         }
                     }
@@ -700,12 +740,14 @@ fn intersect<'a, 'tcx>(
                     ranges: Vec<Constructor<'tcx>>,
                      ctor: &Constructor<'tcx>)
                      -> (Vec<Constructor<'tcx>>, bool) {
-            if let Some((lo1, hi1)) = to_inc_range_pair(cx.tcx, ctor) {
+            if let Some((lo1, hi1, ty)) = to_inc_range_pair(cx.tcx, ctor) {
                 let mut ctor_was_useful = false;
                 // values only consists of ranges
                 let mut new_ranges = vec![];
                 let mut ranges: Vec<_> =
-                    ranges.into_iter().filter_map(|r| to_inc_range_pair(cx.tcx, &r)).collect();
+                    ranges.into_iter().filter_map(|r| {
+                        to_inc_range_pair(cx.tcx, &r).map(|(lo, hi, _)| (lo, hi))
+                    }).collect();
                 while let Some((lo2, hi2)) = ranges.pop() {
                     // eprintln!("{:?} {:?}", (lo2, hi2), (lo1, hi1));
                     if lo1 <= lo2 && hi1 >= hi2 {
@@ -745,9 +787,9 @@ fn intersect<'a, 'tcx>(
                 }
                 // transform ranges to proper format
                 (new_ranges.into_iter().map(|(lo, hi)| {
-                    ConstantRange(ty::Const::from_usize(cx.tcx, lo),
-                                ty::Const::from_usize(cx.tcx, hi),
-                                RangeEnd::Included)
+                    ConstantRange(ty::Const::from_bits(cx.tcx, lo, ty),
+                                  ty::Const::from_bits(cx.tcx, hi, ty),
+                                  RangeEnd::Included)
                 }).collect(), ctor_was_useful)
             } else {
                 (ranges, false)