Skip to content

Commit 87f782e

Browse files
authored
Rollup merge of #89423 - DevinR528:reachable-fields, r=Nadrieril
Fix ICE caused by non_exaustive_omitted_patterns struct lint fixes #89382 Add check that a list of `Pat`s is non empty to prevent ICE in `FnCtxt::lint_non_exhaustive_omitted_patterns`. Is related to #89374 and #89105
2 parents 27b84a9 + b06409e commit 87f782e

File tree

4 files changed

+31
-14
lines changed

4 files changed

+31
-14
lines changed

compiler/rustc_typeck/src/check/pat.rs

+16-11
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
181181
self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, def_bm, ti)
182182
}
183183
PatKind::Path(_) => self.check_pat_path(pat, path_res.unwrap(), expected, ti),
184-
PatKind::Struct(ref qpath, fields, etc) => {
185-
self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, ti)
184+
PatKind::Struct(ref qpath, fields, has_rest_pat) => {
185+
self.check_pat_struct(pat, qpath, fields, has_rest_pat, expected, def_bm, ti)
186186
}
187187
PatKind::Or(pats) => {
188188
let parent_pat = Some(pat);
@@ -712,7 +712,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
712712
pat: &'tcx Pat<'tcx>,
713713
qpath: &hir::QPath<'_>,
714714
fields: &'tcx [hir::PatField<'tcx>],
715-
etc: bool,
715+
has_rest_pat: bool,
716716
expected: Ty<'tcx>,
717717
def_bm: BindingMode,
718718
ti: TopInfo<'tcx>,
@@ -734,7 +734,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
734734
self.demand_eqtype_pat(pat.span, expected, pat_ty, ti);
735735

736736
// Type-check subpatterns.
737-
if self.check_struct_pat_fields(pat_ty, pat, variant, fields, etc, def_bm, ti) {
737+
if self.check_struct_pat_fields(pat_ty, &pat, variant, fields, has_rest_pat, def_bm, ti) {
738738
pat_ty
739739
} else {
740740
self.tcx.ty_error()
@@ -1216,7 +1216,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12161216
pat: &'tcx Pat<'tcx>,
12171217
variant: &'tcx ty::VariantDef,
12181218
fields: &'tcx [hir::PatField<'tcx>],
1219-
etc: bool,
1219+
has_rest_pat: bool,
12201220
def_bm: BindingMode,
12211221
ti: TopInfo<'tcx>,
12221222
) -> bool {
@@ -1290,7 +1290,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12901290

12911291
// Require `..` if struct has non_exhaustive attribute.
12921292
let non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did.is_local();
1293-
if non_exhaustive && !etc {
1293+
if non_exhaustive && !has_rest_pat {
12941294
self.error_foreign_non_exhaustive_spat(pat, adt.variant_descr(), fields.is_empty());
12951295
}
12961296

@@ -1302,7 +1302,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13021302
.struct_span_err(pat.span, "union patterns should have exactly one field")
13031303
.emit();
13041304
}
1305-
if etc {
1305+
if has_rest_pat {
13061306
tcx.sess.struct_span_err(pat.span, "`..` cannot be used in union patterns").emit();
13071307
}
13081308
} else if !unmentioned_fields.is_empty() {
@@ -1313,9 +1313,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13131313
field.vis.is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx)
13141314
})
13151315
.collect();
1316-
if non_exhaustive {
1317-
self.non_exhaustive_reachable_pattern(pat, &accessible_unmentioned_fields, adt_ty)
1318-
} else if !etc {
1316+
1317+
if !has_rest_pat {
13191318
if accessible_unmentioned_fields.is_empty() {
13201319
unmentioned_err = Some(self.error_no_accessible_fields(pat, fields));
13211320
} else {
@@ -1326,6 +1325,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13261325
fields,
13271326
));
13281327
}
1328+
} else if non_exhaustive && !accessible_unmentioned_fields.is_empty() {
1329+
self.lint_non_exhaustive_omitted_patterns(
1330+
pat,
1331+
&accessible_unmentioned_fields,
1332+
adt_ty,
1333+
)
13291334
}
13301335
}
13311336
match (inexistent_fields_err, unmentioned_err) {
@@ -1653,7 +1658,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16531658
/// is not exhaustive enough.
16541659
///
16551660
/// Nb: the partner lint for enums lives in `compiler/rustc_mir_build/src/thir/pattern/usefulness.rs`.
1656-
fn non_exhaustive_reachable_pattern(
1661+
fn lint_non_exhaustive_omitted_patterns(
16571662
&self,
16581663
pat: &Pat<'_>,
16591664
unmentioned_fields: &[(&ty::FieldDef, Ident)],

src/test/ui/rfc-2008-non-exhaustive/auxiliary/structs.rs

+8
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,11 @@ pub struct NestedStruct {
3131
pub foo: u16,
3232
pub bar: NormalStruct,
3333
}
34+
35+
#[derive(Default)]
36+
#[non_exhaustive]
37+
pub struct MixedVisFields {
38+
pub a: u16,
39+
pub b: bool,
40+
pub(crate) foo: bool,
41+
}

src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use enums::{
1010
EmptyNonExhaustiveEnum, NestedNonExhaustive, NonExhaustiveEnum, NonExhaustiveSingleVariant,
1111
VariantNonExhaustive,
1212
};
13-
use structs::{FunctionalRecord, NestedStruct, NormalStruct};
13+
use structs::{FunctionalRecord, MixedVisFields, NestedStruct, NormalStruct};
1414

1515
#[non_exhaustive]
1616
#[derive(Default)]
@@ -141,6 +141,10 @@ fn main() {
141141
//~^ some fields are not explicitly listed
142142
//~^^ some fields are not explicitly listed
143143

144+
// Ok: this tests https://github.com/rust-lang/rust/issues/89382
145+
#[warn(non_exhaustive_omitted_patterns)]
146+
let MixedVisFields { a, b, .. } = MixedVisFields::default();
147+
144148
// Ok: because this only has 1 variant
145149
#[deny(non_exhaustive_omitted_patterns)]
146150
match NonExhaustiveSingleVariant::A(true) {

src/test/ui/rfc-2008-non-exhaustive/reachable-patterns.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,13 @@ LL | #[deny(non_exhaustive_omitted_patterns)]
129129
= note: the matched value is of type `ErrorKind` and the `non_exhaustive_omitted_patterns` attribute was found
130130

131131
error: some variants are not matched explicitly
132-
--> $DIR/reachable-patterns.rs:153:9
132+
--> $DIR/reachable-patterns.rs:157:9
133133
|
134134
LL | _ => {}
135135
| ^ pattern `A(_)` not covered
136136
|
137137
note: the lint level is defined here
138-
--> $DIR/reachable-patterns.rs:151:12
138+
--> $DIR/reachable-patterns.rs:155:12
139139
|
140140
LL | #[deny(non_exhaustive_omitted_patterns)]
141141
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)