about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2021-10-04 23:56:20 -0700
committerGitHub <noreply@github.com>2021-10-04 23:56:20 -0700
commit87f782ede653c0f0472cfa879d7be163af072417 (patch)
treeddcb5cf5bb0c8b621e61fb6819d2ea9077d14c28 /compiler
parent27b84a92c6e012f5665b4adb79adb28e8717a9bd (diff)
parentb06409ebcde5746d36e11f323ea4dcc8bebe581c (diff)
downloadrust-87f782ede653c0f0472cfa879d7be163af072417.tar.gz
rust-87f782ede653c0f0472cfa879d7be163af072417.zip
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
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_typeck/src/check/pat.rs27
1 files changed, 16 insertions, 11 deletions
diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index 98bec3f6eac..635219146d0 100644
--- a/compiler/rustc_typeck/src/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
@@ -181,8 +181,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, def_bm, ti)
             }
             PatKind::Path(_) => self.check_pat_path(pat, path_res.unwrap(), expected, ti),
-            PatKind::Struct(ref qpath, fields, etc) => {
-                self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, ti)
+            PatKind::Struct(ref qpath, fields, has_rest_pat) => {
+                self.check_pat_struct(pat, qpath, fields, has_rest_pat, expected, def_bm, ti)
             }
             PatKind::Or(pats) => {
                 let parent_pat = Some(pat);
@@ -712,7 +712,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         pat: &'tcx Pat<'tcx>,
         qpath: &hir::QPath<'_>,
         fields: &'tcx [hir::PatField<'tcx>],
-        etc: bool,
+        has_rest_pat: bool,
         expected: Ty<'tcx>,
         def_bm: BindingMode,
         ti: TopInfo<'tcx>,
@@ -734,7 +734,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.demand_eqtype_pat(pat.span, expected, pat_ty, ti);
 
         // Type-check subpatterns.
-        if self.check_struct_pat_fields(pat_ty, pat, variant, fields, etc, def_bm, ti) {
+        if self.check_struct_pat_fields(pat_ty, &pat, variant, fields, has_rest_pat, def_bm, ti) {
             pat_ty
         } else {
             self.tcx.ty_error()
@@ -1216,7 +1216,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         pat: &'tcx Pat<'tcx>,
         variant: &'tcx ty::VariantDef,
         fields: &'tcx [hir::PatField<'tcx>],
-        etc: bool,
+        has_rest_pat: bool,
         def_bm: BindingMode,
         ti: TopInfo<'tcx>,
     ) -> bool {
@@ -1290,7 +1290,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Require `..` if struct has non_exhaustive attribute.
         let non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did.is_local();
-        if non_exhaustive && !etc {
+        if non_exhaustive && !has_rest_pat {
             self.error_foreign_non_exhaustive_spat(pat, adt.variant_descr(), fields.is_empty());
         }
 
@@ -1302,7 +1302,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     .struct_span_err(pat.span, "union patterns should have exactly one field")
                     .emit();
             }
-            if etc {
+            if has_rest_pat {
                 tcx.sess.struct_span_err(pat.span, "`..` cannot be used in union patterns").emit();
             }
         } else if !unmentioned_fields.is_empty() {
@@ -1313,9 +1313,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     field.vis.is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx)
                 })
                 .collect();
-            if non_exhaustive {
-                self.non_exhaustive_reachable_pattern(pat, &accessible_unmentioned_fields, adt_ty)
-            } else if !etc {
+
+            if !has_rest_pat {
                 if accessible_unmentioned_fields.is_empty() {
                     unmentioned_err = Some(self.error_no_accessible_fields(pat, fields));
                 } else {
@@ -1326,6 +1325,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         fields,
                     ));
                 }
+            } else if non_exhaustive && !accessible_unmentioned_fields.is_empty() {
+                self.lint_non_exhaustive_omitted_patterns(
+                    pat,
+                    &accessible_unmentioned_fields,
+                    adt_ty,
+                )
             }
         }
         match (inexistent_fields_err, unmentioned_err) {
@@ -1653,7 +1658,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// is not exhaustive enough.
     ///
     /// Nb: the partner lint for enums lives in `compiler/rustc_mir_build/src/thir/pattern/usefulness.rs`.
-    fn non_exhaustive_reachable_pattern(
+    fn lint_non_exhaustive_omitted_patterns(
         &self,
         pat: &Pat<'_>,
         unmentioned_fields: &[(&ty::FieldDef, Ident)],