Skip to content

Commit f93a700

Browse files
committed
Introduce IntRange constructor
1 parent 1909e3f commit f93a700

File tree

1 file changed

+28
-8
lines changed

1 file changed

+28
-8
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,10 @@ enum Constructor<'tcx> {
590590
Variant(DefId),
591591
/// Literal values.
592592
ConstantValue(&'tcx ty::Const<'tcx>, Span),
593-
/// Ranges of literal values (`2..=5` and `2..5`).
593+
/// Ranges of integer literal values (`2`, `2..=5` or `2..5`).
594+
IntRange(IntRange<'tcx>),
595+
// TODO: non-integer
596+
/// Ranges of literal values (`2.0..=5.2`).
594597
ConstantRange(u128, u128, Ty<'tcx>, RangeEnd, Span),
595598
/// Array patterns of length `n`.
596599
FixedLenSlice(u64),
@@ -612,6 +615,7 @@ impl<'tcx> std::cmp::PartialEq for Constructor<'tcx> {
612615
Constructor::ConstantRange(a_start, a_end, a_ty, a_range_end, _),
613616
Constructor::ConstantRange(b_start, b_end, b_ty, b_range_end, _),
614617
) => a_start == b_start && a_end == b_end && a_ty == b_ty && a_range_end == b_range_end,
618+
(Constructor::IntRange(a), Constructor::IntRange(b)) => a == b,
615619
(Constructor::FixedLenSlice(a), Constructor::FixedLenSlice(b)) => a == b,
616620
(
617621
Constructor::VarLenSlice(a_prefix, a_suffix),
@@ -634,6 +638,7 @@ impl<'tcx> Constructor<'tcx> {
634638
let ty = match self {
635639
ConstantValue(value, _) => value.ty,
636640
ConstantRange(_, _, ty, _, _) => ty,
641+
IntRange(_) => return true,
637642
_ => return false,
638643
};
639644
IntRange::is_integral(ty)
@@ -743,7 +748,7 @@ impl<'tcx> Constructor<'tcx> {
743748

744749
remaining_ctors
745750
}
746-
ConstantRange(..) | ConstantValue(..) => {
751+
IntRange(..) | ConstantRange(..) | ConstantValue(..) => {
747752
if let Some(self_range) = IntRange::from_ctor(tcx, param_env, self) {
748753
let mut remaining_ranges = vec![self_range.clone()];
749754
let other_ranges = other_ctors
@@ -767,7 +772,7 @@ impl<'tcx> Constructor<'tcx> {
767772
}
768773

769774
// Convert the ranges back into constructors
770-
remaining_ranges.into_iter().map(|range| range.into_ctor(tcx)).collect()
775+
remaining_ranges.into_iter().map(IntRange).collect()
771776
} else {
772777
if other_ctors.iter().any(|c| {
773778
c == self
@@ -855,7 +860,7 @@ impl<'tcx> Constructor<'tcx> {
855860
}
856861
_ => bug!("bad slice pattern {:?} {:?}", self, ty),
857862
},
858-
ConstantValue(..) | ConstantRange(..) | NonExhaustive => vec![],
863+
ConstantValue(..) | ConstantRange(..) | IntRange(..) | NonExhaustive => vec![],
859864
}
860865
}
861866

@@ -880,7 +885,7 @@ impl<'tcx> Constructor<'tcx> {
880885
},
881886
FixedLenSlice(length) => *length,
882887
VarLenSlice(prefix, suffix) => prefix + suffix,
883-
ConstantValue(..) | ConstantRange(..) | NonExhaustive => 0,
888+
ConstantValue(..) | ConstantRange(..) | IntRange(..) | NonExhaustive => 0,
884889
}
885890
}
886891

@@ -949,6 +954,10 @@ impl<'tcx> Constructor<'tcx> {
949954
hi: ty::Const::from_bits(cx.tcx, hi, ty::ParamEnv::empty().and(ty)),
950955
end,
951956
}),
957+
IntRange(range) => {
958+
// TODO: do it more directly
959+
return range.clone().into_ctor(cx.tcx).apply(cx, ty, None.into_iter());
960+
}
952961
NonExhaustive => PatKind::Wild,
953962
};
954963

@@ -1145,7 +1154,14 @@ fn all_constructors<'a, 'tcx>(
11451154
pcx: PatCtxt<'tcx>,
11461155
) -> Vec<Constructor<'tcx>> {
11471156
debug!("all_constructors({:?})", pcx.ty);
1148-
let make_range = |start, end| ConstantRange(start, end, pcx.ty, RangeEnd::Included, pcx.span);
1157+
let make_range = |start, end| {
1158+
IntRange(
1159+
// `unwrap()` is ok because we know the type is an integer and the range is
1160+
// well-formed.
1161+
IntRange::from_range(cx.tcx, start, end, pcx.ty, &RangeEnd::Included, pcx.span)
1162+
.unwrap(),
1163+
)
1164+
};
11491165
match pcx.ty.kind {
11501166
ty::Bool => [true, false]
11511167
.iter()
@@ -1356,6 +1372,7 @@ impl<'tcx> IntRange<'tcx> {
13561372
match ctor {
13571373
ConstantRange(lo, hi, ty, end, span) => Self::from_range(tcx, *lo, *hi, ty, end, *span),
13581374
ConstantValue(val, span) => Self::from_const(tcx, param_env, val, *span),
1375+
IntRange(range) => Some(range.clone()),
13591376
_ => None,
13601377
}
13611378
}
@@ -1381,6 +1398,7 @@ impl<'tcx> IntRange<'tcx> {
13811398
}
13821399

13831400
/// Converts an `IntRange` to a `ConstantValue` or inclusive `ConstantRange`.
1401+
/// TODO: Deprecated
13841402
fn into_ctor(self, tcx: TyCtxt<'tcx>) -> Constructor<'tcx> {
13851403
let bias = IntRange::signed_bias(tcx, self.ty);
13861404
let (lo, hi) = self.range.into_inner();
@@ -1889,7 +1907,9 @@ fn split_grouped_constructors<'p, 'tcx>(
18891907

18901908
for ctor in ctors.into_iter() {
18911909
match ctor {
1892-
ConstantRange(..) if IntRange::should_treat_range_exhaustively(tcx, ty) => {
1910+
IntRange(..) | ConstantRange(..)
1911+
if IntRange::should_treat_range_exhaustively(tcx, ty) =>
1912+
{
18931913
// We only care about finding all the subranges within the range of the constructor
18941914
// range. Anything else is irrelevant, because it is guaranteed to result in
18951915
// `NotUseful`, which is the default case anyway, and can be ignored.
@@ -1968,7 +1988,7 @@ fn split_grouped_constructors<'p, 'tcx>(
19681988
}
19691989
(Border::AfterMax, _) => None,
19701990
})
1971-
.map(|range| range.into_ctor(tcx)),
1991+
.map(IntRange),
19721992
);
19731993
}
19741994
VarLenSlice(self_prefix, self_suffix) => {

0 commit comments

Comments
 (0)