提交 2c4c8eb1 编写于 作者: N Nicholas Nethercote

Box `PatKind::Range`.

Because it's the biggest variant. Also, make `PatRange` non-`Copy`,
because it's 104 bytes, which is pretty big.
上级 bd1e6836
......@@ -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 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
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);
}
......@@ -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 },
......
......@@ -208,7 +208,7 @@ fn simplify_match_pair<'pat>(
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)
......
......@@ -58,10 +58,10 @@ pub(super) fn test<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> Test<
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 @@ pub(super) fn add_cases_to_switch<'pat>(
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 @@ pub(super) fn perform_test(
}
}
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 @@ pub(super) fn sort_candidate<'pat>(
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 @@ pub(super) fn sort_candidate<'pat>(
}
}
(&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 @@ pub(super) fn sort_candidate<'pat>(
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 @@ fn error_simplifyable<'pat>(&mut self, match_pair: &MatchPair<'pat, '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 @@ fn const_range_contains(
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() {
......
......@@ -252,7 +252,11 @@ fn to_pat<'tcx>(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Pat<'tcx> {
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 @@ pub(crate) fn from_pat(cx: &MatchCheckCtxt<'p, 'tcx>, pat: &Pat<'tcx>) -> Self {
}
}
}
&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 @@ pub(crate) fn to_pat(&self, cx: &MatchCheckCtxt<'p, 'tcx>) -> Pat<'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!(
......
......@@ -134,7 +134,9 @@ fn lower_pattern_range(
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 @@ fn lower_pattern_range(
// `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 @@ fn super_fold_with<F: PatternFolder<'tcx>>(&self, folder: &mut F) -> Self {
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),
......
......@@ -157,7 +157,7 @@ fn pat_is_poly(&mut self, pat: &thir::Pat<'tcx>) -> bool {
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,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册