Skip to content

Commit 0ad2eff

Browse files
committed
Precompute the presence of bindings and ascriptions
1 parent 1091425 commit 0ad2eff

File tree

2 files changed

+41
-10
lines changed

2 files changed

+41
-10
lines changed

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

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,9 @@ struct FlatPat<'pat, 'tcx> {
954954

955955
/// ...and these types asserted.
956956
ascriptions: Vec<Ascription<'tcx>>,
957+
958+
/// Whether this recursively contains no bindings or ascriptions.
959+
simple: bool,
957960
}
958961

959962
impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
@@ -968,7 +971,11 @@ impl<'tcx, 'pat> FlatPat<'pat, 'tcx> {
968971

969972
cx.simplify_match_pairs(&mut match_pairs, &mut bindings, &mut ascriptions);
970973

971-
FlatPat { span: pattern.span, match_pairs, bindings, ascriptions }
974+
let simple = bindings.is_empty()
975+
&& ascriptions.is_empty()
976+
&& match_pairs.iter().all(|mp| mp.is_simple());
977+
978+
FlatPat { span: pattern.span, match_pairs, bindings, ascriptions, simple }
972979
}
973980
}
974981

@@ -1084,12 +1091,27 @@ struct Ascription<'tcx> {
10841091

10851092
#[derive(Debug, Clone)]
10861093
enum TestCase<'pat, 'tcx> {
1087-
Irrefutable { binding: Option<Binding<'tcx>>, ascription: Option<Ascription<'tcx>> },
1088-
Variant { adt_def: ty::AdtDef<'tcx>, variant_index: VariantIdx },
1089-
Constant { value: mir::Const<'tcx> },
1094+
Irrefutable {
1095+
binding: Option<Binding<'tcx>>,
1096+
ascription: Option<Ascription<'tcx>>,
1097+
},
1098+
Variant {
1099+
adt_def: ty::AdtDef<'tcx>,
1100+
variant_index: VariantIdx,
1101+
},
1102+
Constant {
1103+
value: mir::Const<'tcx>,
1104+
},
10901105
Range(&'pat PatRange<'tcx>),
1091-
Slice { len: usize, variable_length: bool },
1092-
Or { pats: Box<[FlatPat<'pat, 'tcx>]> },
1106+
Slice {
1107+
len: usize,
1108+
variable_length: bool,
1109+
},
1110+
Or {
1111+
pats: Box<[FlatPat<'pat, 'tcx>]>,
1112+
/// Whether this recursively contains no bindings or ascriptions.
1113+
simple: bool,
1114+
},
10931115
}
10941116

10951117
#[derive(Debug, Clone)]
@@ -1443,7 +1465,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
14431465

14441466
let first_match_pair = first_candidate.match_pairs.remove(0);
14451467
let or_span = first_match_pair.pattern.span;
1446-
let TestCase::Or { pats } = first_match_pair.test_case else { unreachable!() };
1468+
let TestCase::Or { pats, .. } = first_match_pair.test_case else { unreachable!() };
14471469

14481470
let remainder_start = self.cfg.start_new_block();
14491471
// Test the alternatives of this or-pattern.

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,12 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
122122
let mut subpairs = Vec::new();
123123
let test_case = match pattern.kind {
124124
PatKind::Never | PatKind::Wild | PatKind::Error(_) => default_irrefutable(),
125-
PatKind::Or { ref pats } => TestCase::Or {
126-
pats: pats.iter().map(|pat| FlatPat::new(place.clone(), pat, cx)).collect(),
127-
},
125+
PatKind::Or { ref pats } => {
126+
let pats: Box<[_]> =
127+
pats.iter().map(|pat| FlatPat::new(place.clone(), pat, cx)).collect();
128+
let simple = pats.iter().all(|fpat| fpat.simple);
129+
TestCase::Or { pats, simple }
130+
}
128131

129132
PatKind::Range(ref range) => {
130133
if range.is_full_range(cx.tcx) == Some(true) {
@@ -260,6 +263,12 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
260263

261264
MatchPair { place, test_case, subpairs, pattern }
262265
}
266+
267+
/// Whether this recursively contains no bindings or ascriptions.
268+
pub(super) fn is_simple(&self) -> bool {
269+
!matches!(self.test_case, TestCase::Or { simple: false, .. })
270+
&& self.subpairs.iter().all(|p| p.is_simple())
271+
}
263272
}
264273

265274
pub(super) struct FakeBorrowCollector<'a, 'b, 'tcx> {

0 commit comments

Comments
 (0)