Skip to content

Commit 3ebc541

Browse files
committed
shrink TestBranch::Constant and PatRangeBoundary::Finite
1 parent 9f3f015 commit 3ebc541

File tree

5 files changed

+23
-17
lines changed

5 files changed

+23
-17
lines changed

compiler/rustc_middle/src/thir.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -955,11 +955,10 @@ impl<'tcx> PatRange<'tcx> {
955955
}
956956

957957
#[inline]
958-
pub fn contains(&self, value: ty::Value<'tcx>, tcx: TyCtxt<'tcx>) -> Option<bool> {
958+
pub fn contains(&self, valtree: ty::ValTree<'tcx>, tcx: TyCtxt<'tcx>) -> Option<bool> {
959959
use Ordering::*;
960-
debug_assert_eq!(self.ty, value.ty);
961960
let ty = self.ty;
962-
let value = PatRangeBoundary::Finite(value);
961+
let value = PatRangeBoundary::Finite(valtree);
963962
// For performance, it's important to only do the second comparison if necessary.
964963
Some(
965964
match self.lo.compare_with(value, ty, tcx)? {
@@ -994,11 +993,13 @@ impl<'tcx> PatRange<'tcx> {
994993

995994
impl<'tcx> fmt::Display for PatRange<'tcx> {
996995
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
997-
if let PatRangeBoundary::Finite(value) = &self.lo {
996+
if let &PatRangeBoundary::Finite(valtree) = &self.lo {
997+
let value = ty::Value { ty: self.ty, valtree };
998998
write!(f, "{value}")?;
999999
}
1000-
if let PatRangeBoundary::Finite(value) = &self.hi {
1000+
if let &PatRangeBoundary::Finite(valtree) = &self.hi {
10011001
write!(f, "{}", self.end)?;
1002+
let value = ty::Value { ty: self.ty, valtree };
10021003
write!(f, "{value}")?;
10031004
} else {
10041005
// `0..` is parsed as an inclusive range, we must display it correctly.
@@ -1012,7 +1013,8 @@ impl<'tcx> fmt::Display for PatRange<'tcx> {
10121013
/// If present, the const must be of a numeric type.
10131014
#[derive(Copy, Clone, Debug, PartialEq, HashStable, TypeVisitable)]
10141015
pub enum PatRangeBoundary<'tcx> {
1015-
Finite(ty::Value<'tcx>),
1016+
/// The type if this valtree is stored in the surrounding `PatRange`.
1017+
Finite(ty::ValTree<'tcx>),
10161018
NegInfinity,
10171019
PosInfinity,
10181020
}
@@ -1023,7 +1025,7 @@ impl<'tcx> PatRangeBoundary<'tcx> {
10231025
matches!(self, Self::Finite(..))
10241026
}
10251027
#[inline]
1026-
pub fn as_finite(self) -> Option<ty::Value<'tcx>> {
1028+
pub fn as_finite(self) -> Option<ty::ValTree<'tcx>> {
10271029
match self {
10281030
Self::Finite(value) => Some(value),
10291031
Self::NegInfinity | Self::PosInfinity => None,

compiler/rustc_mir_build/src/builder/matches/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,15 +1373,16 @@ enum TestBranch<'tcx> {
13731373
/// Success branch, used for tests with two possible outcomes.
13741374
Success,
13751375
/// Branch corresponding to this constant.
1376-
Constant(ty::Value<'tcx>, u128),
1376+
/// The type of this valtree is the same for all branches, it must be known by the context.
1377+
Constant(ty::ValTree<'tcx>, u128),
13771378
/// Branch corresponding to this variant.
13781379
Variant(VariantIdx),
13791380
/// Failure branch for tests with two possible outcomes, and "otherwise" branch for other tests.
13801381
Failure,
13811382
}
13821383

13831384
impl<'tcx> TestBranch<'tcx> {
1384-
fn as_constant(&self) -> Option<ty::Value<'tcx>> {
1385+
fn as_constant(&self) -> Option<ty::ValTree<'tcx>> {
13851386
if let Self::Constant(v, _) = self { Some(*v) } else { None }
13861387
}
13871388
}

compiler/rustc_mir_build/src/builder/matches/test.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
279279
};
280280

281281
if let Some(lo) = range.lo.as_finite() {
282+
let lo = ty::Value { ty: range.ty, valtree: lo };
282283
let lo = self.literal_operand(test.span, Const::from_ty_value(self.tcx, lo));
283284
self.compare(
284285
block,
@@ -292,6 +293,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
292293
};
293294

294295
if let Some(hi) = range.hi.as_finite() {
296+
let hi = ty::Value { ty: range.ty, valtree: hi };
295297
let hi = self.literal_operand(test.span, Const::from_ty_value(self.tcx, hi));
296298
let op = match range.end {
297299
RangeEnd::Included => BinOp::Le,
@@ -558,7 +560,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
558560
// not to add such values here.
559561
let is_covering_range = |test_case: &TestCase<'tcx>| {
560562
test_case.as_range().is_some_and(|range| {
561-
matches!(range.contains(value, self.tcx), None | Some(true))
563+
matches!(range.contains(value.valtree, self.tcx), None | Some(true))
562564
})
563565
};
564566
let is_conflicting_candidate = |candidate: &&mut Candidate<'tcx>| {
@@ -576,7 +578,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
576578
} else {
577579
fully_matched = true;
578580
let bits = value.try_to_scalar_int().unwrap().to_bits_unchecked();
579-
Some(TestBranch::Constant(value, bits))
581+
Some(TestBranch::Constant(value.valtree, bits))
580582
}
581583
}
582584
(TestKind::SwitchInt, TestCase::Range(range)) => {
@@ -684,7 +686,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
684686
}
685687
(TestKind::Range(range), &TestCase::Constant { value }) => {
686688
fully_matched = false;
687-
if !range.contains(value, self.tcx)? {
689+
if !range.contains(value.valtree, self.tcx)? {
688690
// `value` is not contained in the testing range,
689691
// so `value` can be matched only if this test fails.
690692
Some(TestBranch::Failure)

compiler/rustc_mir_build/src/thir/pattern/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
161161
format!("found bad range pattern endpoint `{expr:?}` outside of error recovery");
162162
return Err(self.tcx.dcx().span_delayed_bug(expr.span, msg));
163163
};
164-
Ok(Some(PatRangeBoundary::Finite(value)))
164+
Ok(Some(PatRangeBoundary::Finite(value.valtree)))
165165
}
166166

167167
/// 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> {
243243
(RangeEnd::Included, Some(Ordering::Less)) => {}
244244
// `x..=y` where `x == y` and `x` and `y` are finite.
245245
(RangeEnd::Included, Some(Ordering::Equal)) if lo.is_finite() && hi.is_finite() => {
246-
kind = PatKind::Constant { value: lo.as_finite().unwrap() };
246+
let value = ty::Value { ty, valtree: lo.as_finite().unwrap() };
247+
kind = PatKind::Constant { value };
247248
}
248249
// `..=x` where `x == ty::MIN`.
249250
(RangeEnd::Included, Some(Ordering::Equal)) if !lo.is_finite() => {}

compiler/rustc_pattern_analysis/src/rustc.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
722722
match ScalarInt::try_from_uint(bits, size) {
723723
Some(scalar) => {
724724
let valtree = ty::ValTree::from_scalar_int(tcx, scalar);
725-
PatRangeBoundary::Finite(ty::Value { ty: ty.inner(), valtree })
725+
PatRangeBoundary::Finite(valtree)
726726
}
727727
// The value doesn't fit. Since `x >= 0` and 0 always encodes the minimum value
728728
// 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> {
742742
"_".to_string()
743743
} else if range.is_singleton() {
744744
let lo = cx.hoist_pat_range_bdy(range.lo, ty);
745-
let value = lo.as_finite().unwrap();
745+
let value = ty::Value { ty: ty.inner(), valtree: lo.as_finite().unwrap() };
746746
value.to_string()
747747
} else {
748748
// We convert to an inclusive range for diagnostics.
@@ -756,7 +756,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
756756
// probably clear enough.
757757
let max = ty.numeric_max_val(cx.tcx).unwrap();
758758
let max = ty::ValTree::from_scalar_int(cx.tcx, max.try_to_scalar_int().unwrap());
759-
lo = PatRangeBoundary::Finite(ty::Value { ty: ty.inner(), valtree: max });
759+
lo = PatRangeBoundary::Finite(max);
760760
}
761761
let hi = if let Some(hi) = range.hi.minus_one() {
762762
hi

0 commit comments

Comments
 (0)