Skip to content

Commit a181bdc

Browse files
committed
Introduce TestCase enum to replace most matching on PatKind
1 parent 5c9d580 commit a181bdc

File tree

4 files changed

+132
-143
lines changed

4 files changed

+132
-143
lines changed

compiler/rustc_mir_build/src/build/matches/mod.rs

+20-7
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_data_structures::{
1616
};
1717
use rustc_index::bit_set::BitSet;
1818
use rustc_middle::middle::region;
19-
use rustc_middle::mir::*;
19+
use rustc_middle::mir::{self, *};
2020
use rustc_middle::thir::{self, *};
2121
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty};
2222
use rustc_span::symbol::Symbol;
@@ -1052,18 +1052,31 @@ struct Ascription<'tcx> {
10521052
variance: ty::Variance,
10531053
}
10541054

1055+
#[derive(Debug, Clone)]
1056+
enum TestCase<'pat, 'tcx> {
1057+
Irrefutable,
1058+
Variant { adt_def: ty::AdtDef<'tcx>, variant_index: VariantIdx },
1059+
Constant { value: mir::Const<'tcx> },
1060+
Range(&'pat PatRange<'tcx>),
1061+
Slice { len: usize, variable_length: bool },
1062+
Or,
1063+
}
1064+
10551065
#[derive(Debug, Clone)]
10561066
pub(crate) struct MatchPair<'pat, 'tcx> {
1057-
// This place...
1067+
/// This place...
10581068
place: PlaceBuilder<'tcx>,
10591069

1060-
// ... must match this pattern.
1061-
// Invariant: after creation and simplification in `Candidate::new()`, all match pairs must be
1062-
// simplified, i.e. require a test.
1063-
pattern: &'pat Pat<'tcx>,
1070+
/// ... must pass this test...
1071+
// Invariant: after creation and simplification in `Candidate::new()`, this must not be
1072+
// `Irrefutable`.
1073+
test_case: TestCase<'pat, 'tcx>,
10641074

1065-
/// Precomputed sub-match pairs of `pattern`.
1075+
/// ... and these subpairs must match.
10661076
subpairs: Vec<Self>,
1077+
1078+
/// The pattern this was created from.
1079+
pattern: &'pat Pat<'tcx>,
10671080
}
10681081

10691082
/// See [`Test`] for more.

compiler/rustc_mir_build/src/build/matches/simplify.rs

+12-48
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
//! testing a value against a constant.
1414
1515
use crate::build::expr::as_place::PlaceBuilder;
16-
use crate::build::matches::{Ascription, Binding, Candidate, MatchPair};
16+
use crate::build::matches::{Ascription, Binding, Candidate, MatchPair, TestCase};
1717
use crate::build::Builder;
1818
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
1919
use rustc_middle::thir::{self, *};
@@ -128,14 +128,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
128128
ascriptions: &mut Vec<Ascription<'tcx>>,
129129
match_pairs: &mut Vec<MatchPair<'pat, 'tcx>>,
130130
) -> Result<(), MatchPair<'pat, 'tcx>> {
131+
// Collect bindings and ascriptions.
131132
match match_pair.pattern.kind {
132-
PatKind::Leaf { .. }
133-
| PatKind::Deref { .. }
134-
| PatKind::Array { .. }
135-
| PatKind::Never
136-
| PatKind::Wild
137-
| PatKind::Error(_) => {}
138-
139133
PatKind::AscribeUserType {
140134
ascription: thir::Ascription { ref annotation, variance },
141135
..
@@ -203,47 +197,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
203197
}
204198
}
205199

206-
PatKind::Constant { .. } => {
207-
// FIXME normalize patterns when possible
208-
return Err(match_pair);
209-
}
210-
211-
PatKind::Range(ref range) => {
212-
if range.is_full_range(self.tcx) != Some(true) {
213-
return Err(match_pair);
214-
}
215-
}
216-
217-
PatKind::Slice { ref prefix, ref slice, ref suffix } => {
218-
if !(prefix.is_empty() && slice.is_some() && suffix.is_empty()) {
219-
self.simplify_match_pairs(&mut match_pair.subpairs, bindings, ascriptions);
220-
return Err(match_pair);
221-
}
222-
}
223-
224-
PatKind::Variant { adt_def, args, variant_index, subpatterns: _ } => {
225-
let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| {
226-
i == variant_index || {
227-
(self.tcx.features().exhaustive_patterns
228-
|| self.tcx.features().min_exhaustive_patterns)
229-
&& !v
230-
.inhabited_predicate(self.tcx, adt_def)
231-
.instantiate(self.tcx, args)
232-
.apply_ignore_module(self.tcx, self.param_env)
233-
}
234-
}) && (adt_def.did().is_local()
235-
|| !adt_def.is_variant_list_non_exhaustive());
236-
if !irrefutable {
237-
self.simplify_match_pairs(&mut match_pair.subpairs, bindings, ascriptions);
238-
return Err(match_pair);
239-
}
240-
}
241-
242-
PatKind::Or { .. } => return Err(match_pair),
200+
_ => {}
243201
}
244202

245-
// Simplifiable pattern; we replace it with its subpairs.
246-
match_pairs.append(&mut match_pair.subpairs);
247-
Ok(())
203+
if let TestCase::Irrefutable = match_pair.test_case {
204+
// Simplifiable pattern; we replace it with its subpairs.
205+
match_pairs.append(&mut match_pair.subpairs);
206+
Ok(())
207+
} else {
208+
// Unsimplifiable pattern; we recursively simplify its subpairs.
209+
self.simplify_match_pairs(&mut match_pair.subpairs, bindings, ascriptions);
210+
Err(match_pair)
211+
}
248212
}
249213
}

0 commit comments

Comments
 (0)