]> git.lizzy.rs Git - rust.git/commitdiff
Add common struct for range
authorShotaro Yamada <sinkuu@sinkuu.xyz>
Sat, 15 Dec 2018 14:04:23 +0000 (23:04 +0900)
committerShotaro Yamada <sinkuu@sinkuu.xyz>
Sat, 15 Dec 2018 14:14:45 +0000 (23:14 +0900)
src/librustc_mir/build/matches/mod.rs
src/librustc_mir/build/matches/simplify.rs
src/librustc_mir/build/matches/test.rs
src/librustc_mir/hair/mod.rs
src/librustc_mir/hair/pattern/_match.rs
src/librustc_mir/hair/pattern/mod.rs

index 97d983ed9e16356f91f0bf8a9119bad7636dae34..4d61bf8dae681b5451116e2cb0a0f70022dabcf6 100644 (file)
@@ -19,7 +19,6 @@
 use build::{GuardFrame, GuardFrameLocal, LocalsForNode};
 use hair::*;
 use hair::pattern::PatternTypeProjections;
-use rustc::hir;
 use rustc::mir::*;
 use rustc::ty::{self, Ty};
 use rustc::ty::layout::VariantIdx;
@@ -681,12 +680,7 @@ enum TestKind<'tcx> {
     },
 
     // test whether the value falls within an inclusive or exclusive range
-    Range {
-        lo: &'tcx ty::Const<'tcx>,
-        hi: &'tcx ty::Const<'tcx>,
-        ty: Ty<'tcx>,
-        end: hir::RangeEnd,
-    },
+    Range(PatternRange<'tcx>),
 
     // test length of the slice is equal to len
     Len {
index b9fd4f0e0b60b7a84b88a5400ef2dbaaca9d7805..0ce642838707ed5aac8e95b3d1b659fa87e7b8c2 100644 (file)
@@ -107,7 +107,7 @@ fn simplify_match_pair<'pat>(&mut self,
                 Err(match_pair)
             }
 
-            PatternKind::Range { lo, hi, ty, end } => {
+            PatternKind::Range(PatternRange { lo, hi, ty, end }) => {
                 let range = match ty.sty {
                     ty::Char => {
                         Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32)))
index 0abbfc540e63ce285837d1481f02b87d86d63143..c8dec6d0b9764b67528e2d531a5d06f17f3dce03 100644 (file)
@@ -72,16 +72,11 @@ pub fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<'tcx> {
                 }
             }
 
-            PatternKind::Range { lo, hi, ty, end } => {
-                assert!(ty == match_pair.pattern.ty);
+            PatternKind::Range(range) => {
+                assert!(range.ty == match_pair.pattern.ty);
                 Test {
                     span: match_pair.pattern.span,
-                    kind: TestKind::Range {
-                        lo,
-                        hi,
-                        ty,
-                        end,
-                    },
+                    kind: TestKind::Range(range),
                 }
             }
 
@@ -137,9 +132,9 @@ pub fn add_cases_to_switch<'pat>(&mut self,
             PatternKind::Variant { .. } => {
                 panic!("you should have called add_variants_to_switch instead!");
             }
-            PatternKind::Range { ty, lo, hi, end } => {
+            PatternKind::Range(range) => {
                 // Check that none of the switch values are in the range.
-                self.values_not_contained_in_range(ty, lo, hi, end, indices)
+                self.values_not_contained_in_range(range, indices)
                     .unwrap_or(false)
             }
             PatternKind::Slice { .. } |
@@ -381,7 +376,7 @@ pub fn perform_test(&mut self,
                 }
             }
 
-            TestKind::Range { ref lo, ref hi, ty, ref end } => {
+            TestKind::Range(PatternRange { ref lo, ref hi, ty, ref end }) => {
                 // Test `val` by computing `lo <= val && val <= hi`, using primitive comparisons.
                 let lo = self.literal_operand(test.span, ty.clone(), lo.clone());
                 let hi = self.literal_operand(test.span, ty.clone(), hi.clone());
@@ -536,9 +531,9 @@ pub fn sort_candidate<'pat>(&mut self,
             }
 
             (&TestKind::SwitchInt { switch_ty: _, ref options, ref indices },
-             &PatternKind::Range { ty, lo, hi, end }) => {
+             &PatternKind::Range(range)) => {
                 let not_contained = self
-                    .values_not_contained_in_range(ty, lo, hi, end, indices)
+                    .values_not_contained_in_range(range, indices)
                     .unwrap_or(false);
 
                 if not_contained {
@@ -630,12 +625,9 @@ pub fn sort_candidate<'pat>(&mut self,
                 }
             }
 
-            (&TestKind::Range {
-                lo: test_lo, hi: test_hi, ty: test_ty, end: test_end,
-            }, &PatternKind::Range {
-                lo: pat_lo, hi: pat_hi, ty: _, end: pat_end,
-            }) => {
-                if (test_lo, test_hi, test_end) == (pat_lo, pat_hi, pat_end) {
+            (&TestKind::Range(test),
+             &PatternKind::Range(pat)) => {
+                if test == pat {
                     resulting_candidates[0]
                         .push(self.candidate_without_match_pair(
                             match_pair_index,
@@ -648,13 +640,13 @@ pub fn sort_candidate<'pat>(&mut self,
                     use std::cmp::Ordering::*;
                     use rustc::hir::RangeEnd::*;
 
-                    let param_env = ty::ParamEnv::empty().and(test_ty);
+                    let param_env = ty::ParamEnv::empty().and(test.ty);
                     let tcx = self.hir.tcx();
 
-                    let lo = compare_const_vals(tcx, test_lo, pat_hi, param_env)?;
-                    let hi = compare_const_vals(tcx, test_hi, pat_lo, param_env)?;
+                    let lo = compare_const_vals(tcx, test.lo, pat.hi, param_env)?;
+                    let hi = compare_const_vals(tcx, test.hi, pat.lo, param_env)?;
 
-                    match (test_end, pat_end, lo, hi) {
+                    match (test.end, pat.end, lo, hi) {
                         // pat < test
                         (_, _, Greater, _) |
                         (_, Excluded, Equal, _) |
@@ -675,12 +667,8 @@ pub fn sort_candidate<'pat>(&mut self,
                 }
             }
 
-            (&TestKind::Range {
-                lo, hi, ty, end
-            }, &PatternKind::Constant {
-                ref value
-            }) => {
-                if self.const_range_contains(ty, lo, hi, end, value) == Some(false) {
+            (&TestKind::Range(range), &PatternKind::Constant { ref value }) => {
+                if self.const_range_contains(range, value) == Some(false) {
                     // `value` is not contained in the testing range,
                     // so `value` can be matched only if this test fails.
                     resulting_candidates[1].push(candidate.clone());
@@ -807,21 +795,18 @@ fn error_simplifyable<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> !
 
     fn const_range_contains(
         &self,
-        ty: Ty<'tcx>,
-        lo: &'tcx ty::Const<'tcx>,
-        hi: &'tcx ty::Const<'tcx>,
-        end: RangeEnd,
+        range: PatternRange<'tcx>,
         value: &'tcx ty::Const<'tcx>,
     ) -> Option<bool> {
         use std::cmp::Ordering::*;
 
-        let param_env = ty::ParamEnv::empty().and(ty);
+        let param_env = ty::ParamEnv::empty().and(range.ty);
         let tcx = self.hir.tcx();
 
-        let a = compare_const_vals(tcx, lo, value, param_env)?;
-        let b = compare_const_vals(tcx, value, hi, param_env)?;
+        let a = compare_const_vals(tcx, range.lo, value, param_env)?;
+        let b = compare_const_vals(tcx, value, range.hi, param_env)?;
 
-        match (b, end) {
+        match (b, range.end) {
             (Less, _) |
             (Equal, RangeEnd::Included) if a != Greater => Some(true),
             _ => Some(false),
@@ -830,14 +815,11 @@ fn const_range_contains(
 
     fn values_not_contained_in_range(
         &self,
-        ty: Ty<'tcx>,
-        lo: &'tcx ty::Const<'tcx>,
-        hi: &'tcx ty::Const<'tcx>,
-        end: RangeEnd,
+        range: PatternRange<'tcx>,
         indices: &FxHashMap<&'tcx ty::Const<'tcx>, usize>,
     ) -> Option<bool> {
         for val in indices.keys() {
-            if self.const_range_contains(ty, lo, hi, end, val)? {
+            if self.const_range_contains(range, val)? {
                 return Some(false);
             }
         }
index e604b118eacf1f8f445acd5553806bf1ef9dc8e8..b254fce4b7684a6678d77ad99c75e2da1733d340 100644 (file)
@@ -29,7 +29,7 @@
 mod constant;
 
 pub mod pattern;
-pub use self::pattern::{BindingMode, Pattern, PatternKind, FieldPattern};
+pub use self::pattern::{BindingMode, Pattern, PatternKind, PatternRange, FieldPattern};
 pub(crate) use self::pattern::{PatternTypeProjection, PatternTypeProjections};
 
 mod util;
index 4c77350f10ecd7182b8d058fade9b5a02978e614..c0bfee803ef8e2f69fc0ba0d62c08d14cff32e22 100644 (file)
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::indexed_vec::Idx;
 
-use super::{FieldPattern, Pattern, PatternKind};
+use super::{FieldPattern, Pattern, PatternKind, PatternRange};
 use super::{PatternFoldable, PatternFolder, compare_const_vals};
 
 use rustc::hir::def_id::DefId;
@@ -554,12 +554,12 @@ fn apply_constructor<'a>(
                 _ => {
                     match *ctor {
                         ConstantValue(value) => PatternKind::Constant { value },
-                        ConstantRange(lo, hi, ty, end) => PatternKind::Range {
+                        ConstantRange(lo, hi, ty, end) => PatternKind::Range(PatternRange {
                             lo: ty::Const::from_bits(cx.tcx, lo, ty::ParamEnv::empty().and(ty)),
                             hi: ty::Const::from_bits(cx.tcx, hi, ty::ParamEnv::empty().and(ty)),
                             ty,
                             end,
-                        },
+                        }),
                         _ => PatternKind::Wild,
                     }
                 }
@@ -820,7 +820,7 @@ fn from_pat(tcx: TyCtxt<'_, 'tcx, 'tcx>,
                 -> Option<IntRange<'tcx>> {
         Self::from_ctor(tcx, &match pat.kind {
             box PatternKind::Constant { value } => ConstantValue(value),
-            box PatternKind::Range { lo, hi, ty, end } => ConstantRange(
+            box PatternKind::Range(PatternRange { lo, hi, ty, end }) => ConstantRange(
                 lo.to_bits(tcx, ty::ParamEnv::empty().and(ty)).unwrap(),
                 hi.to_bits(tcx, ty::ParamEnv::empty().and(ty)).unwrap(),
                 ty,
@@ -1259,7 +1259,7 @@ fn pat_constructors<'tcx>(cx: &mut MatchCheckCtxt<'_, 'tcx>,
             Some(vec![Variant(adt_def.variants[variant_index].did)])
         }
         PatternKind::Constant { value } => Some(vec![ConstantValue(value)]),
-        PatternKind::Range { lo, hi, ty, end } =>
+        PatternKind::Range(PatternRange { lo, hi, ty, end }) =>
             Some(vec![ConstantRange(
                 lo.to_bits(cx.tcx, ty::ParamEnv::empty().and(ty)).unwrap(),
                 hi.to_bits(cx.tcx, ty::ParamEnv::empty().and(ty)).unwrap(),
@@ -1556,7 +1556,7 @@ fn constructor_covered_by_range<'a, 'tcx>(
 ) -> Result<bool, ErrorReported> {
     let (from, to, end, ty) = match pat.kind {
         box PatternKind::Constant { value } => (value, value, RangeEnd::Included, value.ty),
-        box PatternKind::Range { lo, hi, ty, end } => (lo, hi, end, ty),
+        box PatternKind::Range(PatternRange { lo, hi, end, ty }) => (lo, hi, end, ty),
         _ => bug!("`constructor_covered_by_range` called with {:?}", pat),
     };
     trace!("constructor_covered_by_range {:#?}, {:#?}, {:#?}, {}", ctor, from, to, ty);
index 864f242a304e01b5455c968ce1db9abeca801f5f..b014a76a7393f5178015b89a4b4cd29dbdab61ff 100644 (file)
@@ -219,12 +219,7 @@ pub enum PatternKind<'tcx> {
         value: &'tcx ty::Const<'tcx>,
     },
 
-    Range {
-        lo: &'tcx ty::Const<'tcx>,
-        hi: &'tcx ty::Const<'tcx>,
-        ty: Ty<'tcx>,
-        end: RangeEnd,
-    },
+    Range(PatternRange<'tcx>),
 
     /// matches against a slice, checking the length and extracting elements.
     /// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty.
@@ -243,6 +238,14 @@ pub enum PatternKind<'tcx> {
     },
 }
 
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub struct PatternRange<'tcx> {
+    pub lo: &'tcx ty::Const<'tcx>,
+    pub hi: &'tcx ty::Const<'tcx>,
+    pub ty: Ty<'tcx>,
+    pub end: RangeEnd,
+}
+
 impl<'tcx> fmt::Display for Pattern<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self.kind {
@@ -354,7 +357,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             PatternKind::Constant { value } => {
                 fmt_const_val(f, value)
             }
-            PatternKind::Range { lo, hi, ty: _, end } => {
+            PatternKind::Range(PatternRange { lo, hi, ty: _, end }) => {
                 fmt_const_val(f, lo)?;
                 match end {
                     RangeEnd::Included => write!(f, "..=")?,
@@ -483,7 +486,7 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
                         );
                         match (end, cmp) {
                             (RangeEnd::Excluded, Some(Ordering::Less)) =>
-                                PatternKind::Range { lo, hi, ty, end },
+                                PatternKind::Range(PatternRange { lo, hi, ty, end }),
                             (RangeEnd::Excluded, _) => {
                                 span_err!(
                                     self.tcx.sess,
@@ -497,7 +500,7 @@ fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat) -> Pattern<'tcx> {
                                 PatternKind::Constant { value: lo }
                             }
                             (RangeEnd::Included, Some(Ordering::Less)) => {
-                                PatternKind::Range { lo, hi, ty, end }
+                                PatternKind::Range(PatternRange { lo, hi, ty, end })
                             }
                             (RangeEnd::Included, _) => {
                                 let mut err = struct_span_err!(
@@ -1177,17 +1180,17 @@ fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
             } => PatternKind::Constant {
                 value: value.fold_with(folder)
             },
-            PatternKind::Range {
+            PatternKind::Range(PatternRange {
                 lo,
                 hi,
                 ty,
                 end,
-            } => PatternKind::Range {
+            }) => PatternKind::Range(PatternRange {
                 lo: lo.fold_with(folder),
                 hi: hi.fold_with(folder),
                 ty: ty.fold_with(folder),
                 end,
-            },
+            }),
             PatternKind::Slice {
                 ref prefix,
                 ref slice,