]> git.lizzy.rs Git - rust.git/commitdiff
Introduce signed_bias method
authorvarkor <github@varkor.com>
Thu, 24 May 2018 12:30:21 +0000 (13:30 +0100)
committervarkor <github@varkor.com>
Thu, 16 Aug 2018 19:09:05 +0000 (20:09 +0100)
The epitome of simplicity!

src/librustc_mir/hair/pattern/_match.rs

index e498b5582bf054d5d302d25ff6f977701971cec9..0d56f345d8eafeee0fd9c8c9e208baacc48e12e0 100644 (file)
 use rustc::hir::def_id::DefId;
 use rustc::hir::RangeEnd;
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
+use rustc::ty::layout::{Integer, IntegerExt};
 
 use rustc::mir::Field;
 use rustc::mir::interpret::ConstValue;
 use rustc::util::common::ErrorReported;
 
+use syntax::attr::{SignedInt, UnsignedInt};
 use syntax_pos::{Span, DUMMY_SP};
 
 use arena::TypedArena;
@@ -469,10 +471,9 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
                 ConstantRange(endpoint('\u{E000}'), endpoint('\u{10FFFF}'), RangeEnd::Included),
             ]
         }
-        ty::TyInt(_) if exhaustive_integer_patterns => {
+        ty::TyInt(ity) if exhaustive_integer_patterns => {
             // FIXME(49937): refactor these bit manipulations into interpret.
-            let bits = cx.tcx.layout_of(ty::ParamEnv::reveal_all().and(pcx.ty))
-                             .unwrap().size.bits() as u128;
+            let bits = Integer::from_attr(cx.tcx, SignedInt(ity)).size().bits() as u128;
             let min = 1u128 << (bits - 1);
             let max = (1u128 << (bits - 1)) - 1;
             value_constructors = true;
@@ -480,10 +481,9 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
                                ty::Const::from_bits(cx.tcx, max as u128, pcx.ty),
                                RangeEnd::Included)]
         }
-        ty::TyUint(_) if exhaustive_integer_patterns => {
+        ty::TyUint(uty) if exhaustive_integer_patterns => {
             // FIXME(49937): refactor these bit manipulations into interpret.
-            let bits = cx.tcx.layout_of(ty::ParamEnv::reveal_all().and(pcx.ty))
-                             .unwrap().size.bits() as u128;
+            let bits = Integer::from_attr(cx.tcx, UnsignedInt(uty)).size().bits() as u128;
             let max = !0u128 >> (128 - bits);
             value_constructors = true;
             vec![ConstantRange(ty::Const::from_bits(cx.tcx, 0, pcx.ty),
@@ -627,7 +627,8 @@ fn from_ctor(tcx: TyCtxt<'_, 'tcx, '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) = Self::encode(tcx, ty, (lo, hi));
+                        let bias = IntRange::signed_bias(tcx, ty);
+                        let (lo, hi) = (lo ^ bias, hi ^ bias);
                         // Make sure the interval is well-formed.
                         return if lo > hi || lo == hi && *end == RangeEnd::Excluded {
                             None
@@ -642,8 +643,9 @@ fn from_ctor(tcx: TyCtxt<'_, 'tcx, 'tcx>,
             ConstantValue(val) => {
                 let ty = val.ty;
                 if let Some(val) = val.assert_bits(ty) {
-                    let (lo, hi) = Self::encode(tcx, ty, (val, val));
-                    Some(IntRange { range: lo..=hi, ty })
+                    let bias = IntRange::signed_bias(tcx, ty);
+                    let val = val ^ bias;
+                    Some(IntRange { range: val..=val, ty })
                 } else {
                     None
                 }
@@ -654,46 +656,16 @@ fn from_ctor(tcx: TyCtxt<'_, 'tcx, 'tcx>,
         }
     }
 
-    fn encode(tcx: TyCtxt<'_, 'tcx, 'tcx>,
-              ty: Ty<'tcx>,
-              (lo, hi): (u128, u128))
-              -> (u128, u128) {
+    fn signed_bias(tcx: TyCtxt<'_, 'tcx, 'tcx>, ty: Ty<'tcx>) -> u128 {
         match ty.sty {
-            ty::TyInt(_) => {
-                // FIXME(49937): refactor these bit manipulations into interpret.
-                let bits = tcx.layout_of(ty::ParamEnv::reveal_all().and(ty))
-                              .unwrap().size.bits() as u128;
-                let min = 1u128 << (bits - 1);
-                let mask = !0u128 >> (128 - bits);
-                let offset = |x: u128| x.wrapping_sub(min) & mask;
-                (offset(lo), offset(hi))
+            ty::TyInt(ity) => {
+                let bits = Integer::from_attr(tcx, SignedInt(ity)).size().bits() as u128;
+                1u128 << (bits - 1)
             }
-            _ => (lo, hi)
+            _ => 0
         }
     }
 
-    fn decode(tcx: TyCtxt<'_, 'tcx, 'tcx>,
-              ty: Ty<'tcx>,
-              range: RangeInclusive<u128>)
-              -> Constructor<'tcx> {
-        let (lo, hi) = range.into_inner();
-        let (lo, hi) = match ty.sty {
-            ty::TyInt(_) => {
-                // FIXME(49937): refactor these bit manipulations into interpret.
-                let bits = tcx.layout_of(ty::ParamEnv::reveal_all().and(ty))
-                              .unwrap().size.bits() as u128;
-                let min = 1u128 << (bits - 1);
-                let mask = !0u128 >> (128 - bits);
-                let offset = |x: u128| x.wrapping_add(min) & mask;
-                (offset(lo), offset(hi))
-            }
-            _ => (lo, hi)
-        };
-        ConstantRange(ty::Const::from_bits(tcx, lo, ty),
-                      ty::Const::from_bits(tcx, hi, ty),
-                      RangeEnd::Included)
-    }
-
     fn into_inner(self) -> (u128, u128) {
         self.range.into_inner()
     }
@@ -733,7 +705,11 @@ fn ranges_subtract_pattern<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
         }
         // Convert the remaining ranges from pairs to inclusive `ConstantRange`s.
         remaining_ranges.into_iter().map(|r| {
-            IntRange::decode(cx.tcx, ty, r)
+            let (lo, hi) = r.into_inner();
+            let bias = IntRange::signed_bias(cx.tcx, ty);
+            ConstantRange(ty::Const::from_bits(cx.tcx, lo ^ bias, ty),
+                          ty::Const::from_bits(cx.tcx, hi ^ bias, ty),
+                          RangeEnd::Included)
         }).collect()
     } else {
         ranges