about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlona Enraght-Moony <code@alona.page>2023-12-22 23:29:20 +0000
committerAlona Enraght-Moony <code@alona.page>2023-12-23 02:50:31 +0000
commit1349d86c72fe4d57134edb025d64e0ddff804d77 (patch)
treeda1cff16d8835b9a17e638f428f9ce06c54afcc6
parent3d0e6bed600c0175628e96f1118293cf44fb97bd (diff)
downloadrust-1349d86c72fe4d57134edb025d64e0ddff804d77.tar.gz
rust-1349d86c72fe4d57134edb025d64e0ddff804d77.zip
bool->enum for ast::PatKind::Struct presence of `..`
See https://github.com/rust-lang/rust/blob/cee794ee98d49b45a55ba225680d98e0c4672736/compiler/rustc_parse/src/parser/pat.rs#L890-L897 for the only place this is constructed.
-rw-r--r--compiler/rustc_ast/src/ast.rs12
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs2
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs4
-rw-r--r--compiler/rustc_expand/src/build.rs2
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs2
-rw-r--r--src/tools/rustfmt/src/patterns.rs12
7 files changed, 30 insertions, 15 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index a121b5a9bed..027b09b7f30 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -779,8 +779,7 @@ pub enum PatKind {
     Ident(BindingAnnotation, Ident, Option<P<Pat>>),
 
     /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
-    /// The `bool` is `true` in the presence of a `..`.
-    Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, /* recovered */ bool),
+    Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
 
     /// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
     TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
@@ -837,6 +836,15 @@ pub enum PatKind {
     MacCall(P<MacCall>),
 }
 
+/// Whether the `..` is present in a struct fields pattern.
+#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
+pub enum PatFieldsRest {
+    /// `module::StructName { field, ..}`
+    Rest,
+    /// `module::StructName { field }`
+    None,
+}
+
 /// The kind of borrow in an `AddrOf` expression,
 /// e.g., `&place` or `&raw const place`.
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index 017314ee4d1..3ffa4f1f2e6 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -82,7 +82,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                                 span: self.lower_span(f.span),
                             }
                         }));
-                        break hir::PatKind::Struct(qpath, fs, *etc);
+                        break hir::PatKind::Struct(qpath, fs, *etc == ast::PatFieldsRest::Rest);
                     }
                     PatKind::Tuple(pats) => {
                         let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple");
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index d6c15ec35b6..619fd7a49eb 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1427,7 +1427,7 @@ impl<'a> State<'a> {
                 }
                 self.nbsp();
                 self.word("{");
-                let empty = fields.is_empty() && !etc;
+                let empty = fields.is_empty() && *etc == ast::PatFieldsRest::None;
                 if !empty {
                     self.space();
                 }
@@ -1445,7 +1445,7 @@ impl<'a> State<'a> {
                     },
                     |f| f.pat.span,
                 );
-                if *etc {
+                if *etc == ast::PatFieldsRest::Rest {
                     if !fields.is_empty() {
                         self.word_space(",");
                     }
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index 86f555fa08b..c17d8472dcc 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -488,7 +488,7 @@ impl<'a> ExtCtxt<'a> {
         path: ast::Path,
         field_pats: ThinVec<ast::PatField>,
     ) -> P<ast::Pat> {
-        self.pat(span, PatKind::Struct(None, path, field_pats, false))
+        self.pat(span, PatKind::Struct(None, path, field_pats, ast::PatFieldsRest::None))
     }
     pub fn pat_tuple(&self, span: Span, pats: ThinVec<P<ast::Pat>>) -> P<ast::Pat> {
         self.pat(span, PatKind::Tuple(pats))
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 80233eddb9b..3fc4179af65 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -15,7 +15,7 @@ use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Delimiter};
 use rustc_ast::{
     self as ast, AttrVec, BindingAnnotation, ByRef, Expr, ExprKind, MacCall, Mutability, Pat,
-    PatField, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
+    PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
 };
 use rustc_ast_pretty::pprust;
 use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, PResult};
@@ -890,7 +890,8 @@ impl<'a> Parser<'a> {
             e.span_label(path.span, "while parsing the fields for this pattern");
             e.emit();
             self.recover_stmt();
-            (ThinVec::new(), true)
+            // When recovering, pretend we had `Foo { .. }`, to avoid cascading errors.
+            (ThinVec::new(), PatFieldsRest::Rest)
         });
         self.bump();
         Ok(PatKind::Struct(qself, path, fields, etc))
@@ -964,9 +965,9 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses the fields of a struct-like pattern.
-    fn parse_pat_fields(&mut self) -> PResult<'a, (ThinVec<PatField>, bool)> {
+    fn parse_pat_fields(&mut self) -> PResult<'a, (ThinVec<PatField>, PatFieldsRest)> {
         let mut fields = ThinVec::new();
-        let mut etc = false;
+        let mut etc = PatFieldsRest::None;
         let mut ate_comma = true;
         let mut delayed_err: Option<DiagnosticBuilder<'a, ErrorGuaranteed>> = None;
         let mut first_etc_and_maybe_comma_span = None;
@@ -1000,7 +1001,7 @@ impl<'a> Parser<'a> {
                 || self.check_noexpect(&token::DotDotDot)
                 || self.check_keyword(kw::Underscore)
             {
-                etc = true;
+                etc = PatFieldsRest::Rest;
                 let mut etc_sp = self.token.span;
                 if first_etc_and_maybe_comma_span.is_none() {
                     if let Some(comma_tok) = self
diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
index 65600009c1d..77adcdd0e6b 100644
--- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
@@ -293,7 +293,7 @@ fn extend_with_struct_pat(
     qself1: &Option<P<ast::QSelf>>,
     path1: &ast::Path,
     fps1: &mut [ast::PatField],
-    rest1: bool,
+    rest1: ast::PatFieldsRest,
     start: usize,
     alternatives: &mut ThinVec<P<Pat>>,
 ) -> bool {
diff --git a/src/tools/rustfmt/src/patterns.rs b/src/tools/rustfmt/src/patterns.rs
index 8504999b8ff..0fa6edaa5d7 100644
--- a/src/tools/rustfmt/src/patterns.rs
+++ b/src/tools/rustfmt/src/patterns.rs
@@ -259,9 +259,15 @@ impl Rewrite for Pat {
                 None,
                 None,
             ),
-            PatKind::Struct(ref qself, ref path, ref fields, ellipsis) => {
-                rewrite_struct_pat(qself, path, fields, ellipsis, self.span, context, shape)
-            }
+            PatKind::Struct(ref qself, ref path, ref fields, rest) => rewrite_struct_pat(
+                qself,
+                path,
+                fields,
+                rest == ast::PatFieldsRest::Rest,
+                self.span,
+                context,
+                shape,
+            ),
             PatKind::MacCall(ref mac) => {
                 rewrite_macro(mac, None, context, shape, MacroPosition::Pat)
             }