diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2021-10-04 23:56:20 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-10-04 23:56:20 -0700 |
| commit | 87f782ede653c0f0472cfa879d7be163af072417 (patch) | |
| tree | ddcb5cf5bb0c8b621e61fb6819d2ea9077d14c28 /compiler | |
| parent | 27b84a92c6e012f5665b4adb79adb28e8717a9bd (diff) | |
| parent | b06409ebcde5746d36e11f323ea4dcc8bebe581c (diff) | |
| download | rust-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.rs | 27 |
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)], |
