about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2025-07-29 13:28:47 +0200
committerRalf Jung <post@ralfj.de>2025-08-14 09:44:22 +0200
commitdbc030e0346f0958bea91601de7d115554bbf74e (patch)
tree36b8fc36a117123562d8fdd65224b99ef1ccd21d
parenta1acbfb050675f197fd525c830203f07412148bd (diff)
downloadrust-dbc030e0346f0958bea91601de7d115554bbf74e.tar.gz
rust-dbc030e0346f0958bea91601de7d115554bbf74e.zip
shrink TestBranch::Constant and PatRangeBoundary::Finite
-rw-r--r--compiler/rustc_middle/src/thir.rs15
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/mod.rs6
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/test.rs8
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs5
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs6
5 files changed, 23 insertions, 17 deletions
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 4910aa93be8..2c7b41193eb 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -959,9 +959,9 @@ impl<'tcx> PatRange<'tcx> {
     #[inline]
     pub fn contains(&self, value: ty::Value<'tcx>, tcx: TyCtxt<'tcx>) -> Option<bool> {
         use Ordering::*;
-        debug_assert_eq!(self.ty, value.ty);
+        debug_assert_eq!(value.ty, self.ty);
         let ty = self.ty;
-        let value = PatRangeBoundary::Finite(value);
+        let value = PatRangeBoundary::Finite(value.valtree);
         // For performance, it's important to only do the second comparison if necessary.
         Some(
             match self.lo.compare_with(value, ty, tcx)? {
@@ -996,11 +996,13 @@ impl<'tcx> PatRange<'tcx> {
 
 impl<'tcx> fmt::Display for PatRange<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        if let PatRangeBoundary::Finite(value) = &self.lo {
+        if let &PatRangeBoundary::Finite(valtree) = &self.lo {
+            let value = ty::Value { ty: self.ty, valtree };
             write!(f, "{value}")?;
         }
-        if let PatRangeBoundary::Finite(value) = &self.hi {
+        if let &PatRangeBoundary::Finite(valtree) = &self.hi {
             write!(f, "{}", self.end)?;
+            let value = ty::Value { ty: self.ty, valtree };
             write!(f, "{value}")?;
         } else {
             // `0..` is parsed as an inclusive range, we must display it correctly.
@@ -1014,7 +1016,8 @@ impl<'tcx> fmt::Display for PatRange<'tcx> {
 /// If present, the const must be of a numeric type.
 #[derive(Copy, Clone, Debug, PartialEq, HashStable, TypeVisitable)]
 pub enum PatRangeBoundary<'tcx> {
-    Finite(ty::Value<'tcx>),
+    /// The type of this valtree is stored in the surrounding `PatRange`.
+    Finite(ty::ValTree<'tcx>),
     NegInfinity,
     PosInfinity,
 }
@@ -1025,7 +1028,7 @@ impl<'tcx> PatRangeBoundary<'tcx> {
         matches!(self, Self::Finite(..))
     }
     #[inline]
-    pub fn as_finite(self) -> Option<ty::Value<'tcx>> {
+    pub fn as_finite(self) -> Option<ty::ValTree<'tcx>> {
         match self {
             Self::Finite(value) => Some(value),
             Self::NegInfinity | Self::PosInfinity => None,
diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs
index cdbac050734..2833b649ed7 100644
--- a/compiler/rustc_mir_build/src/builder/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs
@@ -1357,8 +1357,8 @@ pub(crate) struct Test<'tcx> {
 enum TestBranch<'tcx> {
     /// Success branch, used for tests with two possible outcomes.
     Success,
-    /// Branch corresponding to this constant.
-    Constant(ty::Value<'tcx>, u128),
+    /// Branch corresponding to this constant. Must be a scalar.
+    Constant(ty::Value<'tcx>),
     /// Branch corresponding to this variant.
     Variant(VariantIdx),
     /// Failure branch for tests with two possible outcomes, and "otherwise" branch for other tests.
@@ -1367,7 +1367,7 @@ enum TestBranch<'tcx> {
 
 impl<'tcx> TestBranch<'tcx> {
     fn as_constant(&self) -> Option<ty::Value<'tcx>> {
-        if let Self::Constant(v, _) = self { Some(*v) } else { None }
+        if let Self::Constant(v) = self { Some(*v) } else { None }
     }
 }
 
diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs
index 6771470e45a..f2f708bddce 100644
--- a/compiler/rustc_mir_build/src/builder/matches/test.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/test.rs
@@ -112,7 +112,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 let otherwise_block = target_block(TestBranch::Failure);
                 let switch_targets = SwitchTargets::new(
                     target_blocks.iter().filter_map(|(&branch, &block)| {
-                        if let TestBranch::Constant(_, bits) = branch {
+                        if let TestBranch::Constant(value) = branch {
+                            let bits = value.try_to_scalar_int().unwrap().to_bits_unchecked();
                             Some((bits, block))
                         } else {
                             None
@@ -279,6 +280,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 };
 
                 if let Some(lo) = range.lo.as_finite() {
+                    let lo = ty::Value { ty: range.ty, valtree: lo };
                     let lo = self.literal_operand(test.span, Const::from_ty_value(self.tcx, lo));
                     self.compare(
                         block,
@@ -292,6 +294,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 };
 
                 if let Some(hi) = range.hi.as_finite() {
+                    let hi = ty::Value { ty: range.ty, valtree: hi };
                     let hi = self.literal_operand(test.span, Const::from_ty_value(self.tcx, hi));
                     let op = match range.end {
                         RangeEnd::Included => BinOp::Le,
@@ -575,8 +578,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     None
                 } else {
                     fully_matched = true;
-                    let bits = value.try_to_scalar_int().unwrap().to_bits_unchecked();
-                    Some(TestBranch::Constant(value, bits))
+                    Some(TestBranch::Constant(value))
                 }
             }
             (TestKind::SwitchInt, TestCase::Range(range)) => {
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 539ebc3a3d7..166e64a5fcb 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -161,7 +161,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
                 format!("found bad range pattern endpoint `{expr:?}` outside of error recovery");
             return Err(self.tcx.dcx().span_delayed_bug(expr.span, msg));
         };
-        Ok(Some(PatRangeBoundary::Finite(value)))
+        Ok(Some(PatRangeBoundary::Finite(value.valtree)))
     }
 
     /// Overflowing literals are linted against in a late pass. This is mostly fine, except when we
@@ -243,7 +243,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             (RangeEnd::Included, Some(Ordering::Less)) => {}
             // `x..=y` where `x == y` and `x` and `y` are finite.
             (RangeEnd::Included, Some(Ordering::Equal)) if lo.is_finite() && hi.is_finite() => {
-                kind = PatKind::Constant { value: lo.as_finite().unwrap() };
+                let value = ty::Value { ty, valtree: lo.as_finite().unwrap() };
+                kind = PatKind::Constant { value };
             }
             // `..=x` where `x == ty::MIN`.
             (RangeEnd::Included, Some(Ordering::Equal)) if !lo.is_finite() => {}
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index e4703ddfc45..97f1c842797 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -722,7 +722,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
                 match ScalarInt::try_from_uint(bits, size) {
                     Some(scalar) => {
                         let valtree = ty::ValTree::from_scalar_int(tcx, scalar);
-                        PatRangeBoundary::Finite(ty::Value { ty: ty.inner(), valtree })
+                        PatRangeBoundary::Finite(valtree)
                     }
                     // The value doesn't fit. Since `x >= 0` and 0 always encodes the minimum value
                     // for a type, the problem isn't that the value is too small. So it must be too
@@ -742,7 +742,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
             "_".to_string()
         } else if range.is_singleton() {
             let lo = cx.hoist_pat_range_bdy(range.lo, ty);
-            let value = lo.as_finite().unwrap();
+            let value = ty::Value { ty: ty.inner(), valtree: lo.as_finite().unwrap() };
             value.to_string()
         } else {
             // We convert to an inclusive range for diagnostics.
@@ -756,7 +756,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
                 // probably clear enough.
                 let max = ty.numeric_max_val(cx.tcx).unwrap();
                 let max = ty::ValTree::from_scalar_int(cx.tcx, max.try_to_scalar_int().unwrap());
-                lo = PatRangeBoundary::Finite(ty::Value { ty: ty.inner(), valtree: max });
+                lo = PatRangeBoundary::Finite(max);
             }
             let hi = if let Some(hi) = range.hi.minus_one() {
                 hi