Skip to content

Commit fde45e9

Browse files
committed
Remove dependency of SubPatSet on Pat
1 parent 5853399 commit fde45e9

File tree

1 file changed

+23
-27
lines changed

1 file changed

+23
-27
lines changed

compiler/rustc_mir_build/src/thir/pattern/usefulness.rs

+23-27
Original file line numberDiff line numberDiff line change
@@ -624,27 +624,25 @@ impl<'p, 'tcx> fmt::Debug for Matrix<'p, 'tcx> {
624624
/// `self.is_empty()` we ensure that `self` is `Empty`, and same with `Full`. This is not important
625625
/// for correctness currently.
626626
#[derive(Debug, Clone)]
627-
enum SubPatSet<'p, 'tcx> {
627+
enum SubPatSet {
628628
/// The empty set. This means the pattern is unreachable.
629629
Empty,
630630
/// The set containing the full pattern.
631631
Full,
632632
/// If the pattern is a pattern with a constructor or a pattern-stack, we store a set for each
633633
/// of its subpatterns. Missing entries in the map are implicitly full, because that's the
634634
/// common case.
635-
Seq { subpats: FxHashMap<usize, SubPatSet<'p, 'tcx>> },
635+
Seq { subpats: FxHashMap<usize, SubPatSet> },
636636
/// If the pattern is an or-pattern, we store a set for each of its alternatives. Missing
637637
/// entries in the map are implicitly empty. Note: we always flatten nested or-patterns.
638638
Alt {
639-
subpats: FxHashMap<usize, SubPatSet<'p, 'tcx>>,
640-
/// Counts the total number of alternatives in the pattern
641-
alt_count: usize,
642-
/// We keep the pattern around to retrieve spans.
643-
pat: &'p Pat<'tcx>,
639+
subpats: FxHashMap<usize, SubPatSet>,
640+
/// Span of each alternative in the pattern
641+
spans: Vec<Span>,
644642
},
645643
}
646644

647-
impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
645+
impl SubPatSet {
648646
fn full() -> Self {
649647
SubPatSet::Full
650648
}
@@ -670,8 +668,8 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
670668
// The whole pattern is reachable only when all its alternatives are.
671669
SubPatSet::Seq { subpats } => subpats.values().all(|sub_set| sub_set.is_full()),
672670
// The whole or-pattern is reachable only when all its alternatives are.
673-
SubPatSet::Alt { subpats, alt_count, .. } => {
674-
subpats.len() == *alt_count && subpats.values().all(|set| set.is_full())
671+
SubPatSet::Alt { subpats, spans, .. } => {
672+
subpats.len() == spans.len() && subpats.values().all(|set| set.is_full())
675673
}
676674
}
677675
}
@@ -726,7 +724,7 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
726724
/// whole pattern is unreachable) we return `None`.
727725
fn list_unreachable_spans(&self) -> Option<Vec<Span>> {
728726
/// Panics if `set.is_empty()`.
729-
fn fill_spans(set: &SubPatSet<'_, '_>, spans: &mut Vec<Span>) {
727+
fn fill_spans(set: &SubPatSet, spans: &mut Vec<Span>) {
730728
match set {
731729
SubPatSet::Empty => bug!(),
732730
SubPatSet::Full => {}
@@ -735,13 +733,12 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
735733
fill_spans(sub_set, spans);
736734
}
737735
}
738-
SubPatSet::Alt { subpats, pat, alt_count, .. } => {
739-
let expanded = expand_or_pat(pat);
740-
for i in 0..*alt_count {
736+
SubPatSet::Alt { subpats, spans: alt_spans, .. } => {
737+
for (i, span) in alt_spans.iter().enumerate() {
741738
let sub_set = subpats.get(&i).unwrap_or(&SubPatSet::Empty);
742739
if sub_set.is_empty() {
743740
// Found an unreachable subpattern.
744-
spans.push(expanded[i].span);
741+
spans.push(*span);
745742
} else {
746743
fill_spans(sub_set, spans);
747744
}
@@ -806,7 +803,7 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
806803
/// Here `None` would return the full set and `Some(true | false)` would return the set
807804
/// containing `false`. After `unsplit_or_pat`, we want the set to contain `None` and `false`.
808805
/// This is what this function does.
809-
fn unsplit_or_pat(mut self, alt_id: usize, alt_count: usize, pat: &'p Pat<'tcx>) -> Self {
806+
fn unsplit_or_pat(mut self, alt_id: usize, spans: Vec<Span>) -> Self {
810807
use SubPatSet::*;
811808
if self.is_empty() {
812809
return Empty;
@@ -822,7 +819,7 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
822819
};
823820
let mut subpats_first_col = FxHashMap::default();
824821
subpats_first_col.insert(alt_id, set_first_col);
825-
let set_first_col = Alt { subpats: subpats_first_col, pat, alt_count };
822+
let set_first_col = Alt { subpats: subpats_first_col, spans };
826823

827824
let mut subpats = match self {
828825
Full => FxHashMap::default(),
@@ -842,19 +839,19 @@ impl<'p, 'tcx> SubPatSet<'p, 'tcx> {
842839
/// witnesses of non-exhaustiveness when there are any.
843840
/// Which variant to use is dictated by `ArmType`.
844841
#[derive(Clone, Debug)]
845-
enum Usefulness<'p, 'tcx> {
842+
enum Usefulness<'tcx> {
846843
/// Carries a set of subpatterns that have been found to be reachable. If empty, this indicates
847844
/// the whole pattern is unreachable. If not, this indicates that the pattern is reachable but
848845
/// that some sub-patterns may be unreachable (due to or-patterns). In the absence of
849846
/// or-patterns this will always be either `Empty` (the whole pattern is unreachable) or `Full`
850847
/// (the whole pattern is reachable).
851-
NoWitnesses(SubPatSet<'p, 'tcx>),
848+
NoWitnesses(SubPatSet),
852849
/// Carries a list of witnesses of non-exhaustiveness. If empty, indicates that the whole
853850
/// pattern is unreachable.
854851
WithWitnesses(Vec<Witness<'tcx>>),
855852
}
856853

857-
impl<'p, 'tcx> Usefulness<'p, 'tcx> {
854+
impl<'tcx> Usefulness<'tcx> {
858855
fn new_useful(preference: ArmType) -> Self {
859856
match preference {
860857
FakeExtraWildcard => WithWitnesses(vec![Witness(vec![])]),
@@ -889,17 +886,17 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> {
889886

890887
/// After calculating the usefulness for a branch of an or-pattern, call this to make this
891888
/// usefulness mergeable with those from the other branches.
892-
fn unsplit_or_pat(self, alt_id: usize, alt_count: usize, pat: &'p Pat<'tcx>) -> Self {
889+
fn unsplit_or_pat(self, alt_id: usize, spans: Vec<Span>) -> Self {
893890
match self {
894-
NoWitnesses(subpats) => NoWitnesses(subpats.unsplit_or_pat(alt_id, alt_count, pat)),
891+
NoWitnesses(subpats) => NoWitnesses(subpats.unsplit_or_pat(alt_id, spans)),
895892
WithWitnesses(_) => bug!(),
896893
}
897894
}
898895

899896
/// After calculating usefulness after a specialization, call this to reconstruct a usefulness
900897
/// that makes sense for the matrix pre-specialization. This new usefulness can then be merged
901898
/// with the results of specializing with the other constructors.
902-
fn apply_constructor(
899+
fn apply_constructor<'p>(
903900
self,
904901
pcx: PatCtxt<'_, 'p, 'tcx>,
905902
matrix: &Matrix<'p, 'tcx>, // used to compute missing ctors
@@ -1099,7 +1096,7 @@ fn is_useful<'p, 'tcx>(
10991096
hir_id: HirId,
11001097
is_under_guard: bool,
11011098
is_top_level: bool,
1102-
) -> Usefulness<'p, 'tcx> {
1099+
) -> Usefulness<'tcx> {
11031100
debug!("matrix,v={:?}{:?}", matrix, v);
11041101
let Matrix { patterns: rows, .. } = matrix;
11051102

@@ -1129,15 +1126,14 @@ fn is_useful<'p, 'tcx>(
11291126
let mut ret = Usefulness::new_not_useful(witness_preference);
11301127
if is_or_pat(v.head()) {
11311128
debug!("expanding or-pattern");
1132-
let v_head = v.head();
11331129
let vs: Vec<_> = v.expand_or_pat().collect();
1134-
let alt_count = vs.len();
1130+
let spans: Vec<_> = vs.iter().map(|pat| pat.head().span).collect();
11351131
// We try each or-pattern branch in turn.
11361132
let mut matrix = matrix.clone();
11371133
for (i, v) in vs.into_iter().enumerate() {
11381134
let usefulness =
11391135
is_useful(cx, &matrix, &v, witness_preference, hir_id, is_under_guard, false);
1140-
let usefulness = usefulness.unsplit_or_pat(i, alt_count, v_head);
1136+
let usefulness = usefulness.unsplit_or_pat(i, spans.clone());
11411137
ret.extend(usefulness);
11421138
// If pattern has a guard don't add it to the matrix.
11431139
if !is_under_guard {

0 commit comments

Comments
 (0)