diff options
| author | Alona Enraght-Moony <code@alona.page> | 2023-12-22 23:29:20 +0000 |
|---|---|---|
| committer | Alona Enraght-Moony <code@alona.page> | 2023-12-23 02:50:31 +0000 |
| commit | 1349d86c72fe4d57134edb025d64e0ddff804d77 (patch) | |
| tree | da1cff16d8835b9a17e638f428f9ce06c54afcc6 | |
| parent | 3d0e6bed600c0175628e96f1118293cf44fb97bd (diff) | |
| download | rust-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.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_ast_lowering/src/pat.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_ast_pretty/src/pprust/state.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_expand/src/build.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/pat.rs | 11 | ||||
| -rw-r--r-- | src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs | 2 | ||||
| -rw-r--r-- | src/tools/rustfmt/src/patterns.rs | 12 |
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) } |
