Skip to content

Commit 1aa7494

Browse files
committed
Introduce signed_bias method
The epitome of simplicity!
1 parent 72cc4bd commit 1aa7494

File tree

1 file changed

+21
-45
lines changed

1 file changed

+21
-45
lines changed

src/librustc_mir/hair/pattern/_match.rs

Lines changed: 21 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ use super::{PatternFoldable, PatternFolder, compare_const_vals};
2121
use rustc::hir::def_id::DefId;
2222
use rustc::hir::RangeEnd;
2323
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
24+
use rustc::ty::layout::{Integer, IntegerExt};
2425

2526
use rustc::mir::Field;
2627
use rustc::mir::interpret::ConstValue;
2728
use rustc::util::common::ErrorReported;
2829

30+
use syntax::attr::{SignedInt, UnsignedInt};
2931
use syntax_pos::{Span, DUMMY_SP};
3032

3133
use arena::TypedArena;
@@ -469,21 +471,19 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
469471
ConstantRange(endpoint('\u{E000}'), endpoint('\u{10FFFF}'), RangeEnd::Included),
470472
]
471473
}
472-
ty::TyInt(_) if exhaustive_integer_patterns => {
474+
ty::TyInt(ity) if exhaustive_integer_patterns => {
473475
// FIXME(49937): refactor these bit manipulations into interpret.
474-
let bits = cx.tcx.layout_of(ty::ParamEnv::reveal_all().and(pcx.ty))
475-
.unwrap().size.bits() as u128;
476+
let bits = Integer::from_attr(cx.tcx, SignedInt(ity)).size().bits() as u128;
476477
let min = 1u128 << (bits - 1);
477478
let max = (1u128 << (bits - 1)) - 1;
478479
value_constructors = true;
479480
vec![ConstantRange(ty::Const::from_bits(cx.tcx, min as u128, pcx.ty),
480481
ty::Const::from_bits(cx.tcx, max as u128, pcx.ty),
481482
RangeEnd::Included)]
482483
}
483-
ty::TyUint(_) if exhaustive_integer_patterns => {
484+
ty::TyUint(uty) if exhaustive_integer_patterns => {
484485
// FIXME(49937): refactor these bit manipulations into interpret.
485-
let bits = cx.tcx.layout_of(ty::ParamEnv::reveal_all().and(pcx.ty))
486-
.unwrap().size.bits() as u128;
486+
let bits = Integer::from_attr(cx.tcx, UnsignedInt(uty)).size().bits() as u128;
487487
let max = !0u128 >> (128 - bits);
488488
value_constructors = true;
489489
vec![ConstantRange(ty::Const::from_bits(cx.tcx, 0, pcx.ty),
@@ -627,7 +627,8 @@ impl<'tcx> IntRange<'tcx> {
627627
if let Some(hi) = hi.assert_bits(ty) {
628628
// Perform a shift if the underlying types are signed,
629629
// which makes the interval arithmetic simpler.
630-
let (lo, hi) = Self::encode(tcx, ty, (lo, hi));
630+
let bias = IntRange::signed_bias(tcx, ty);
631+
let (lo, hi) = (lo ^ bias, hi ^ bias);
631632
// Make sure the interval is well-formed.
632633
return if lo > hi || lo == hi && *end == RangeEnd::Excluded {
633634
None
@@ -642,8 +643,9 @@ impl<'tcx> IntRange<'tcx> {
642643
ConstantValue(val) => {
643644
let ty = val.ty;
644645
if let Some(val) = val.assert_bits(ty) {
645-
let (lo, hi) = Self::encode(tcx, ty, (val, val));
646-
Some(IntRange { range: lo..=hi, ty })
646+
let bias = IntRange::signed_bias(tcx, ty);
647+
let val = val ^ bias;
648+
Some(IntRange { range: val..=val, ty })
647649
} else {
648650
None
649651
}
@@ -654,46 +656,16 @@ impl<'tcx> IntRange<'tcx> {
654656
}
655657
}
656658

657-
fn encode(tcx: TyCtxt<'_, 'tcx, 'tcx>,
658-
ty: Ty<'tcx>,
659-
(lo, hi): (u128, u128))
660-
-> (u128, u128) {
659+
fn signed_bias(tcx: TyCtxt<'_, 'tcx, 'tcx>, ty: Ty<'tcx>) -> u128 {
661660
match ty.sty {
662-
ty::TyInt(_) => {
663-
// FIXME(49937): refactor these bit manipulations into interpret.
664-
let bits = tcx.layout_of(ty::ParamEnv::reveal_all().and(ty))
665-
.unwrap().size.bits() as u128;
666-
let min = 1u128 << (bits - 1);
667-
let mask = !0u128 >> (128 - bits);
668-
let offset = |x: u128| x.wrapping_sub(min) & mask;
669-
(offset(lo), offset(hi))
661+
ty::TyInt(ity) => {
662+
let bits = Integer::from_attr(tcx, SignedInt(ity)).size().bits() as u128;
663+
1u128 << (bits - 1)
670664
}
671-
_ => (lo, hi)
665+
_ => 0
672666
}
673667
}
674668

675-
fn decode(tcx: TyCtxt<'_, 'tcx, 'tcx>,
676-
ty: Ty<'tcx>,
677-
range: RangeInclusive<u128>)
678-
-> Constructor<'tcx> {
679-
let (lo, hi) = range.into_inner();
680-
let (lo, hi) = match ty.sty {
681-
ty::TyInt(_) => {
682-
// FIXME(49937): refactor these bit manipulations into interpret.
683-
let bits = tcx.layout_of(ty::ParamEnv::reveal_all().and(ty))
684-
.unwrap().size.bits() as u128;
685-
let min = 1u128 << (bits - 1);
686-
let mask = !0u128 >> (128 - bits);
687-
let offset = |x: u128| x.wrapping_add(min) & mask;
688-
(offset(lo), offset(hi))
689-
}
690-
_ => (lo, hi)
691-
};
692-
ConstantRange(ty::Const::from_bits(tcx, lo, ty),
693-
ty::Const::from_bits(tcx, hi, ty),
694-
RangeEnd::Included)
695-
}
696-
697669
fn into_inner(self) -> (u128, u128) {
698670
self.range.into_inner()
699671
}
@@ -733,7 +705,11 @@ fn ranges_subtract_pattern<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
733705
}
734706
// Convert the remaining ranges from pairs to inclusive `ConstantRange`s.
735707
remaining_ranges.into_iter().map(|r| {
736-
IntRange::decode(cx.tcx, ty, r)
708+
let (lo, hi) = r.into_inner();
709+
let bias = IntRange::signed_bias(cx.tcx, ty);
710+
ConstantRange(ty::Const::from_bits(cx.tcx, lo ^ bias, ty),
711+
ty::Const::from_bits(cx.tcx, hi ^ bias, ty),
712+
RangeEnd::Included)
737713
}).collect()
738714
} else {
739715
ranges

0 commit comments

Comments
 (0)