Skip to content

Commit 9ff6ae5

Browse files
committed
recover from InterPat addition
1 parent b3f7403 commit 9ff6ae5

2 files changed

Lines changed: 26 additions & 28 deletions

File tree

compiler/rustc_mir_build/src/builder/matches/match_pair.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::sync::Arc;
33
use rustc_abi::FieldIdx;
44
use rustc_middle::mir::{Pinnedness, Place, PlaceElem, ProjectionElem};
55
use rustc_middle::span_bug;
6-
use rustc_middle::thir::{Ascription, DerefPatBorrowMode, FieldPat, Pat, PatKind};
6+
use rustc_middle::thir::{Ascription, DerefPatBorrowMode, ExprId, FieldPat, Pat, PatKind};
77
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
88
use rustc_span::Span;
99

@@ -87,11 +87,15 @@ impl<'tcx> FlatPat<'tcx> {
8787
/// when squashing any or-patterns.
8888
fn from_inter_pat(inter_pat: InterPat<'tcx>) -> Self {
8989
let mut match_pairs = vec![];
90+
let mut guard_patterns = vec![];
91+
if let Some(guard_pat) = inter_pat.guard_pat {
92+
guard_patterns.push(super::OrderedPatternData::One(guard_pat));
93+
}
9094
let mut extra_data = PatternExtraData {
9195
span: inter_pat.pattern_span,
92-
bindings: vec![],
93-
ascriptions: vec![],
96+
guard_patterns,
9497
is_never: inter_pat.is_never,
98+
..Default::default()
9599
};
96100
squash_inter_pat(inter_pat, &mut match_pairs, &mut extra_data);
97101

@@ -114,13 +118,18 @@ fn squash_inter_pat<'tcx>(
114118
or_subpats,
115119
ascriptions,
116120
binding,
121+
guard_pat,
117122
pattern_span,
118123
is_never: _, // Not needed by `MatchPairTree` forests.
119124
} = inter_pat;
120125

121126
// Type ascriptions can appear regardless of whether the node is an or-pattern.
122127
extra_data.ascriptions.extend(ascriptions);
123128

129+
guard_pat.inspect(|&guard_pat| {
130+
extra_data.guard_patterns.push(super::OrderedPatternData::One(guard_pat));
131+
});
132+
124133
// Or and non-or patterns have very different handling.
125134
if let Some(or_subpats) = or_subpats {
126135
// We're dealing with an or-pattern node.
@@ -139,7 +148,10 @@ fn squash_inter_pat<'tcx>(
139148
// or-patterns that will be simplified by `merge_trivial_subcandidates`. In
140149
// other words, we can assume this expands into subcandidates.
141150
// FIXME(@dianne): this needs updating/removing if we always merge or-patterns
142-
extra_data.bindings.push(super::SubpatternBindings::FromOrPattern);
151+
extra_data.bindings.push(super::OrderedPatternData::FromOrPattern);
152+
}
153+
if or_subpats.iter().any(|pat| !pat.extra_data.guard_patterns.is_empty()) {
154+
extra_data.guard_patterns.push(super::OrderedPatternData::FromOrPattern);
143155
}
144156

145157
match_pairs.push(MatchPairTree {
@@ -179,7 +191,7 @@ fn squash_inter_pat<'tcx>(
179191
// the binding to `copy_field` will occur before the binding for `x`.
180192
// See <https://github.com/rust-lang/rust/issues/69971> for more background.
181193
if let Some(binding) = binding {
182-
extra_data.bindings.push(super::SubpatternBindings::One(binding));
194+
extra_data.bindings.push(super::OrderedPatternData::One(binding));
183195
}
184196
}
185197
}
@@ -214,6 +226,8 @@ struct InterPat<'tcx> {
214226
/// Binding to establish for a [`PatKind::Binding`] node.
215227
binding: Option<super::Binding<'tcx>>,
216228

229+
guard_pat: Option<ExprId>,
230+
217231
/// Span field of the THIR pattern this node was created from.
218232
pattern_span: Span,
219233
/// True if this pattern can never match, because all of its alternatives
@@ -256,6 +270,7 @@ impl<'tcx> InterPat<'tcx> {
256270
let mut or_subpats = None;
257271
let mut ascriptions = vec![];
258272
let mut binding = None;
273+
let mut guard_pat = None;
259274

260275
// Apply any type ascriptions to the value at `match_pair.place`.
261276
if let Some(place) = place
@@ -455,9 +470,10 @@ impl<'tcx> InterPat<'tcx> {
455470
}
456471

457472
PatKind::Guard { ref subpattern, condition } => {
458-
MatchPairTree::for_pattern(place_builder, subpattern, cx, match_pairs, extra_data);
459-
extra_data.guard_patterns.push(super::OrderedPatternData::One(condition));
460-
return;
473+
let subpattern = InterPat::lower_thir_pat(cx, place_builder, subpattern);
474+
subpats.push(subpattern);
475+
guard_pat = Some(condition);
476+
None
461477
}
462478

463479
PatKind::Never => Some(TestableCase::Never),
@@ -480,6 +496,7 @@ impl<'tcx> InterPat<'tcx> {
480496
or_subpats,
481497
ascriptions,
482498
binding,
499+
guard_pat,
483500
pattern_span: pattern.span,
484501
is_never,
485502
}

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

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
979979

980980
/// Data extracted from a pattern that doesn't affect which branch is taken. Collected during
981981
/// pattern simplification and not mutated later.
982-
#[derive(Debug, Clone)]
982+
#[derive(Debug, Clone, Default)]
983983
struct PatternExtraData<'tcx> {
984984
/// [`Span`] of the original pattern.
985985
span: Span,
@@ -1032,25 +1032,6 @@ struct FlatPat<'tcx> {
10321032
extra_data: PatternExtraData<'tcx>,
10331033
}
10341034

1035-
impl<'tcx> FlatPat<'tcx> {
1036-
/// Creates a `FlatPat` containing a simplified [`MatchPairTree`] list/forest
1037-
/// for the given pattern.
1038-
fn new(place: PlaceBuilder<'tcx>, pattern: &Pat<'tcx>, cx: &mut Builder<'_, 'tcx>) -> Self {
1039-
// Recursively build a tree of match pairs for the given pattern.
1040-
let mut match_pairs = vec![];
1041-
let mut extra_data = PatternExtraData {
1042-
span: pattern.span,
1043-
bindings: Vec::new(),
1044-
ascriptions: Vec::new(),
1045-
is_never: pattern.is_never_pattern(),
1046-
guard_patterns: Vec::new(),
1047-
};
1048-
MatchPairTree::for_pattern(place, pattern, cx, &mut match_pairs, &mut extra_data);
1049-
1050-
Self { match_pairs, extra_data }
1051-
}
1052-
}
1053-
10541035
/// Candidates are a generalization of (a) top-level match arms, and
10551036
/// (b) sub-branches of or-patterns, allowing the match-lowering process to handle
10561037
/// them both in a mostly-uniform way. For example, the list of candidates passed

0 commit comments

Comments
 (0)