Skip to content

Commit 8f7ba7a

Browse files
committed
Clarify conditions for exhaustive integer range matching
1 parent c75685b commit 8f7ba7a

File tree

1 file changed

+20
-17
lines changed

1 file changed

+20
-17
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,17 @@ impl<'tcx> Constructor<'tcx> {
630630
}
631631
}
632632

633+
// Whether to evaluate a constructor using exhaustive integer matching. This is true if the
634+
// constructor is a range or constant with an integer type.
635+
fn is_range_and_should_match_exhaustively(&self, tcx: TyCtxt<'tcx>) -> bool {
636+
let ty = match self {
637+
ConstantValue(value, _) => value.ty,
638+
ConstantRange(_, _, ty, _, _) => ty,
639+
_ => return false,
640+
};
641+
IntRange::should_treat_range_exhaustively(tcx, ty)
642+
}
643+
633644
fn variant_index_for_adt<'a>(
634645
&self,
635646
cx: &MatchCheckCtxt<'a, 'tcx>,
@@ -1280,6 +1291,13 @@ impl<'tcx> IntRange<'tcx> {
12801291
}
12811292
}
12821293

1294+
fn should_treat_range_exhaustively(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
1295+
// Don't treat `usize`/`isize` exhaustively unless the `precise_pointer_size_matching`
1296+
// feature is enabled.
1297+
IntRange::is_integral(ty)
1298+
&& (!ty.is_ptr_sized_integral() || tcx.features().precise_pointer_size_matching)
1299+
}
1300+
12831301
#[inline]
12841302
fn integral_size_and_signed_bias(tcx: TyCtxt<'tcx>, ty: Ty<'_>) -> Option<(Size, u128)> {
12851303
match ty.kind {
@@ -1857,21 +1875,6 @@ fn slice_pat_covered_by_const<'tcx>(
18571875
Ok(true)
18581876
}
18591877

1860-
// Whether to evaluate a constructor using exhaustive integer matching. This is true if the
1861-
// constructor is a range or constant with an integer type.
1862-
fn should_treat_range_exhaustively(tcx: TyCtxt<'tcx>, ctor: &Constructor<'tcx>) -> bool {
1863-
let ty = match ctor {
1864-
ConstantValue(value, _) => value.ty,
1865-
ConstantRange(_, _, ty, _, _) => ty,
1866-
_ => return false,
1867-
};
1868-
if let ty::Char | ty::Int(_) | ty::Uint(_) = ty.kind {
1869-
!ty.is_ptr_sized_integral() || tcx.features().precise_pointer_size_matching
1870-
} else {
1871-
false
1872-
}
1873-
}
1874-
18751878
/// For exhaustive integer matching, some constructors are grouped within other constructors
18761879
/// (namely integer typed values are grouped within ranges). However, when specialising these
18771880
/// constructors, we want to be specialising for the underlying constructors (the integers), not
@@ -1923,7 +1926,7 @@ fn split_grouped_constructors<'p, 'tcx>(
19231926

19241927
for ctor in ctors.into_iter() {
19251928
match ctor {
1926-
ConstantRange(..) if should_treat_range_exhaustively(tcx, &ctor) => {
1929+
ConstantRange(..) if ctor.is_range_and_should_match_exhaustively(tcx) => {
19271930
// We only care about finding all the subranges within the range of the constructor
19281931
// range. Anything else is irrelevant, because it is guaranteed to result in
19291932
// `NotUseful`, which is the default case anyway, and can be ignored.
@@ -2342,7 +2345,7 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
23422345
// If the constructor is a:
23432346
// - Single value: add a row if the pattern contains the constructor.
23442347
// - Range: add a row if the constructor intersects the pattern.
2345-
if should_treat_range_exhaustively(cx.tcx, constructor) {
2348+
if constructor.is_range_and_should_match_exhaustively(cx.tcx) {
23462349
match (
23472350
IntRange::from_ctor(cx.tcx, cx.param_env, constructor),
23482351
IntRange::from_pat(cx.tcx, cx.param_env, pat),

0 commit comments

Comments
 (0)