Skip to content

Commit a047284

Browse files
committed
Make MaybeInfiniteInt::plus_one/minus_one fallible
1 parent 4282576 commit a047284

File tree

3 files changed

+23
-20
lines changed

3 files changed

+23
-20
lines changed

compiler/rustc_pattern_analysis/src/constructor.rs

+19-16
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ impl fmt::Display for RangeEnd {
192192
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
193193
pub enum MaybeInfiniteInt {
194194
NegInfinity,
195-
/// Encoded value. DO NOT CONSTRUCT BY HAND; use `new_finite`.
195+
/// Encoded value. DO NOT CONSTRUCT BY HAND; use `new_finite_{int,uint}`.
196196
#[non_exhaustive]
197197
Finite(u128),
198198
/// The integer after `u128::MAX`. We need it to represent `x..=u128::MAX` as an exclusive range.
@@ -229,25 +229,22 @@ impl MaybeInfiniteInt {
229229
}
230230

231231
/// Note: this will not turn a finite value into an infinite one or vice-versa.
232-
pub fn minus_one(self) -> Self {
232+
pub fn minus_one(self) -> Option<Self> {
233233
match self {
234-
Finite(n) => match n.checked_sub(1) {
235-
Some(m) => Finite(m),
236-
None => panic!("Called `MaybeInfiniteInt::minus_one` on 0"),
237-
},
238-
JustAfterMax => Finite(u128::MAX),
239-
x => x,
234+
Finite(n) => n.checked_sub(1).map(Finite),
235+
JustAfterMax => Some(Finite(u128::MAX)),
236+
x => Some(x),
240237
}
241238
}
242239
/// Note: this will not turn a finite value into an infinite one or vice-versa.
243-
pub fn plus_one(self) -> Self {
240+
pub fn plus_one(self) -> Option<Self> {
244241
match self {
245242
Finite(n) => match n.checked_add(1) {
246-
Some(m) => Finite(m),
247-
None => JustAfterMax,
243+
Some(m) => Some(Finite(m)),
244+
None => Some(JustAfterMax),
248245
},
249-
JustAfterMax => panic!("Called `MaybeInfiniteInt::plus_one` on u128::MAX+1"),
250-
x => x,
246+
JustAfterMax => None,
247+
x => Some(x),
251248
}
252249
}
253250
}
@@ -268,18 +265,24 @@ impl IntRange {
268265
pub fn is_singleton(&self) -> bool {
269266
// Since `lo` and `hi` can't be the same `Infinity` and `plus_one` never changes from finite
270267
// to infinite, this correctly only detects ranges that contain exacly one `Finite(x)`.
271-
self.lo.plus_one() == self.hi
268+
self.lo.plus_one() == Some(self.hi)
272269
}
273270

271+
/// Construct a singleton range.
272+
/// `x` must be a `Finite(_)` value.
274273
#[inline]
275274
pub fn from_singleton(x: MaybeInfiniteInt) -> IntRange {
276-
IntRange { lo: x, hi: x.plus_one() }
275+
// `unwrap()` is ok on a finite value
276+
IntRange { lo: x, hi: x.plus_one().unwrap() }
277277
}
278278

279+
/// Construct a range with these boundaries.
280+
/// `lo` must not be `PosInfinity` or `JustAfterMax`. `hi` must not be `NegInfinity`.
281+
/// If `end` is `Included`, `hi` must also not be `JustAfterMax`.
279282
#[inline]
280283
pub fn from_range(lo: MaybeInfiniteInt, mut hi: MaybeInfiniteInt, end: RangeEnd) -> IntRange {
281284
if end == RangeEnd::Included {
282-
hi = hi.plus_one();
285+
hi = hi.plus_one().unwrap();
283286
}
284287
if lo >= hi {
285288
// This should have been caught earlier by E0030.

compiler/rustc_pattern_analysis/src/rustc.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -718,12 +718,12 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
718718
let value = mir::Const::from_ty_const(c, cx.tcx);
719719
lo = PatRangeBoundary::Finite(value);
720720
}
721-
let hi = if matches!(range.hi, Finite(0)) {
721+
let hi = if let Some(hi) = range.hi.minus_one() {
722+
hi
723+
} else {
722724
// The range encodes `..ty::MIN`, so we can't convert it to an inclusive range.
723725
end = rustc_hir::RangeEnd::Excluded;
724726
range.hi
725-
} else {
726-
range.hi.minus_one()
727727
};
728728
let hi = cx.hoist_pat_range_bdy(hi, ty);
729729
PatKind::Range(Box::new(PatRange { lo, hi, end, ty: ty.inner() }))

compiler/rustc_pattern_analysis/src/usefulness.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1526,7 +1526,7 @@ fn collect_overlapping_range_endpoints<'p, Cx: TypeCx>(
15261526
}
15271527
}
15281528
suffixes.push((child_row_id, pat))
1529-
} else if this_range.hi == overlap.plus_one() {
1529+
} else if Some(this_range.hi) == overlap.plus_one() {
15301530
// `this_range` looks like `this_range.lo..=overlap`; it overlaps with any
15311531
// ranges that look like `overlap..=hi`.
15321532
if !suffixes.is_empty() {

0 commit comments

Comments
 (0)