1
Fork 0

sort_candidates: avoid the second comparison if possible.

This is a performance win for `unicode-normalization`.

The commit also removes the closure, which isn't necessary. And
reformulates the comparison into a form I find easier to read.
This commit is contained in:
Nicholas Nethercote 2022-06-08 17:02:06 +10:00
parent 7e4ec35d0c
commit c4cd04480b

View file

@ -632,39 +632,33 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} }
(&TestKind::Range(test), &PatKind::Range(pat)) => { (&TestKind::Range(test), &PatKind::Range(pat)) => {
use std::cmp::Ordering::*;
if test == pat { if test == pat {
self.candidate_without_match_pair(match_pair_index, candidate); self.candidate_without_match_pair(match_pair_index, candidate);
return Some(0); return Some(0);
} }
let no_overlap = (|| {
use rustc_hir::RangeEnd::*;
use std::cmp::Ordering::*;
let tcx = self.tcx; let tcx = self.tcx;
let test_ty = test.lo.ty(); let test_ty = test.lo.ty();
let lo = compare_const_vals(tcx, test.lo, pat.hi, self.param_env, test_ty)?;
let hi = compare_const_vals(tcx, test.hi, pat.lo, self.param_env, test_ty)?;
match (test.end, pat.end, lo, hi) { // For performance, it's important to only do the second
// pat < test // `compare_const_vals` if necessary.
(_, _, Greater, _) | let no_overlap = if matches!(
(_, Excluded, Equal, _) | (compare_const_vals(tcx, test.hi, pat.lo, self.param_env, test_ty)?, test.end),
// pat > test (Less, _) | (Equal, RangeEnd::Excluded) // test < pat
(_, _, _, Less) | ) || matches!(
(Excluded, _, _, Equal) => Some(true), (compare_const_vals(tcx, test.lo, pat.hi, self.param_env, test_ty)?, pat.end),
_ => Some(false), (Greater, _) | (Equal, RangeEnd::Excluded) // test > pat
} ) {
})();
if let Some(true) = no_overlap {
// Testing range does not overlap with pattern range,
// so the pattern can be matched only if this test fails.
Some(1) Some(1)
} else { } else {
None None
} };
// If the testing range does not overlap with pattern range,
// the pattern can be matched only if this test fails.
no_overlap
} }
(&TestKind::Range(range), &PatKind::Constant { value }) => { (&TestKind::Range(range), &PatKind::Constant { value }) => {