@@ -181,8 +181,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
181
181
self . check_pat_tuple_struct ( pat, qpath, subpats, ddpos, expected, def_bm, ti)
182
182
}
183
183
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)
186
186
}
187
187
PatKind :: Or ( pats) => {
188
188
let parent_pat = Some ( pat) ;
@@ -712,7 +712,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
712
712
pat : & ' tcx Pat < ' tcx > ,
713
713
qpath : & hir:: QPath < ' _ > ,
714
714
fields : & ' tcx [ hir:: PatField < ' tcx > ] ,
715
- etc : bool ,
715
+ has_rest_pat : bool ,
716
716
expected : Ty < ' tcx > ,
717
717
def_bm : BindingMode ,
718
718
ti : TopInfo < ' tcx > ,
@@ -734,7 +734,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
734
734
self . demand_eqtype_pat ( pat. span , expected, pat_ty, ti) ;
735
735
736
736
// 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) {
738
738
pat_ty
739
739
} else {
740
740
self . tcx . ty_error ( )
@@ -1216,7 +1216,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1216
1216
pat : & ' tcx Pat < ' tcx > ,
1217
1217
variant : & ' tcx ty:: VariantDef ,
1218
1218
fields : & ' tcx [ hir:: PatField < ' tcx > ] ,
1219
- etc : bool ,
1219
+ has_rest_pat : bool ,
1220
1220
def_bm : BindingMode ,
1221
1221
ti : TopInfo < ' tcx > ,
1222
1222
) -> bool {
@@ -1290,7 +1290,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1290
1290
1291
1291
// Require `..` if struct has non_exhaustive attribute.
1292
1292
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 {
1294
1294
self . error_foreign_non_exhaustive_spat ( pat, adt. variant_descr ( ) , fields. is_empty ( ) ) ;
1295
1295
}
1296
1296
@@ -1302,7 +1302,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1302
1302
. struct_span_err ( pat. span , "union patterns should have exactly one field" )
1303
1303
. emit ( ) ;
1304
1304
}
1305
- if etc {
1305
+ if has_rest_pat {
1306
1306
tcx. sess . struct_span_err ( pat. span , "`..` cannot be used in union patterns" ) . emit ( ) ;
1307
1307
}
1308
1308
} else if !unmentioned_fields. is_empty ( ) {
@@ -1313,9 +1313,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1313
1313
field. vis . is_accessible_from ( tcx. parent_module ( pat. hir_id ) . to_def_id ( ) , tcx)
1314
1314
} )
1315
1315
. 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 {
1319
1318
if accessible_unmentioned_fields. is_empty ( ) {
1320
1319
unmentioned_err = Some ( self . error_no_accessible_fields ( pat, fields) ) ;
1321
1320
} else {
@@ -1326,6 +1325,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1326
1325
fields,
1327
1326
) ) ;
1328
1327
}
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
+ )
1329
1334
}
1330
1335
}
1331
1336
match ( inexistent_fields_err, unmentioned_err) {
@@ -1653,7 +1658,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1653
1658
/// is not exhaustive enough.
1654
1659
///
1655
1660
/// 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 (
1657
1662
& self ,
1658
1663
pat : & Pat < ' _ > ,
1659
1664
unmentioned_fields : & [ ( & ty:: FieldDef , Ident ) ] ,
0 commit comments