Remove TestCase::Irrefutable
This commit is contained in:
parent
ef44273838
commit
854feae887
4 changed files with 38 additions and 58 deletions
|
@ -116,24 +116,23 @@ impl<'tcx> MatchPairTree<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let place = place_builder.try_to_place(cx);
|
let place = place_builder.try_to_place(cx);
|
||||||
let default_irrefutable = || TestCase::Irrefutable {};
|
|
||||||
let mut subpairs = Vec::new();
|
let mut subpairs = Vec::new();
|
||||||
let test_case = match pattern.kind {
|
let test_case = match pattern.kind {
|
||||||
PatKind::Wild | PatKind::Error(_) => default_irrefutable(),
|
PatKind::Wild | PatKind::Error(_) => None,
|
||||||
|
|
||||||
PatKind::Or { ref pats } => TestCase::Or {
|
PatKind::Or { ref pats } => Some(TestCase::Or {
|
||||||
pats: pats.iter().map(|pat| FlatPat::new(place_builder.clone(), pat, cx)).collect(),
|
pats: pats.iter().map(|pat| FlatPat::new(place_builder.clone(), pat, cx)).collect(),
|
||||||
},
|
}),
|
||||||
|
|
||||||
PatKind::Range(ref range) => {
|
PatKind::Range(ref range) => {
|
||||||
if range.is_full_range(cx.tcx) == Some(true) {
|
if range.is_full_range(cx.tcx) == Some(true) {
|
||||||
default_irrefutable()
|
None
|
||||||
} else {
|
} else {
|
||||||
TestCase::Range(Arc::clone(range))
|
Some(TestCase::Range(Arc::clone(range)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PatKind::Constant { value } => TestCase::Constant { value },
|
PatKind::Constant { value } => Some(TestCase::Constant { value }),
|
||||||
|
|
||||||
PatKind::AscribeUserType {
|
PatKind::AscribeUserType {
|
||||||
ascription: Ascription { ref annotation, variance },
|
ascription: Ascription { ref annotation, variance },
|
||||||
|
@ -154,7 +153,7 @@ impl<'tcx> MatchPairTree<'tcx> {
|
||||||
extra_data.ascriptions.push(super::Ascription { source, annotation, variance });
|
extra_data.ascriptions.push(super::Ascription { source, annotation, variance });
|
||||||
}
|
}
|
||||||
|
|
||||||
default_irrefutable()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
PatKind::Binding { mode, var, ref subpattern, .. } => {
|
PatKind::Binding { mode, var, ref subpattern, .. } => {
|
||||||
|
@ -199,12 +198,12 @@ impl<'tcx> MatchPairTree<'tcx> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
default_irrefutable()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
PatKind::ExpandedConstant { subpattern: ref pattern, def_id: _, is_inline: false } => {
|
PatKind::ExpandedConstant { subpattern: ref pattern, def_id: _, is_inline: false } => {
|
||||||
MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs, extra_data);
|
MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs, extra_data);
|
||||||
default_irrefutable()
|
None
|
||||||
}
|
}
|
||||||
PatKind::ExpandedConstant { subpattern: ref pattern, def_id, is_inline: true } => {
|
PatKind::ExpandedConstant { subpattern: ref pattern, def_id, is_inline: true } => {
|
||||||
MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs, extra_data);
|
MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs, extra_data);
|
||||||
|
@ -233,7 +232,7 @@ impl<'tcx> MatchPairTree<'tcx> {
|
||||||
extra_data.ascriptions.push(super::Ascription { annotation, source, variance });
|
extra_data.ascriptions.push(super::Ascription { annotation, source, variance });
|
||||||
}
|
}
|
||||||
|
|
||||||
default_irrefutable()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
PatKind::Array { ref prefix, ref slice, ref suffix } => {
|
PatKind::Array { ref prefix, ref slice, ref suffix } => {
|
||||||
|
@ -245,7 +244,7 @@ impl<'tcx> MatchPairTree<'tcx> {
|
||||||
slice,
|
slice,
|
||||||
suffix,
|
suffix,
|
||||||
);
|
);
|
||||||
default_irrefutable()
|
None
|
||||||
}
|
}
|
||||||
PatKind::Slice { ref prefix, ref slice, ref suffix } => {
|
PatKind::Slice { ref prefix, ref slice, ref suffix } => {
|
||||||
cx.prefix_slice_suffix(
|
cx.prefix_slice_suffix(
|
||||||
|
@ -258,12 +257,12 @@ impl<'tcx> MatchPairTree<'tcx> {
|
||||||
);
|
);
|
||||||
|
|
||||||
if prefix.is_empty() && slice.is_some() && suffix.is_empty() {
|
if prefix.is_empty() && slice.is_some() && suffix.is_empty() {
|
||||||
default_irrefutable()
|
None
|
||||||
} else {
|
} else {
|
||||||
TestCase::Slice {
|
Some(TestCase::Slice {
|
||||||
len: prefix.len() + suffix.len(),
|
len: prefix.len() + suffix.len(),
|
||||||
variable_length: slice.is_some(),
|
variable_length: slice.is_some(),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,16 +278,12 @@ impl<'tcx> MatchPairTree<'tcx> {
|
||||||
.apply_ignore_module(cx.tcx, cx.infcx.typing_env(cx.param_env))
|
.apply_ignore_module(cx.tcx, cx.infcx.typing_env(cx.param_env))
|
||||||
}) && (adt_def.did().is_local()
|
}) && (adt_def.did().is_local()
|
||||||
|| !adt_def.is_variant_list_non_exhaustive());
|
|| !adt_def.is_variant_list_non_exhaustive());
|
||||||
if irrefutable {
|
if irrefutable { None } else { Some(TestCase::Variant { adt_def, variant_index }) }
|
||||||
default_irrefutable()
|
|
||||||
} else {
|
|
||||||
TestCase::Variant { adt_def, variant_index }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PatKind::Leaf { ref subpatterns } => {
|
PatKind::Leaf { ref subpatterns } => {
|
||||||
cx.field_match_pairs(&mut subpairs, extra_data, place_builder, subpatterns);
|
cx.field_match_pairs(&mut subpairs, extra_data, place_builder, subpatterns);
|
||||||
default_irrefutable()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
PatKind::Deref { ref subpattern } => {
|
PatKind::Deref { ref subpattern } => {
|
||||||
|
@ -299,7 +294,7 @@ impl<'tcx> MatchPairTree<'tcx> {
|
||||||
&mut subpairs,
|
&mut subpairs,
|
||||||
extra_data,
|
extra_data,
|
||||||
);
|
);
|
||||||
default_irrefutable()
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
PatKind::DerefPattern { ref subpattern, mutability } => {
|
PatKind::DerefPattern { ref subpattern, mutability } => {
|
||||||
|
@ -316,18 +311,25 @@ impl<'tcx> MatchPairTree<'tcx> {
|
||||||
&mut subpairs,
|
&mut subpairs,
|
||||||
extra_data,
|
extra_data,
|
||||||
);
|
);
|
||||||
TestCase::Deref { temp, mutability }
|
Some(TestCase::Deref { temp, mutability })
|
||||||
}
|
}
|
||||||
|
|
||||||
PatKind::Never => TestCase::Never,
|
PatKind::Never => Some(TestCase::Never),
|
||||||
};
|
};
|
||||||
|
|
||||||
match_pairs.push(MatchPairTree {
|
if let Some(test_case) = test_case {
|
||||||
place,
|
// This pattern is refutable, so push a new match-pair node.
|
||||||
test_case,
|
match_pairs.push(MatchPairTree {
|
||||||
subpairs,
|
place,
|
||||||
pattern_ty: pattern.ty,
|
test_case,
|
||||||
pattern_span: pattern.span,
|
subpairs,
|
||||||
});
|
pattern_ty: pattern.ty,
|
||||||
|
pattern_span: pattern.span,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// This pattern is irrefutable, so it doesn't need its own match-pair node.
|
||||||
|
// Just push its refutable subpatterns instead, if any.
|
||||||
|
match_pairs.extend(subpairs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1054,7 +1054,6 @@ struct Candidate<'tcx> {
|
||||||
/// (see [`Builder::test_remaining_match_pairs_after_or`]).
|
/// (see [`Builder::test_remaining_match_pairs_after_or`]).
|
||||||
///
|
///
|
||||||
/// Invariants:
|
/// Invariants:
|
||||||
/// - All [`TestCase::Irrefutable`] patterns have been removed by simplification.
|
|
||||||
/// - All or-patterns ([`TestCase::Or`]) have been sorted to the end.
|
/// - All or-patterns ([`TestCase::Or`]) have been sorted to the end.
|
||||||
match_pairs: Vec<MatchPairTree<'tcx>>,
|
match_pairs: Vec<MatchPairTree<'tcx>>,
|
||||||
|
|
||||||
|
@ -1226,17 +1225,11 @@ struct Ascription<'tcx> {
|
||||||
/// - [`Builder::pick_test_for_match_pair`] (to choose a test)
|
/// - [`Builder::pick_test_for_match_pair`] (to choose a test)
|
||||||
/// - [`Builder::sort_candidate`] (to see how the test interacts with a match pair)
|
/// - [`Builder::sort_candidate`] (to see how the test interacts with a match pair)
|
||||||
///
|
///
|
||||||
/// Two variants are unlike the others and deserve special mention:
|
/// Note that or-patterns are not tested directly like the other variants.
|
||||||
///
|
/// Instead they participate in or-pattern expansion, where they are transformed into
|
||||||
/// - [`Self::Irrefutable`] is only used temporarily when building a [`MatchPairTree`].
|
/// subcandidates. See [`Builder::expand_and_match_or_candidates`].
|
||||||
/// They are then flattened away by [`Builder::simplify_match_pairs`], with any
|
|
||||||
/// bindings/ascriptions incorporated into the enclosing [`FlatPat`].
|
|
||||||
/// - [`Self::Or`] are not tested directly like the other variants. Instead they
|
|
||||||
/// participate in or-pattern expansion, where they are transformed into subcandidates.
|
|
||||||
/// - See [`Builder::expand_and_match_or_candidates`].
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
enum TestCase<'tcx> {
|
enum TestCase<'tcx> {
|
||||||
Irrefutable {},
|
|
||||||
Variant { adt_def: ty::AdtDef<'tcx>, variant_index: VariantIdx },
|
Variant { adt_def: ty::AdtDef<'tcx>, variant_index: VariantIdx },
|
||||||
Constant { value: mir::Const<'tcx> },
|
Constant { value: mir::Const<'tcx> },
|
||||||
Range(Arc<PatRange<'tcx>>),
|
Range(Arc<PatRange<'tcx>>),
|
||||||
|
@ -1269,10 +1262,6 @@ pub(crate) struct MatchPairTree<'tcx> {
|
||||||
place: Option<Place<'tcx>>,
|
place: Option<Place<'tcx>>,
|
||||||
|
|
||||||
/// ... must pass this test...
|
/// ... must pass this test...
|
||||||
///
|
|
||||||
/// ---
|
|
||||||
/// Invariant: after creation and simplification in [`FlatPat::new`],
|
|
||||||
/// this must not be [`TestCase::Irrefutable`].
|
|
||||||
test_case: TestCase<'tcx>,
|
test_case: TestCase<'tcx>,
|
||||||
|
|
||||||
/// ... and these subpairs must match.
|
/// ... and these subpairs must match.
|
||||||
|
|
|
@ -47,13 +47,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
// match lowering forces us to lower bindings inside or-patterns last.
|
// match lowering forces us to lower bindings inside or-patterns last.
|
||||||
for mut match_pair in mem::take(match_pairs) {
|
for mut match_pair in mem::take(match_pairs) {
|
||||||
self.simplify_match_pairs(&mut match_pair.subpairs, extra_data);
|
self.simplify_match_pairs(&mut match_pair.subpairs, extra_data);
|
||||||
if let TestCase::Irrefutable {} = match_pair.test_case {
|
// Unsimplifiable pattern; we keep it.
|
||||||
// Simplifiable pattern; we replace it with its already simplified subpairs.
|
match_pairs.push(match_pair);
|
||||||
match_pairs.append(&mut match_pair.subpairs);
|
|
||||||
} else {
|
|
||||||
// Unsimplifiable pattern; we keep it.
|
|
||||||
match_pairs.push(match_pair);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move or-patterns to the end, because they can result in us
|
// Move or-patterns to the end, because they can result in us
|
||||||
|
|
|
@ -55,12 +55,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
// Or-patterns are not tested directly; instead they are expanded into subcandidates,
|
// Or-patterns are not tested directly; instead they are expanded into subcandidates,
|
||||||
// which are then distinguished by testing whatever non-or patterns they contain.
|
// which are then distinguished by testing whatever non-or patterns they contain.
|
||||||
TestCase::Or { .. } => bug!("or-patterns should have already been handled"),
|
TestCase::Or { .. } => bug!("or-patterns should have already been handled"),
|
||||||
|
|
||||||
TestCase::Irrefutable { .. } => span_bug!(
|
|
||||||
match_pair.pattern_span,
|
|
||||||
"simplifiable pattern found: {:?}",
|
|
||||||
match_pair.pattern_span
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Test { span: match_pair.pattern_span, kind }
|
Test { span: match_pair.pattern_span, kind }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue