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:
parent
7e4ec35d0c
commit
c4cd04480b
1 changed files with 18 additions and 24 deletions
|
@ -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 = (|| {
|
let tcx = self.tcx;
|
||||||
use rustc_hir::RangeEnd::*;
|
let test_ty = test.lo.ty();
|
||||||
use std::cmp::Ordering::*;
|
|
||||||
|
|
||||||
let tcx = self.tcx;
|
// For performance, it's important to only do the second
|
||||||
|
// `compare_const_vals` if necessary.
|
||||||
let test_ty = test.lo.ty();
|
let no_overlap = if matches!(
|
||||||
let lo = compare_const_vals(tcx, test.lo, pat.hi, self.param_env, test_ty)?;
|
(compare_const_vals(tcx, test.hi, pat.lo, self.param_env, test_ty)?, test.end),
|
||||||
let hi = compare_const_vals(tcx, test.hi, pat.lo, self.param_env, test_ty)?;
|
(Less, _) | (Equal, RangeEnd::Excluded) // test < pat
|
||||||
|
) || matches!(
|
||||||
match (test.end, pat.end, lo, hi) {
|
(compare_const_vals(tcx, test.lo, pat.hi, self.param_env, test_ty)?, pat.end),
|
||||||
// pat < test
|
(Greater, _) | (Equal, RangeEnd::Excluded) // test > pat
|
||||||
(_, _, Greater, _) |
|
) {
|
||||||
(_, Excluded, Equal, _) |
|
|
||||||
// pat > test
|
|
||||||
(_, _, _, Less) |
|
|
||||||
(Excluded, _, _, Equal) => Some(true),
|
|
||||||
_ => Some(false),
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
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 }) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue