Skip to content

Commit 1c5401d

Browse files
committed
Skip unnecessary comparison with half-open ranges
1 parent 29f87ad commit 1c5401d

File tree

2 files changed

+30
-38
lines changed
  • compiler

2 files changed

+30
-38
lines changed

compiler/rustc_middle/src/thir.rs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -958,22 +958,6 @@ impl<'tcx> PatRangeBoundary<'tcx> {
958958
Self::NegInfinity | Self::PosInfinity => None,
959959
}
960960
}
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-
}
977961
pub fn eval_bits(self, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> u128 {
978962
match self {
979963
Self::Finite(value) => value.eval_bits(tcx, param_env),

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

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -318,33 +318,41 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
318318
}
319319

320320
TestKind::Range(ref range) => {
321-
let lower_bound_success = self.cfg.start_new_block();
322-
321+
let [success, fail] = *target_blocks else {
322+
bug!("`TestKind::Range` should have two target blocks");
323+
};
323324
// Test `val` by computing `lo <= val && val <= hi`, using primitive comparisons.
324-
// FIXME: skip useless comparison when the range is half-open.
325-
let lo = range.lo.to_const(range.ty, self.tcx);
326-
let hi = range.hi.to_const(range.ty, self.tcx);
327-
let lo = self.literal_operand(test.span, lo);
328-
let hi = self.literal_operand(test.span, hi);
329325
let val = Operand::Copy(place);
330326

331-
let [success, fail] = *target_blocks else {
332-
bug!("`TestKind::Range` should have two target blocks");
327+
let intermediate_block = if !range.lo.is_finite() {
328+
block
329+
} else if !range.hi.is_finite() {
330+
success
331+
} else {
332+
self.cfg.start_new_block()
333333
};
334-
self.compare(
335-
block,
336-
lower_bound_success,
337-
fail,
338-
source_info,
339-
BinOp::Le,
340-
lo,
341-
val.clone(),
342-
);
343-
let op = match range.end {
344-
RangeEnd::Included => BinOp::Le,
345-
RangeEnd::Excluded => BinOp::Lt,
334+
335+
if let Some(lo) = range.lo.as_finite() {
336+
let lo = self.literal_operand(test.span, lo);
337+
self.compare(
338+
block,
339+
intermediate_block,
340+
fail,
341+
source_info,
342+
BinOp::Le,
343+
lo,
344+
val.clone(),
345+
);
346346
};
347-
self.compare(lower_bound_success, success, fail, source_info, op, val, hi);
347+
348+
if let Some(hi) = range.hi.as_finite() {
349+
let hi = self.literal_operand(test.span, hi);
350+
let op = match range.end {
351+
RangeEnd::Included => BinOp::Le,
352+
RangeEnd::Excluded => BinOp::Lt,
353+
};
354+
self.compare(intermediate_block, success, fail, source_info, op, val, hi);
355+
}
348356
}
349357

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

0 commit comments

Comments
 (0)