Remove TestCase::Irrefutable

This commit is contained in:
Zalathar 2025-03-05 23:25:59 +11:00
parent ef44273838
commit 854feae887
4 changed files with 38 additions and 58 deletions

View file

@ -116,24 +116,23 @@ impl<'tcx> MatchPairTree<'tcx> {
}
let place = place_builder.try_to_place(cx);
let default_irrefutable = || TestCase::Irrefutable {};
let mut subpairs = Vec::new();
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(),
},
}),
PatKind::Range(ref range) => {
if range.is_full_range(cx.tcx) == Some(true) {
default_irrefutable()
None
} 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 {
ascription: Ascription { ref annotation, variance },
@ -154,7 +153,7 @@ impl<'tcx> MatchPairTree<'tcx> {
extra_data.ascriptions.push(super::Ascription { source, annotation, variance });
}
default_irrefutable()
None
}
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 } => {
MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs, extra_data);
default_irrefutable()
None
}
PatKind::ExpandedConstant { subpattern: ref pattern, def_id, is_inline: true } => {
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 });
}
default_irrefutable()
None
}
PatKind::Array { ref prefix, ref slice, ref suffix } => {
@ -245,7 +244,7 @@ impl<'tcx> MatchPairTree<'tcx> {
slice,
suffix,
);
default_irrefutable()
None
}
PatKind::Slice { ref prefix, ref slice, ref suffix } => {
cx.prefix_slice_suffix(
@ -258,12 +257,12 @@ impl<'tcx> MatchPairTree<'tcx> {
);
if prefix.is_empty() && slice.is_some() && suffix.is_empty() {
default_irrefutable()
None
} else {
TestCase::Slice {
Some(TestCase::Slice {
len: prefix.len() + suffix.len(),
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))
}) && (adt_def.did().is_local()
|| !adt_def.is_variant_list_non_exhaustive());
if irrefutable {
default_irrefutable()
} else {
TestCase::Variant { adt_def, variant_index }
}
if irrefutable { None } else { Some(TestCase::Variant { adt_def, variant_index }) }
}
PatKind::Leaf { ref subpatterns } => {
cx.field_match_pairs(&mut subpairs, extra_data, place_builder, subpatterns);
default_irrefutable()
None
}
PatKind::Deref { ref subpattern } => {
@ -299,7 +294,7 @@ impl<'tcx> MatchPairTree<'tcx> {
&mut subpairs,
extra_data,
);
default_irrefutable()
None
}
PatKind::DerefPattern { ref subpattern, mutability } => {
@ -316,18 +311,25 @@ impl<'tcx> MatchPairTree<'tcx> {
&mut subpairs,
extra_data,
);
TestCase::Deref { temp, mutability }
Some(TestCase::Deref { temp, mutability })
}
PatKind::Never => TestCase::Never,
PatKind::Never => Some(TestCase::Never),
};
match_pairs.push(MatchPairTree {
place,
test_case,
subpairs,
pattern_ty: pattern.ty,
pattern_span: pattern.span,
});
if let Some(test_case) = test_case {
// This pattern is refutable, so push a new match-pair node.
match_pairs.push(MatchPairTree {
place,
test_case,
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);
}
}
}

View file

@ -1054,7 +1054,6 @@ struct Candidate<'tcx> {
/// (see [`Builder::test_remaining_match_pairs_after_or`]).
///
/// Invariants:
/// - All [`TestCase::Irrefutable`] patterns have been removed by simplification.
/// - All or-patterns ([`TestCase::Or`]) have been sorted to the end.
match_pairs: Vec<MatchPairTree<'tcx>>,
@ -1226,17 +1225,11 @@ struct Ascription<'tcx> {
/// - [`Builder::pick_test_for_match_pair`] (to choose a test)
/// - [`Builder::sort_candidate`] (to see how the test interacts with a match pair)
///
/// Two variants are unlike the others and deserve special mention:
///
/// - [`Self::Irrefutable`] is only used temporarily when building a [`MatchPairTree`].
/// 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`].
/// Note that or-patterns 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)]
enum TestCase<'tcx> {
Irrefutable {},
Variant { adt_def: ty::AdtDef<'tcx>, variant_index: VariantIdx },
Constant { value: mir::Const<'tcx> },
Range(Arc<PatRange<'tcx>>),
@ -1269,10 +1262,6 @@ pub(crate) struct MatchPairTree<'tcx> {
place: Option<Place<'tcx>>,
/// ... must pass this test...
///
/// ---
/// Invariant: after creation and simplification in [`FlatPat::new`],
/// this must not be [`TestCase::Irrefutable`].
test_case: TestCase<'tcx>,
/// ... and these subpairs must match.

View file

@ -47,13 +47,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// match lowering forces us to lower bindings inside or-patterns last.
for mut match_pair in mem::take(match_pairs) {
self.simplify_match_pairs(&mut match_pair.subpairs, extra_data);
if let TestCase::Irrefutable {} = match_pair.test_case {
// Simplifiable pattern; we replace it with its already simplified subpairs.
match_pairs.append(&mut match_pair.subpairs);
} else {
// Unsimplifiable pattern; we keep it.
match_pairs.push(match_pair);
}
// Unsimplifiable pattern; we keep it.
match_pairs.push(match_pair);
}
// Move or-patterns to the end, because they can result in us

View file

@ -55,12 +55,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// Or-patterns are not tested directly; instead they are expanded into subcandidates,
// which are then distinguished by testing whatever non-or patterns they contain.
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 }