@@ -62,7 +62,6 @@ use rustc_span::{Span, DUMMY_SP};
62
62
use rustc_target::abi::{Integer, Size, VariantIdx};
63
63
64
64
use smallvec::{smallvec, SmallVec};
65
- use std::borrow::Cow;
66
65
use std::cmp::{self, max, min, Ordering};
67
66
use std::fmt;
68
67
use std::iter::{once, IntoIterator};
@@ -1107,33 +1106,27 @@ impl<'tcx> SplitWildcard<'tcx> {
1107
1106
/// because the code mustn't observe that it is uninhabited. In that case that field is not
1108
1107
/// included in `fields`. For that reason, when you have a `mir::Field` you must use
1109
1108
/// `index_with_declared_idx`.
1110
- #[derive(Debug, Clone)]
1109
+ #[derive(Debug, Clone, Copy )]
1111
1110
pub(super) struct Fields<'p, 'tcx> {
1112
- fields: SmallVec<[ &'p DeconstructedPat<'p, 'tcx>; 2]> ,
1111
+ fields: &'p [ DeconstructedPat<'p, 'tcx>] ,
1113
1112
}
1114
1113
1115
1114
impl<'p, 'tcx> Fields<'p, 'tcx> {
1116
1115
fn empty() -> Self {
1117
- Fields { fields: SmallVec::new() }
1116
+ Fields { fields: &[] }
1118
1117
}
1119
1118
1120
1119
fn singleton(cx: &MatchCheckCtxt<'p, 'tcx>, field: DeconstructedPat<'p, 'tcx>) -> Self {
1121
1120
let field: &_ = cx.pattern_arena.alloc(field);
1122
- Fields { fields: smallvec![ field] }
1121
+ Fields { fields: std::slice::from_ref( field) }
1123
1122
}
1124
1123
1125
1124
pub(super) fn from_iter(
1126
1125
cx: &MatchCheckCtxt<'p, 'tcx>,
1127
1126
fields: impl IntoIterator<Item = DeconstructedPat<'p, 'tcx>>,
1128
1127
) -> Self {
1129
- let fields: &_ = cx.pattern_arena.alloc_from_iter(fields);
1130
- Fields { fields: fields.into_iter().collect() }
1131
- }
1132
-
1133
- pub(super) fn from_ref_iter(
1134
- fields: impl IntoIterator<Item = &'p DeconstructedPat<'p, 'tcx>>,
1135
- ) -> Self {
1136
- Fields { fields: fields.into_iter().collect() }
1128
+ let fields: &[_] = cx.pattern_arena.alloc_from_iter(fields);
1129
+ Fields { fields }
1137
1130
}
1138
1131
1139
1132
fn wildcards_from_tys(
@@ -1222,7 +1215,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
1222
1215
pub(super) fn iter_patterns<'a>(
1223
1216
&'a self,
1224
1217
) -> impl Iterator<Item = &'p DeconstructedPat<'p, 'tcx>> + Captures<'a> {
1225
- self.fields.iter().copied()
1218
+ self.fields.iter()
1226
1219
}
1227
1220
}
1228
1221
@@ -1245,9 +1238,8 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
1245
1238
1246
1239
pub(crate) fn from_pat(cx: &MatchCheckCtxt<'p, 'tcx>, pat: &Pat<'tcx>) -> Self {
1247
1240
let mkpat = |pat| DeconstructedPat::from_pat(cx, pat);
1248
- let allocpat = |pat| &*cx.pattern_arena.alloc(mkpat(pat));
1249
1241
let ctor;
1250
- let mut fields;
1242
+ let fields;
1251
1243
match pat.kind.as_ref() {
1252
1244
PatKind::AscribeUserType { subpattern, .. } => return mkpat(subpattern),
1253
1245
PatKind::Binding { subpattern: Some(subpat), .. } => return mkpat(subpat),
@@ -1263,10 +1255,15 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
1263
1255
match pat.ty.kind() {
1264
1256
ty::Tuple(fs) => {
1265
1257
ctor = Single;
1266
- fields = Fields::wildcards_from_tys(cx, fs.iter().map(|ty| ty.expect_ty()));
1258
+ let mut wilds: SmallVec<[_; 2]> = fs
1259
+ .iter()
1260
+ .map(|ty| ty.expect_ty())
1261
+ .map(DeconstructedPat::wildcard)
1262
+ .collect();
1267
1263
for pat in subpatterns {
1268
- fields.fields [pat.field.index()] = allocpat (&pat.pattern);
1264
+ wilds [pat.field.index()] = mkpat (&pat.pattern);
1269
1265
}
1266
+ fields = Fields::from_iter(cx, wilds);
1270
1267
}
1271
1268
ty::Adt(adt, substs) if adt.is_box() => {
1272
1269
// The only legal patterns of type `Box` (outside `std`) are `_` and box
@@ -1306,12 +1303,14 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
1306
1303
field_id_to_id[field.index()] = Some(i);
1307
1304
ty
1308
1305
});
1309
- fields = Fields::wildcards_from_tys(cx, tys);
1306
+ let mut wilds: SmallVec<[_; 2]> =
1307
+ tys.map(DeconstructedPat::wildcard).collect();
1310
1308
for pat in subpatterns {
1311
1309
if let Some(i) = field_id_to_id[pat.field.index()] {
1312
- fields.fields [i] = allocpat (&pat.pattern);
1310
+ wilds [i] = mkpat (&pat.pattern);
1313
1311
}
1314
1312
}
1313
+ fields = Fields::from_iter(cx, wilds);
1315
1314
}
1316
1315
_ => bug!("pattern has unexpected type: pat: {:?}, ty: {:?}", pat, pat.ty),
1317
1316
}
@@ -1510,40 +1509,38 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
1510
1509
&'a self,
1511
1510
cx: &MatchCheckCtxt<'p, 'tcx>,
1512
1511
other_ctor: &Constructor<'tcx>,
1513
- ) -> Cow<'a, Fields <'p, 'tcx>> {
1512
+ ) -> SmallVec<[&'p DeconstructedPat <'p, 'tcx>; 2] > {
1514
1513
match (&self.ctor, other_ctor) {
1515
1514
(Wildcard, _) => {
1516
1515
// We return a wildcard for each field of `other_ctor`.
1517
- Cow::Owned( Fields::wildcards(cx, self.ty, other_ctor))
1516
+ Fields::wildcards(cx, self.ty, other_ctor).iter_patterns().collect( )
1518
1517
}
1519
1518
(Slice(self_slice), Slice(other_slice))
1520
1519
if self_slice.arity() != other_slice.arity() =>
1521
1520
{
1522
1521
// The only tricky case: two slices of different arity. Since `self_slice` covers
1523
1522
// `other_slice`, `self_slice` must be `VarLen`, i.e. of the form
1524
1523
// `[prefix, .., suffix]`. Moreover `other_slice` is guaranteed to have a larger
1525
- // arity. We fill the middle part with enough wildcards to reach the length of the
1526
- // new, larger slice.
1524
+ // arity. So we fill the middle part with enough wildcards to reach the length of
1525
+ // the new, larger slice.
1527
1526
match self_slice.kind {
1528
1527
FixedLen(_) => bug!("{:?} doesn't cover {:?}", self_slice, other_slice),
1529
1528
VarLen(prefix, suffix) => {
1530
1529
let inner_ty = match *self.ty.kind() {
1531
1530
ty::Slice(ty) | ty::Array(ty, _) => ty,
1532
1531
_ => bug!("bad slice pattern {:?} {:?}", self.ctor, self.ty),
1533
1532
};
1534
- let prefix = self.fields.fields[..prefix].iter().copied();
1535
- let suffix =
1536
- self.fields.fields[self_slice.arity() - suffix..].iter().copied();
1533
+ let prefix = &self.fields.fields[..prefix];
1534
+ let suffix = &self.fields.fields[self_slice.arity() - suffix..];
1535
+ let wildcard: &_ =
1536
+ cx.pattern_arena.alloc(DeconstructedPat::wildcard(inner_ty));
1537
1537
let extra_wildcards = other_slice.arity() - self_slice.arity();
1538
- let extra_wildcards: &[_] = cx.pattern_arena.alloc_from_iter(
1539
- (0..extra_wildcards).map(|_| DeconstructedPat::wildcard(inner_ty)),
1540
- );
1541
- let fields = prefix.chain(extra_wildcards).chain(suffix);
1542
- Cow::Owned(Fields::from_ref_iter(fields))
1538
+ let extra_wildcards = (0..extra_wildcards).map(|_| wildcard);
1539
+ prefix.iter().chain(extra_wildcards).chain(suffix).collect()
1543
1540
}
1544
1541
}
1545
1542
}
1546
- _ => Cow::Borrowed(& self.fields),
1543
+ _ => self.fields.iter_patterns().collect( ),
1547
1544
}
1548
1545
}
1549
1546
}
0 commit comments