Skip to content

Commit 34b0774

Browse files
committed
Remove some unnecessary conversions between Constructor and IntRange
1 parent eea0b79 commit 34b0774

File tree

1 file changed

+24
-49
lines changed

1 file changed

+24
-49
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 24 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ impl<'tcx> Constructor<'tcx> {
649649
match self {
650650
// Any base constructor can be used unchanged.
651651
Single | Variant(_) | ConstantValue(_) | FixedLenSlice(_) => smallvec![self],
652-
IntRange(..) if IntRange::should_treat_range_exhaustively(cx.tcx, ty) => {
652+
IntRange(ctor_range) if IntRange::should_treat_range_exhaustively(cx.tcx, ty) => {
653653
// Splitting up a range naïvely would mean creating a separate constructor for
654654
// every single value in the range, which is clearly impractical. We therefore want
655655
// to keep together subranges for which the specialisation will be identical across
@@ -681,9 +681,6 @@ impl<'tcx> Constructor<'tcx> {
681681
// essentially amounts to performing the intuitive merging operation depicted
682682
// above.)
683683

684-
// We only care about finding all the subranges within the range of `self`.
685-
let ctor_range = IntRange::from_ctor(cx.tcx, cx.param_env, &self).unwrap();
686-
687684
/// Represents a border between 2 integers. Because the intervals spanning borders
688685
/// must be able to cover every integer, we need to be able to represent
689686
/// 2^128 + 1 such borders.
@@ -708,7 +705,7 @@ impl<'tcx> Constructor<'tcx> {
708705
// class lies between 2 borders.
709706
let row_borders = head_ctors
710707
.iter()
711-
.flat_map(|ctor| IntRange::from_ctor(cx.tcx, cx.param_env, ctor))
708+
.flat_map(IntRange::from_ctor)
712709
.flat_map(|range| ctor_range.intersection(cx.tcx, &range))
713710
.flat_map(|range| range_borders(range));
714711
let ctor_borders = range_borders(ctor_range.clone());
@@ -731,7 +728,8 @@ impl<'tcx> Constructor<'tcx> {
731728
(Border::JustBefore(n), Border::AfterMax) => Some(n..=u128::MAX),
732729
(Border::AfterMax, _) => None,
733730
})
734-
.map(|range| IntRange::range_to_ctor(cx.tcx, ty, range))
731+
.map(|range| IntRange::new(ty, range))
732+
.map(IntRange)
735733
.collect()
736734
}
737735
// When not treated exhaustively, don't split ranges.
@@ -915,8 +913,8 @@ impl<'tcx> Constructor<'tcx> {
915913
/// notation).
916914
fn subtract_meta_constructor(
917915
self,
918-
tcx: TyCtxt<'tcx>,
919-
param_env: ty::ParamEnv<'tcx>,
916+
_tcx: TyCtxt<'tcx>,
917+
_param_env: ty::ParamEnv<'tcx>,
920918
used_ctors: &Vec<Constructor<'tcx>>,
921919
) -> SmallVec<[Constructor<'tcx>; 1]> {
922920
debug!("subtract_meta_constructor {:?}", self);
@@ -1042,31 +1040,25 @@ impl<'tcx> Constructor<'tcx> {
10421040

10431041
remaining_ctors
10441042
}
1045-
IntRange(..) => {
1046-
let mut remaining_ctors = smallvec![self];
1043+
IntRange(range) => {
1044+
let used_ranges = used_ctors.iter().flat_map(IntRange::from_ctor);
1045+
let mut remaining_ranges: SmallVec<[IntRange<'tcx>; 1]> = smallvec![range];
10471046

10481047
// For each used ctor, subtract from the current set of constructors.
1049-
for used_ctor in used_ctors {
1050-
remaining_ctors = remaining_ctors
1048+
for used_range in used_ranges {
1049+
remaining_ranges = remaining_ranges
10511050
.into_iter()
1052-
.filter(|ctor| ctor != used_ctor)
1053-
.flat_map(|ctor| -> SmallVec<[Constructor<'tcx>; 2]> {
1054-
if let Some(interval) = IntRange::from_ctor(tcx, param_env, used_ctor) {
1055-
interval.subtract_from(tcx, param_env, ctor)
1056-
} else {
1057-
smallvec![ctor]
1058-
}
1059-
})
1051+
.flat_map(|range| used_range.subtract_from(range))
10601052
.collect();
10611053

10621054
// If the constructors that have been considered so far already cover
10631055
// the entire range of `self`, no need to look at more constructors.
1064-
if remaining_ctors.is_empty() {
1056+
if remaining_ranges.is_empty() {
10651057
break;
10661058
}
10671059
}
10681060

1069-
remaining_ctors
1061+
remaining_ranges.into_iter().map(IntRange).collect()
10701062
}
10711063
Wildcard | MissingConstructors(_) => {
10721064
bug!("shouldn't try to subtract constructor {:?}", self)
@@ -1513,6 +1505,10 @@ struct IntRange<'tcx> {
15131505
}
15141506

15151507
impl<'tcx> IntRange<'tcx> {
1508+
fn new(ty: Ty<'tcx>, range: RangeInclusive<u128>) -> Self {
1509+
IntRange { ty, range }
1510+
}
1511+
15161512
#[inline]
15171513
fn is_integral(ty: Ty<'_>) -> bool {
15181514
match ty.kind {
@@ -1597,11 +1593,7 @@ impl<'tcx> IntRange<'tcx> {
15971593
}
15981594
}
15991595

1600-
fn from_ctor(
1601-
_tcx: TyCtxt<'tcx>,
1602-
_param_env: ty::ParamEnv<'tcx>,
1603-
ctor: &Constructor<'tcx>,
1604-
) -> Option<IntRange<'tcx>> {
1596+
fn from_ctor(ctor: &Constructor<'tcx>) -> Option<IntRange<'tcx>> {
16051597
match ctor {
16061598
IntRange(range) => Some(range.clone()),
16071599
_ => None,
@@ -1619,15 +1611,6 @@ impl<'tcx> IntRange<'tcx> {
16191611
}
16201612
}
16211613

1622-
/// Converts a `RangeInclusive` to a `Constructor`.
1623-
fn range_to_ctor(
1624-
_tcx: TyCtxt<'tcx>,
1625-
ty: Ty<'tcx>,
1626-
range: RangeInclusive<u128>,
1627-
) -> Constructor<'tcx> {
1628-
IntRange(IntRange { ty, range })
1629-
}
1630-
16311614
/// Converts an `IntRange` to a `PatKind::Constant` or inclusive `PatKind::Range`.
16321615
fn to_patkind(&self, tcx: TyCtxt<'tcx>) -> PatKind<'tcx> {
16331616
let bias = IntRange::signed_bias(tcx, self.ty);
@@ -1648,16 +1631,8 @@ impl<'tcx> IntRange<'tcx> {
16481631

16491632
/// Returns a collection of ranges that spans the values covered by `ctor`, subtracted
16501633
/// by the values covered by `self`: i.e., `ctor \ self` (in set notation).
1651-
fn subtract_from(
1652-
&self,
1653-
tcx: TyCtxt<'tcx>,
1654-
param_env: ty::ParamEnv<'tcx>,
1655-
ctor: Constructor<'tcx>,
1656-
) -> SmallVec<[Constructor<'tcx>; 2]> {
1657-
let range = match IntRange::from_ctor(tcx, param_env, &ctor) {
1658-
None => return smallvec![],
1659-
Some(int_range) => int_range.range,
1660-
};
1634+
fn subtract_from(&self, other: Self) -> SmallVec<[Self; 2]> {
1635+
let range = other.range;
16611636

16621637
let ty = self.ty;
16631638
let (lo, hi) = (*self.range.start(), *self.range.end());
@@ -1666,17 +1641,17 @@ impl<'tcx> IntRange<'tcx> {
16661641
if lo > range_hi || range_lo > hi {
16671642
// The pattern doesn't intersect with the range at all,
16681643
// so the range remains untouched.
1669-
remaining_ranges.push(Self::range_to_ctor(tcx, ty, range_lo..=range_hi));
1644+
remaining_ranges.push(Self::new(ty, range_lo..=range_hi));
16701645
} else {
16711646
if lo > range_lo {
16721647
// The pattern intersects an upper section of the
16731648
// range, so a lower section will remain.
1674-
remaining_ranges.push(Self::range_to_ctor(tcx, ty, range_lo..=(lo - 1)));
1649+
remaining_ranges.push(Self::new(ty, range_lo..=(lo - 1)));
16751650
}
16761651
if hi < range_hi {
16771652
// The pattern intersects a lower section of the
16781653
// range, so an upper section will remain.
1679-
remaining_ranges.push(Self::range_to_ctor(tcx, ty, (hi + 1)..=range_hi));
1654+
remaining_ranges.push(Self::new(ty, (hi + 1)..=range_hi));
16801655
}
16811656
}
16821657
remaining_ranges

0 commit comments

Comments
 (0)