Skip to content

Commit f4af3b0

Browse files
committed
Refactor to remove explicit integer type matching
1 parent 8389972 commit f4af3b0

File tree

1 file changed

+22
-46
lines changed

1 file changed

+22
-46
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 22 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,6 @@ impl<'a, 'tcx> FromIterator<Vec<&'a Pattern<'tcx>>> for Matrix<'a, 'tcx> {
138138
}
139139
}
140140

141-
//NOTE: appears to be the only place other then InferCtxt to contain a ParamEnv
142141
pub struct MatchCheckCtxt<'a, 'tcx: 'a> {
143142
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
144143
/// The module in which the match occurs. This is necessary for
@@ -470,48 +469,24 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
470469
ConstantRange(endpoint('\u{E000}'), endpoint('\u{10FFFF}'), RangeEnd::Included),
471470
]
472471
}
473-
ty::TyInt(int_ty) if exhaustive_integer_patterns => {
474-
use syntax::ast::IntTy::*;
475-
let min_max_ty = |sty| {
476-
let size = cx.tcx.layout_of(ty::ParamEnv::reveal_all().and(sty))
477-
.unwrap().size.bits() as i128;
478-
let min = (1i128 << (size - 1)).wrapping_neg();
479-
let max = (1i128 << (size - 1)).wrapping_sub(1);
480-
(min as u128, max as u128, sty)
481-
};
482-
let (min, max, ty) = match int_ty {
483-
Isize => min_max_ty(cx.tcx.types.isize),
484-
I8 => min_max_ty(cx.tcx.types.i8),
485-
I16 => min_max_ty(cx.tcx.types.i16),
486-
I32 => min_max_ty(cx.tcx.types.i32),
487-
I64 => min_max_ty(cx.tcx.types.i64),
488-
I128 => min_max_ty(cx.tcx.types.i128),
489-
};
472+
ty::TyInt(_) if exhaustive_integer_patterns => {
473+
let size = cx.tcx.layout_of(ty::ParamEnv::reveal_all().and(pcx.ty))
474+
.unwrap().size.bits() as i128;
475+
let min = (1i128 << (size - 1)).wrapping_neg();
476+
let max = (1i128 << (size - 1)).wrapping_sub(1);
490477
value_constructors = true;
491-
vec![ConstantRange(ty::Const::from_bits(cx.tcx, min, ty),
492-
ty::Const::from_bits(cx.tcx, max, ty),
478+
vec![ConstantRange(ty::Const::from_bits(cx.tcx, min as u128, pcx.ty),
479+
ty::Const::from_bits(cx.tcx, max as u128, pcx.ty),
493480
RangeEnd::Included)]
494481
}
495-
ty::TyUint(uint_ty) if exhaustive_integer_patterns => {
496-
use syntax::ast::UintTy::*;
497-
let min_max_ty = |sty| {
498-
let size = cx.tcx.layout_of(ty::ParamEnv::reveal_all().and(sty))
499-
.unwrap().size.bits() as u32;
500-
let shift = 1u128.overflowing_shl(size);
501-
let max = shift.0.wrapping_sub(1 + (shift.1 as u128));
502-
(0u128, max as u128, sty)
503-
};
504-
let (min, max, ty) = match uint_ty {
505-
Usize => min_max_ty(cx.tcx.types.usize),
506-
U8 => min_max_ty(cx.tcx.types.u8),
507-
U16 => min_max_ty(cx.tcx.types.u16),
508-
U32 => min_max_ty(cx.tcx.types.u32),
509-
U64 => min_max_ty(cx.tcx.types.u64),
510-
U128 => min_max_ty(cx.tcx.types.u128),
511-
};
482+
ty::TyUint(_) if exhaustive_integer_patterns => {
483+
let size = cx.tcx.layout_of(ty::ParamEnv::reveal_all().and(pcx.ty))
484+
.unwrap().size.bits() as u32;
485+
let shift = 1u128.overflowing_shl(size);
486+
let max = shift.0.wrapping_sub(1 + (shift.1 as u128));
512487
value_constructors = true;
513-
vec![ConstantRange(ty::Const::from_bits(cx.tcx, min, ty),
514-
ty::Const::from_bits(cx.tcx, max, ty),
488+
vec![ConstantRange(ty::Const::from_bits(cx.tcx, 0u128, pcx.ty),
489+
ty::Const::from_bits(cx.tcx, max as u128, pcx.ty),
515490
RangeEnd::Included)]
516491
}
517492
_ => {
@@ -643,7 +618,7 @@ impl<'tcx> Interval<'tcx> {
643618
if let Some(hi) = hi.assert_bits(ty) {
644619
// Perform a shift if the underlying types are signed,
645620
// which makes the interval arithmetic simpler.
646-
let (lo, hi) = Interval::offset_sign(ty, (lo, hi), true);
621+
let (lo, hi) = Interval::offset_sign(ty, lo..=hi, true);
647622
// Make sure the interval is well-formed.
648623
return if lo > hi || lo == hi && *end == RangeEnd::Excluded {
649624
None
@@ -665,7 +640,8 @@ impl<'tcx> Interval<'tcx> {
665640
}
666641
}
667642

668-
fn offset_sign(ty: Ty<'tcx>, (lo, hi): (u128, u128), forwards: bool) -> (u128, u128) {
643+
fn offset_sign(ty: Ty<'tcx>, range: RangeInclusive<u128>, forwards: bool) -> (u128, u128) {
644+
let (lo, hi) = range.into_inner();
669645
use syntax::ast::IntTy::*;
670646
match ty.sty {
671647
ty::TyInt(int_ty) => {
@@ -720,23 +696,23 @@ fn ranges_subtract_pattern<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
720696
if pat_interval_lo > subrange_hi || subrange_lo > pat_interval_hi {
721697
// The pattern doesn't intersect with the subrange at all,
722698
// so the subrange remains untouched.
723-
remaining_ranges.push((subrange_lo, subrange_hi));
699+
remaining_ranges.push(subrange_lo..=subrange_hi);
724700
} else {
725701
if pat_interval_lo > subrange_lo {
726702
// The pattern intersects an upper section of the
727703
// subrange, so a lower section will remain.
728-
remaining_ranges.push((subrange_lo, pat_interval_lo - 1));
704+
remaining_ranges.push(subrange_lo..=(pat_interval_lo - 1));
729705
}
730706
if pat_interval_hi < subrange_hi {
731707
// The pattern intersects a lower section of the
732708
// subrange, so an upper section will remain.
733-
remaining_ranges.push((pat_interval_hi + 1, subrange_hi));
709+
remaining_ranges.push((pat_interval_hi + 1)..=subrange_hi);
734710
}
735711
}
736712
}
737713
// Convert the remaining ranges from pairs to inclusive `ConstantRange`s.
738-
remaining_ranges.into_iter().map(|(lo, hi)| {
739-
let (lo, hi) = Interval::offset_sign(ty, (lo, hi), false);
714+
remaining_ranges.into_iter().map(|r| {
715+
let (lo, hi) = Interval::offset_sign(ty, r, false);
740716
ConstantRange(ty::Const::from_bits(cx.tcx, lo, ty),
741717
ty::Const::from_bits(cx.tcx, hi, ty),
742718
RangeEnd::Included)

0 commit comments

Comments
 (0)