Skip to content

Commit 64fe0d8

Browse files
authored
Unrolled build for rust-lang#121376
Rollup merge of rust-lang#121376 - Nadrieril:mir-half-ranges, r=pnkfelix Skip unnecessary comparison with half-open range patterns This is the last remaining detail in the implementation of half-open range patterns. Until now, a half-open range pattern like `10..` was converted to `10..T::MAX` before lowering to MIR, which generated an extra pointless comparison. With this PR we don't generate it.
2 parents 384d26f + 7c6960e commit 64fe0d8

File tree

2 files changed

+32
-38
lines changed
  • compiler

2 files changed

+32
-38
lines changed

compiler/rustc_middle/src/thir.rs

+2-16
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,9 @@ pub enum PatKind<'tcx> {
815815
/// The boundaries must be of the same type and that type must be numeric.
816816
#[derive(Clone, Debug, PartialEq, HashStable, TypeVisitable)]
817817
pub struct PatRange<'tcx> {
818+
/// Must not be `PosInfinity`.
818819
pub lo: PatRangeBoundary<'tcx>,
820+
/// Must not be `NegInfinity`.
819821
pub hi: PatRangeBoundary<'tcx>,
820822
#[type_visitable(ignore)]
821823
pub end: RangeEnd,
@@ -958,22 +960,6 @@ impl<'tcx> PatRangeBoundary<'tcx> {
958960
Self::NegInfinity | Self::PosInfinity => None,
959961
}
960962
}
961-
#[inline]
962-
pub fn to_const(self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> mir::Const<'tcx> {
963-
match self {
964-
Self::Finite(value) => value,
965-
Self::NegInfinity => {
966-
// Unwrap is ok because the type is known to be numeric.
967-
let c = ty.numeric_min_val(tcx).unwrap();
968-
mir::Const::from_ty_const(c, tcx)
969-
}
970-
Self::PosInfinity => {
971-
// Unwrap is ok because the type is known to be numeric.
972-
let c = ty.numeric_max_val(tcx).unwrap();
973-
mir::Const::from_ty_const(c, tcx)
974-
}
975-
}
976-
}
977963
pub fn eval_bits(self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> u128 {
978964
match self {
979965
Self::Finite(value) => value.eval_bits(tcx, param_env),

compiler/rustc_mir_build/src/build/matches/test.rs

+30-22
Original file line numberDiff line numberDiff line change
@@ -291,33 +291,41 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
291291
}
292292

293293
TestKind::Range(ref range) => {
294-
let lower_bound_success = self.cfg.start_new_block();
295-
294+
let [success, fail] = *target_blocks else {
295+
bug!("`TestKind::Range` should have two target blocks");
296+
};
296297
// Test `val` by computing `lo <= val && val <= hi`, using primitive comparisons.
297-
// FIXME: skip useless comparison when the range is half-open.
298-
let lo = range.lo.to_const(range.ty, self.tcx);
299-
let hi = range.hi.to_const(range.ty, self.tcx);
300-
let lo = self.literal_operand(test.span, lo);
301-
let hi = self.literal_operand(test.span, hi);
302298
let val = Operand::Copy(place);
303299

304-
let [success, fail] = *target_blocks else {
305-
bug!("`TestKind::Range` should have two target blocks");
300+
let intermediate_block = if !range.lo.is_finite() {
301+
block
302+
} else if !range.hi.is_finite() {
303+
success
304+
} else {
305+
self.cfg.start_new_block()
306306
};
307-
self.compare(
308-
block,
309-
lower_bound_success,
310-
fail,
311-
source_info,
312-
BinOp::Le,
313-
lo,
314-
val.clone(),
315-
);
316-
let op = match range.end {
317-
RangeEnd::Included => BinOp::Le,
318-
RangeEnd::Excluded => BinOp::Lt,
307+
308+
if let Some(lo) = range.lo.as_finite() {
309+
let lo = self.literal_operand(test.span, lo);
310+
self.compare(
311+
block,
312+
intermediate_block,
313+
fail,
314+
source_info,
315+
BinOp::Le,
316+
lo,
317+
val.clone(),
318+
);
319319
};
320-
self.compare(lower_bound_success, success, fail, source_info, op, val, hi);
320+
321+
if let Some(hi) = range.hi.as_finite() {
322+
let hi = self.literal_operand(test.span, hi);
323+
let op = match range.end {
324+
RangeEnd::Included => BinOp::Le,
325+
RangeEnd::Excluded => BinOp::Lt,
326+
};
327+
self.compare(intermediate_block, success, fail, source_info, op, val, hi);
328+
}
321329
}
322330

323331
TestKind::Len { len, op } => {

0 commit comments

Comments
 (0)