Skip to content

Commit 196b6a3

Browse files
committed
Simplify
1 parent bb56714 commit 196b6a3

File tree

1 file changed

+34
-46
lines changed
  • compiler/rustc_pattern_analysis/src

1 file changed

+34
-46
lines changed

Diff for: compiler/rustc_pattern_analysis/src/rustc.rs

+34-46
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_middle::mir::interpret::Scalar;
1010
use rustc_middle::mir::{self, Const};
1111
use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange, PatRangeBoundary};
1212
use rustc_middle::ty::layout::IntegerExt;
13-
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, TypeVisitableExt, VariantDef};
13+
use rustc_middle::ty::{self, FieldDef, OpaqueTypeKey, Ty, TyCtxt, TypeVisitableExt, VariantDef};
1414
use rustc_session::lint;
1515
use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
1616
use rustc_target::abi::{FieldIdx, Integer, VariantIdx, FIRST_VARIANT};
@@ -158,32 +158,19 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
158158
}
159159
}
160160

161-
// In the cases of either a `#[non_exhaustive]` field list or a non-public field, we hide
162-
// uninhabited fields in order not to reveal the uninhabitedness of the whole variant.
163-
// This lists the fields we keep along with their types.
164-
pub(crate) fn list_variant_nonhidden_fields(
161+
pub(crate) fn variant_sub_tys(
165162
&self,
166163
ty: RevealedTy<'tcx>,
167164
variant: &'tcx VariantDef,
168-
) -> impl Iterator<Item = (FieldIdx, RevealedTy<'tcx>, bool)> + Captures<'p> + Captures<'_>
165+
) -> impl Iterator<Item = (&'tcx FieldDef, RevealedTy<'tcx>)> + Captures<'p> + Captures<'_>
169166
{
170-
let cx = self;
171-
let ty::Adt(adt, args) = ty.kind() else { bug!() };
172-
// Whether we must avoid matching the fields of this variant exhaustively.
173-
let is_non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did().is_local();
174-
175-
variant.fields.iter().enumerate().map(move |(i, field)| {
176-
let ty = field.ty(cx.tcx, args);
167+
let ty::Adt(_, args) = ty.kind() else { bug!() };
168+
variant.fields.iter().map(move |field| {
169+
let ty = field.ty(self.tcx, args);
177170
// `field.ty()` doesn't normalize after instantiating.
178-
let ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
179-
let is_visible = adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
180-
let is_uninhabited = (cx.tcx.features().exhaustive_patterns
181-
|| cx.tcx.features().min_exhaustive_patterns)
182-
&& cx.is_uninhabited(ty);
183-
184-
let skip = is_uninhabited && (!is_visible || is_non_exhaustive);
185-
let ty = cx.reveal_opaque_ty(ty);
186-
(FieldIdx::new(i), ty, skip)
171+
let ty = self.tcx.normalize_erasing_regions(self.param_env, ty);
172+
let ty = self.reveal_opaque_ty(ty);
173+
(field, ty)
187174
})
188175
}
189176

@@ -230,9 +217,21 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
230217
} else {
231218
let variant =
232219
&adt.variant(RustcMatchCheckCtxt::variant_index_for_adt(&ctor, *adt));
233-
let tys = cx
234-
.list_variant_nonhidden_fields(ty, variant)
235-
.map(|(_, ty, skip)| (ty, SkipField(skip)));
220+
221+
// In the cases of either a `#[non_exhaustive]` field list or a non-public
222+
// field, we skip uninhabited fields in order not to reveal the
223+
// uninhabitedness of the whole variant.
224+
let is_non_exhaustive =
225+
variant.is_field_list_non_exhaustive() && !adt.did().is_local();
226+
let tys = cx.variant_sub_tys(ty, variant).map(|(field, ty)| {
227+
let is_visible =
228+
adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
229+
let is_uninhabited = (cx.tcx.features().exhaustive_patterns
230+
|| cx.tcx.features().min_exhaustive_patterns)
231+
&& cx.is_uninhabited(*ty);
232+
let skip = is_uninhabited && (!is_visible || is_non_exhaustive);
233+
(ty, SkipField(skip))
234+
});
236235
cx.dropless_arena.alloc_from_iter(tys)
237236
}
238237
}
@@ -269,9 +268,8 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
269268
// patterns. If we're here we can assume this is a box pattern.
270269
1
271270
} else {
272-
let variant =
273-
&adt.variant(RustcMatchCheckCtxt::variant_index_for_adt(&ctor, *adt));
274-
self.list_variant_nonhidden_fields(ty, variant).count()
271+
let variant_idx = RustcMatchCheckCtxt::variant_index_for_adt(&ctor, *adt);
272+
adt.variant(variant_idx).fields.len()
275273
}
276274
}
277275
_ => bug!("Unexpected type for constructor `{ctor:?}`: {ty:?}"),
@@ -507,20 +505,12 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
507505
};
508506
let variant =
509507
&adt.variant(RustcMatchCheckCtxt::variant_index_for_adt(&ctor, *adt));
510-
// For each field in the variant, we store the relevant index into `self.fields` if any.
511-
let mut field_id_to_id: Vec<Option<usize>> =
512-
(0..variant.fields.len()).map(|_| None).collect();
513-
let tys = cx.list_variant_nonhidden_fields(ty, variant).enumerate().map(
514-
|(i, (field, ty, _))| {
515-
field_id_to_id[field.index()] = Some(i);
516-
ty
517-
},
518-
);
519-
fields = tys.map(|ty| DeconstructedPat::wildcard(ty)).collect();
508+
fields = cx
509+
.variant_sub_tys(ty, variant)
510+
.map(|(_, ty)| DeconstructedPat::wildcard(ty))
511+
.collect();
520512
for pat in subpatterns {
521-
if let Some(i) = field_id_to_id[pat.field.index()] {
522-
fields[i] = self.lower_pat(&pat.pattern);
523-
}
513+
fields[pat.field.index()] = self.lower_pat(&pat.pattern);
524514
}
525515
}
526516
_ => bug!("pattern has unexpected type: pat: {:?}, ty: {:?}", pat, ty),
@@ -762,11 +752,9 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
762752
ty::Adt(adt_def, args) => {
763753
let variant_index =
764754
RustcMatchCheckCtxt::variant_index_for_adt(&pat.ctor(), *adt_def);
765-
let variant = &adt_def.variant(variant_index);
766-
let subpatterns = cx
767-
.list_variant_nonhidden_fields(*pat.ty(), variant)
768-
.zip(subpatterns)
769-
.map(|((field, _ty, _), pattern)| FieldPat { field, pattern })
755+
let subpatterns = subpatterns
756+
.enumerate()
757+
.map(|(i, pattern)| FieldPat { field: FieldIdx::new(i), pattern })
770758
.collect();
771759

772760
if adt_def.is_enum() {

0 commit comments

Comments
 (0)