Skip to content

Refactor integer range handling in the usefulness algorithm #66326

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 29 commits into from
Nov 16, 2019
Merged
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c75685b
Note link between apply/specialize/arity functions
Nadrieril Nov 7, 2019
8f7ba7a
Clarify conditions for exhaustive integer range matching
Nadrieril Nov 7, 2019
3531c52
Factor out range construction in `all_constructors`
Nadrieril Nov 7, 2019
34ad52e
`pat_constructor` does not need `pcx` anymore
Nadrieril Nov 7, 2019
8c1835d
IntRange::from_pat is redundant with pat_constructors
Nadrieril Nov 7, 2019
f3752ee
Cleanup `constructor_covered_by_range`
Nadrieril Nov 7, 2019
81db2ee
Special-case range inclusion when the range is integral but non-exhau…
Nadrieril Nov 7, 2019
0a18610
Move range exhaustiveness check to IntRange::intersection
Nadrieril Nov 7, 2019
6de7afd
Prefer IntRange::into_ctor to range_to_ctor
Nadrieril Nov 7, 2019
c6c8625
Special-case subtracting from a range if that range is not an IntRange
Nadrieril Nov 9, 2019
75a5088
Avoid converting through Constructor when subtracting ranges
Nadrieril Nov 9, 2019
1909e3f
`Constructor::display` was only needed for displaying `IntRange`
Nadrieril Nov 9, 2019
f93a700
Introduce IntRange constructor
Nadrieril Nov 15, 2019
4232816
formatting
Nadrieril Nov 15, 2019
6b8bfef
Add `IntRange::to_pat` and use it instead of custom `display()`
Nadrieril Nov 9, 2019
84784dd
Eagerly convert ranges to IntRange
Nadrieril Nov 9, 2019
aadd5e5
Factor out getting the boundaries of an `IntRange`
Nadrieril Nov 9, 2019
d1642f1
Inline now-trivial IntRange::from_ctor
Nadrieril Nov 9, 2019
0192124
Make should_treat_range_exhaustively a method
Nadrieril Nov 9, 2019
f674f89
Store Const directly in ConstantRange
Nadrieril Nov 9, 2019
3e5aadc
Remove unnecessary data from ConstantValue/ConstantRange
Nadrieril Nov 9, 2019
e47d631
Malformed range patterns can't happen thanks to E0030
Nadrieril Nov 9, 2019
d31b4c3
Remove fishy condition
Nadrieril Nov 9, 2019
c38aad4
Add test for failing `try_eval_bits`
Nadrieril Nov 12, 2019
9165dd0
Apply suggestions from code review
Nadrieril Nov 12, 2019
b679e77
Factor out IntRange::is_subrange
Nadrieril Nov 12, 2019
addd8a9
Apply suggestions from code review
Nadrieril Nov 12, 2019
cde9808
Add regression test
Nadrieril Nov 12, 2019
694a511
Apply suggestions from code review
Nadrieril Nov 15, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
IntRange::from_pat is redundant with pat_constructors
  • Loading branch information
Nadrieril committed Nov 15, 2019
commit 8c1835dc6e92aacc1172d7ae4071de1f9dbb0d89
42 changes: 13 additions & 29 deletions src/librustc_mir/hair/pattern/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1374,29 +1374,10 @@ impl<'tcx> IntRange<'tcx> {
fn from_pat(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
mut pat: &Pat<'tcx>,
pat: &Pat<'tcx>,
) -> Option<IntRange<'tcx>> {
loop {
match pat.kind {
box PatKind::Constant { value } => {
return Self::from_const(tcx, param_env, value, pat.span);
}
box PatKind::Range(PatRange { lo, hi, end }) => {
return Self::from_range(
tcx,
lo.eval_bits(tcx, param_env, lo.ty),
hi.eval_bits(tcx, param_env, hi.ty),
&lo.ty,
&end,
pat.span,
);
}
box PatKind::AscribeUserType { ref subpattern, .. } => {
pat = subpattern;
}
_ => return None,
}
}
let ctor = pat_constructor(tcx, param_env, pat)?;
IntRange::from_ctor(tcx, param_env, &ctor)
}

// The return value of `signed_bias` should be XORed with an endpoint to encode/decode it.
Expand Down Expand Up @@ -1632,7 +1613,7 @@ pub fn is_useful<'p, 'a, 'tcx>(

debug!("is_useful_expand_first_col: pcx={:#?}, expanding {:#?}", pcx, v.head());

if let Some(constructor) = pat_constructor(cx, v.head()) {
if let Some(constructor) = pat_constructor(cx.tcx, cx.param_env, v.head()) {
debug!("is_useful - expanding constructor: {:#?}", constructor);
split_grouped_constructors(
cx.tcx,
Expand All @@ -1651,7 +1632,7 @@ pub fn is_useful<'p, 'a, 'tcx>(
debug!("is_useful - expanding wildcard");

let used_ctors: Vec<Constructor<'_>> =
matrix.heads().filter_map(|p| pat_constructor(cx, p)).collect();
matrix.heads().filter_map(|p| pat_constructor(cx.tcx, cx.param_env, p)).collect();
debug!("used_ctors = {:#?}", used_ctors);
// `all_ctors` are all the constructors for the given type, which
// should all be represented (or caught with the wild pattern `_`).
Expand Down Expand Up @@ -1754,26 +1735,29 @@ fn is_useful_specialized<'p, 'a, 'tcx>(
/// Determines the constructor that the given pattern can be specialized to.
/// Returns `None` in case of a catch-all, which can't be specialized.
fn pat_constructor<'tcx>(
cx: &mut MatchCheckCtxt<'_, 'tcx>,
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
pat: &Pat<'tcx>,
) -> Option<Constructor<'tcx>> {
match *pat.kind {
PatKind::AscribeUserType { ref subpattern, .. } => pat_constructor(cx, subpattern),
PatKind::AscribeUserType { ref subpattern, .. } => {
pat_constructor(tcx, param_env, subpattern)
}
PatKind::Binding { .. } | PatKind::Wild => None,
PatKind::Leaf { .. } | PatKind::Deref { .. } => Some(Single),
PatKind::Variant { adt_def, variant_index, .. } => {
Some(Variant(adt_def.variants[variant_index].def_id))
}
PatKind::Constant { value } => Some(ConstantValue(value, pat.span)),
PatKind::Range(PatRange { lo, hi, end }) => Some(ConstantRange(
lo.eval_bits(cx.tcx, cx.param_env, lo.ty),
hi.eval_bits(cx.tcx, cx.param_env, hi.ty),
lo.eval_bits(tcx, param_env, lo.ty),
hi.eval_bits(tcx, param_env, hi.ty),
lo.ty,
end,
pat.span,
)),
PatKind::Array { .. } => match pat.ty.kind {
ty::Array(_, length) => Some(FixedLenSlice(length.eval_usize(cx.tcx, cx.param_env))),
ty::Array(_, length) => Some(FixedLenSlice(length.eval_usize(tcx, param_env))),
_ => span_bug!(pat.span, "bad ty {:?} for array pattern", pat.ty),
},
PatKind::Slice { ref prefix, ref slice, ref suffix } => {
Expand Down