about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_middle/src/thir.rs18
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs52
2 files changed, 32 insertions, 38 deletions
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 2ad592174f1..65875ff3f9a 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -815,7 +815,9 @@ pub enum PatKind<'tcx> {
 /// The boundaries must be of the same type and that type must be numeric.
 #[derive(Clone, Debug, PartialEq, HashStable, TypeVisitable)]
 pub struct PatRange<'tcx> {
+    /// Must not be `PosInfinity`.
     pub lo: PatRangeBoundary<'tcx>,
+    /// Must not be `NegInfinity`.
     pub hi: PatRangeBoundary<'tcx>,
     #[type_visitable(ignore)]
     pub end: RangeEnd,
@@ -958,22 +960,6 @@ impl<'tcx> PatRangeBoundary<'tcx> {
             Self::NegInfinity | Self::PosInfinity => None,
         }
     }
-    #[inline]
-    pub fn to_const(self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> mir::Const<'tcx> {
-        match self {
-            Self::Finite(value) => value,
-            Self::NegInfinity => {
-                // Unwrap is ok because the type is known to be numeric.
-                let c = ty.numeric_min_val(tcx).unwrap();
-                mir::Const::from_ty_const(c, tcx)
-            }
-            Self::PosInfinity => {
-                // Unwrap is ok because the type is known to be numeric.
-                let c = ty.numeric_max_val(tcx).unwrap();
-                mir::Const::from_ty_const(c, tcx)
-            }
-        }
-    }
     pub fn eval_bits(self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> u128 {
         match self {
             Self::Finite(value) => value.eval_bits(tcx, param_env),
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index 1c97de58863..1b6994966d1 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -291,33 +291,41 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
 
             TestKind::Range(ref range) => {
-                let lower_bound_success = self.cfg.start_new_block();
-
+                let [success, fail] = *target_blocks else {
+                    bug!("`TestKind::Range` should have two target blocks");
+                };
                 // Test `val` by computing `lo <= val && val <= hi`, using primitive comparisons.
-                // FIXME: skip useless comparison when the range is half-open.
-                let lo = range.lo.to_const(range.ty, self.tcx);
-                let hi = range.hi.to_const(range.ty, self.tcx);
-                let lo = self.literal_operand(test.span, lo);
-                let hi = self.literal_operand(test.span, hi);
                 let val = Operand::Copy(place);
 
-                let [success, fail] = *target_blocks else {
-                    bug!("`TestKind::Range` should have two target blocks");
+                let intermediate_block = if !range.lo.is_finite() {
+                    block
+                } else if !range.hi.is_finite() {
+                    success
+                } else {
+                    self.cfg.start_new_block()
                 };
-                self.compare(
-                    block,
-                    lower_bound_success,
-                    fail,
-                    source_info,
-                    BinOp::Le,
-                    lo,
-                    val.clone(),
-                );
-                let op = match range.end {
-                    RangeEnd::Included => BinOp::Le,
-                    RangeEnd::Excluded => BinOp::Lt,
+
+                if let Some(lo) = range.lo.as_finite() {
+                    let lo = self.literal_operand(test.span, lo);
+                    self.compare(
+                        block,
+                        intermediate_block,
+                        fail,
+                        source_info,
+                        BinOp::Le,
+                        lo,
+                        val.clone(),
+                    );
                 };
-                self.compare(lower_bound_success, success, fail, source_info, op, val, hi);
+
+                if let Some(hi) = range.hi.as_finite() {
+                    let hi = self.literal_operand(test.span, hi);
+                    let op = match range.end {
+                        RangeEnd::Included => BinOp::Le,
+                        RangeEnd::Excluded => BinOp::Lt,
+                    };
+                    self.compare(intermediate_block, success, fail, source_info, op, val, hi);
+                }
             }
 
             TestKind::Len { len, op } => {