Inline and remove constructor_intersects_pattern().
This is a 2% instruction count win on `unicode_normalization-check-clean`.
This commit is contained in:
parent
9a1a3b9013
commit
62ea39a1c9
1 changed files with 26 additions and 33 deletions
|
|
@ -1625,36 +1625,6 @@ fn split_grouped_constructors<'p, 'tcx>(
|
|||
split_ctors
|
||||
}
|
||||
|
||||
/// Checks whether there exists any shared value in either `ctor` or `pat` by intersecting them.
|
||||
fn constructor_intersects_pattern<'p, 'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
ctor: &Constructor<'tcx>,
|
||||
pat: &'p Pat<'tcx>,
|
||||
) -> Option<SmallVec<[&'p Pat<'tcx>; 2]>> {
|
||||
if should_treat_range_exhaustively(tcx, ctor) {
|
||||
match (IntRange::from_ctor(tcx, param_env, ctor), IntRange::from_pat(tcx, param_env, pat)) {
|
||||
(Some(ctor), Some(pat)) => {
|
||||
ctor.intersection(&pat).map(|_| {
|
||||
let (pat_lo, pat_hi) = pat.range.into_inner();
|
||||
let (ctor_lo, ctor_hi) = ctor.range.into_inner();
|
||||
assert!(pat_lo <= ctor_lo && ctor_hi <= pat_hi);
|
||||
smallvec![]
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
// Fallback for non-ranges and ranges that involve floating-point numbers, which are not
|
||||
// conveniently handled by `IntRange`. For these cases, the constructor may not be a range
|
||||
// so intersection actually devolves into being covered by the pattern.
|
||||
match constructor_covered_by_range(tcx, param_env, ctor, pat) {
|
||||
Ok(true) => Some(smallvec![]),
|
||||
Ok(false) | Err(ErrorReported) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn constructor_covered_by_range<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
|
|
@ -1845,9 +1815,32 @@ fn specialize<'p, 'a: 'p, 'tcx>(
|
|||
PatKind::Constant { .. } |
|
||||
PatKind::Range { .. } => {
|
||||
// If the constructor is a:
|
||||
// Single value: add a row if the pattern contains the constructor.
|
||||
// Range: add a row if the constructor intersects the pattern.
|
||||
constructor_intersects_pattern(cx.tcx, cx.param_env, constructor, pat)
|
||||
// - Single value: add a row if the pattern contains the constructor.
|
||||
// - Range: add a row if the constructor intersects the pattern.
|
||||
if should_treat_range_exhaustively(cx.tcx, constructor) {
|
||||
match (IntRange::from_ctor(cx.tcx, cx.param_env, constructor),
|
||||
IntRange::from_pat(cx.tcx, cx.param_env, pat)) {
|
||||
(Some(ctor), Some(pat)) => {
|
||||
ctor.intersection(&pat).map(|_| {
|
||||
let (pat_lo, pat_hi) = pat.range.into_inner();
|
||||
let (ctor_lo, ctor_hi) = ctor.range.into_inner();
|
||||
assert!(pat_lo <= ctor_lo && ctor_hi <= pat_hi);
|
||||
smallvec![]
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
// Fallback for non-ranges and ranges that involve
|
||||
// floating-point numbers, which are not conveniently handled
|
||||
// by `IntRange`. For these cases, the constructor may not be a
|
||||
// range so intersection actually devolves into being covered
|
||||
// by the pattern.
|
||||
match constructor_covered_by_range(cx.tcx, cx.param_env, constructor, pat) {
|
||||
Ok(true) => Some(smallvec![]),
|
||||
Ok(false) | Err(ErrorReported) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PatKind::Array { ref prefix, ref slice, ref suffix } |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue