Box PatKind::Range.

Because it's the biggest variant. Also, make `PatRange` non-`Copy`,
because it's 104 bytes, which is pretty big.
This commit is contained in:
Nicholas Nethercote 2022-08-26 11:36:24 +10:00
parent bd1e6836a0
commit 2c4c8eb1a3
7 changed files with 34 additions and 26 deletions

View File

@ -628,7 +628,7 @@ pub enum PatKind<'tcx> {
value: mir::ConstantKind<'tcx>,
},
Range(PatRange<'tcx>),
Range(Box<PatRange<'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.
@ -653,7 +653,7 @@ pub enum PatKind<'tcx> {
},
}
#[derive(Copy, Clone, Debug, PartialEq, HashStable)]
#[derive(Clone, Debug, PartialEq, HashStable)]
pub struct PatRange<'tcx> {
pub lo: mir::ConstantKind<'tcx>,
pub hi: mir::ConstantKind<'tcx>,
@ -767,7 +767,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
write!(f, "{}", subpattern)
}
PatKind::Constant { value } => write!(f, "{}", value),
PatKind::Range(PatRange { lo, hi, end }) => {
PatKind::Range(box PatRange { lo, hi, end }) => {
write!(f, "{}", lo)?;
write!(f, "{}", end)?;
write!(f, "{}", hi)
@ -809,8 +809,8 @@ mod size_asserts {
static_assert_size!(Block, 56);
static_assert_size!(Expr<'_>, 64);
static_assert_size!(ExprKind<'_>, 40);
static_assert_size!(Pat<'_>, 128);
static_assert_size!(PatKind<'_>, 112);
static_assert_size!(Pat<'_>, 112);
static_assert_size!(PatKind<'_>, 96);
static_assert_size!(Stmt<'_>, 56);
static_assert_size!(StmtKind<'_>, 48);
}

View File

@ -979,7 +979,7 @@ enum TestKind<'tcx> {
},
/// Test whether the value falls within an inclusive or exclusive range
Range(PatRange<'tcx>),
Range(Box<PatRange<'tcx>>),
/// Test that the length of the slice is equal to `len`.
Len { len: u64, op: BinOp },

View File

@ -208,7 +208,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Err(match_pair)
}
PatKind::Range(PatRange { lo, hi, end }) => {
PatKind::Range(box PatRange { lo, hi, end }) => {
let (range, bias) = match *lo.ty().kind() {
ty::Char => {
(Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32))), 0)

View File

@ -58,10 +58,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
kind: TestKind::Eq { value, ty: match_pair.pattern.ty },
},
PatKind::Range(range) => {
PatKind::Range(ref range) => {
assert_eq!(range.lo.ty(), match_pair.pattern.ty);
assert_eq!(range.hi.ty(), match_pair.pattern.ty);
Test { span: match_pair.pattern.span, kind: TestKind::Range(range) }
Test { span: match_pair.pattern.span, kind: TestKind::Range(range.clone()) }
}
PatKind::Slice { ref prefix, ref slice, ref suffix } => {
@ -102,9 +102,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
PatKind::Variant { .. } => {
panic!("you should have called add_variants_to_switch instead!");
}
PatKind::Range(range) => {
PatKind::Range(ref range) => {
// Check that none of the switch values are in the range.
self.values_not_contained_in_range(range, options).unwrap_or(false)
self.values_not_contained_in_range(&*range, options).unwrap_or(false)
}
PatKind::Slice { .. }
| PatKind::Array { .. }
@ -272,7 +272,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}
TestKind::Range(PatRange { lo, hi, ref end }) => {
TestKind::Range(box PatRange { lo, hi, ref end }) => {
let lower_bound_success = self.cfg.start_new_block();
let target_blocks = make_target_blocks(self);
@ -540,9 +540,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Some(index)
}
(&TestKind::SwitchInt { switch_ty: _, ref options }, &PatKind::Range(range)) => {
(&TestKind::SwitchInt { switch_ty: _, ref options }, &PatKind::Range(ref range)) => {
let not_contained =
self.values_not_contained_in_range(range, options).unwrap_or(false);
self.values_not_contained_in_range(&*range, options).unwrap_or(false);
if not_contained {
// No switch values are contained in the pattern range,
@ -631,7 +631,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}
(&TestKind::Range(test), &PatKind::Range(pat)) => {
(&TestKind::Range(ref test), &PatKind::Range(ref pat)) => {
use std::cmp::Ordering::*;
if test == pat {
@ -658,8 +658,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
no_overlap
}
(&TestKind::Range(range), &PatKind::Constant { value }) => {
if let Some(false) = self.const_range_contains(range, value) {
(&TestKind::Range(ref range), &PatKind::Constant { value }) => {
if let Some(false) = self.const_range_contains(&*range, value) {
// `value` is not contained in the testing range,
// so `value` can be matched only if this test fails.
Some(1)
@ -754,7 +754,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
fn const_range_contains(
&self,
range: PatRange<'tcx>,
range: &PatRange<'tcx>,
value: ConstantKind<'tcx>,
) -> Option<bool> {
use std::cmp::Ordering::*;
@ -772,7 +772,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
fn values_not_contained_in_range(
&self,
range: PatRange<'tcx>,
range: &PatRange<'tcx>,
options: &FxIndexMap<ConstantKind<'tcx>, u128>,
) -> Option<bool> {
for &val in options.keys() {

View File

@ -252,7 +252,11 @@ impl IntRange {
let kind = if lo == hi {
PatKind::Constant { value: lo_const }
} else {
PatKind::Range(PatRange { lo: lo_const, hi: hi_const, end: RangeEnd::Included })
PatKind::Range(Box::new(PatRange {
lo: lo_const,
hi: hi_const,
end: RangeEnd::Included,
}))
};
Pat { ty, span: DUMMY_SP, kind }
@ -1402,7 +1406,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
}
}
}
&PatKind::Range(PatRange { lo, hi, end }) => {
&PatKind::Range(box PatRange { lo, hi, end }) => {
let ty = lo.ty();
ctor = if let Some(int_range) = IntRange::from_range(
cx.tcx,
@ -1511,7 +1515,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
}
}
&Str(value) => PatKind::Constant { value },
&FloatRange(lo, hi, end) => PatKind::Range(PatRange { lo, hi, end }),
&FloatRange(lo, hi, end) => PatKind::Range(Box::new(PatRange { lo, hi, end })),
IntRange(range) => return range.to_pat(cx.tcx, self.ty),
Wildcard | NonExhaustive => PatKind::Wild,
Missing { .. } => bug!(

View File

@ -134,7 +134,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
match (end, cmp) {
// `x..y` where `x < y`.
// Non-empty because the range includes at least `x`.
(RangeEnd::Excluded, Some(Ordering::Less)) => PatKind::Range(PatRange { lo, hi, end }),
(RangeEnd::Excluded, Some(Ordering::Less)) => {
PatKind::Range(Box::new(PatRange { lo, hi, end }))
}
// `x..y` where `x >= y`. The range is empty => error.
(RangeEnd::Excluded, _) => {
struct_span_err!(
@ -149,7 +151,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
// `x..=y` where `x == y`.
(RangeEnd::Included, Some(Ordering::Equal)) => PatKind::Constant { value: lo },
// `x..=y` where `x < y`.
(RangeEnd::Included, Some(Ordering::Less)) => PatKind::Range(PatRange { lo, hi, end }),
(RangeEnd::Included, Some(Ordering::Less)) => {
PatKind::Range(Box::new(PatRange { lo, hi, end }))
}
// `x..=y` where `x > y` hence the range is empty => error.
(RangeEnd::Included, _) => {
let mut err = struct_span_err!(
@ -735,7 +739,7 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> {
PatKind::Deref { subpattern: subpattern.fold_with(folder) }
}
PatKind::Constant { value } => PatKind::Constant { value },
PatKind::Range(range) => PatKind::Range(range),
PatKind::Range(ref range) => PatKind::Range(range.clone()),
PatKind::Slice { ref prefix, ref slice, ref suffix } => PatKind::Slice {
prefix: prefix.fold_with(folder),
slice: slice.fold_with(folder),

View File

@ -157,7 +157,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
match pat.kind {
thir::PatKind::Constant { value } => value.has_param_types_or_consts(),
thir::PatKind::Range(thir::PatRange { lo, hi, .. }) => {
thir::PatKind::Range(box thir::PatRange { lo, hi, .. }) => {
lo.has_param_types_or_consts() || hi.has_param_types_or_consts()
}
_ => false,