Skip to content

Commit be01e28

Browse files
committed
Push down the decision to skip fields
1 parent ef32456 commit be01e28

File tree

1 file changed

+22
-16
lines changed
  • compiler/rustc_pattern_analysis/src

1 file changed

+22
-16
lines changed

compiler/rustc_pattern_analysis/src/rustc.rs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,14 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
165165
&self,
166166
ty: RevealedTy<'tcx>,
167167
variant: &'tcx VariantDef,
168-
) -> impl Iterator<Item = (FieldIdx, RevealedTy<'tcx>)> + Captures<'p> + Captures<'_> {
168+
) -> impl Iterator<Item = (FieldIdx, RevealedTy<'tcx>, bool)> + Captures<'p> + Captures<'_>
169+
{
169170
let cx = self;
170171
let ty::Adt(adt, args) = ty.kind() else { bug!() };
171-
// Whether we must not match the fields of this variant exhaustively.
172+
// Whether we must avoid matching the fields of this variant exhaustively.
172173
let is_non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did().is_local();
173174

174-
variant.fields.iter().enumerate().filter_map(move |(i, field)| {
175+
variant.fields.iter().enumerate().map(move |(i, field)| {
175176
let ty = field.ty(cx.tcx, args);
176177
// `field.ty()` doesn't normalize after instantiating.
177178
let ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
@@ -180,12 +181,9 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
180181
|| cx.tcx.features().min_exhaustive_patterns)
181182
&& cx.is_uninhabited(ty);
182183

183-
if is_uninhabited && (!is_visible || is_non_exhaustive) {
184-
None
185-
} else {
186-
let ty = cx.reveal_opaque_ty(ty);
187-
Some((FieldIdx::new(i), ty))
188-
}
184+
let skip = is_uninhabited && (!is_visible || is_non_exhaustive);
185+
let ty = cx.reveal_opaque_ty(ty);
186+
(FieldIdx::new(i), ty, skip)
189187
})
190188
}
191189

@@ -229,7 +227,10 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
229227
} else {
230228
let variant =
231229
&adt.variant(RustcMatchCheckCtxt::variant_index_for_adt(&ctor, *adt));
232-
let tys = cx.list_variant_nonhidden_fields(ty, variant).map(|(_, ty)| ty);
230+
let tys = cx
231+
.list_variant_nonhidden_fields(ty, variant)
232+
.filter(|(_, _, skip)| !skip)
233+
.map(|(_, ty, _)| ty);
233234
cx.dropless_arena.alloc_from_iter(tys)
234235
}
235236
}
@@ -276,7 +277,9 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
276277
} else {
277278
let variant =
278279
&adt.variant(RustcMatchCheckCtxt::variant_index_for_adt(&ctor, *adt));
279-
self.list_variant_nonhidden_fields(ty, variant).count()
280+
self.list_variant_nonhidden_fields(ty, variant)
281+
.filter(|(_, _, skip)| !skip)
282+
.count()
280283
}
281284
}
282285
_ => bug!("Unexpected type for constructor `{ctor:?}`: {ty:?}"),
@@ -523,12 +526,14 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
523526
// For each field in the variant, we store the relevant index into `self.fields` if any.
524527
let mut field_id_to_id: Vec<Option<usize>> =
525528
(0..variant.fields.len()).map(|_| None).collect();
526-
let tys = cx.list_variant_nonhidden_fields(ty, variant).enumerate().map(
527-
|(i, (field, ty))| {
529+
let tys = cx
530+
.list_variant_nonhidden_fields(ty, variant)
531+
.filter(|(_, _, skip)| !skip)
532+
.enumerate()
533+
.map(|(i, (field, ty, _))| {
528534
field_id_to_id[field.index()] = Some(i);
529535
ty
530-
},
531-
);
536+
});
532537
fields = tys.map(|ty| DeconstructedPat::wildcard(ty)).collect();
533538
for pat in subpatterns {
534539
if let Some(i) = field_id_to_id[pat.field.index()] {
@@ -778,8 +783,9 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
778783
let variant = &adt_def.variant(variant_index);
779784
let subpatterns = cx
780785
.list_variant_nonhidden_fields(*pat.ty(), variant)
786+
.filter(|(_, _, skip)| !skip)
781787
.zip(subpatterns)
782-
.map(|((field, _ty), pattern)| FieldPat { field, pattern })
788+
.map(|((field, _ty, _), pattern)| FieldPat { field, pattern })
783789
.collect();
784790

785791
if adt_def.is_enum() {

0 commit comments

Comments
 (0)