Skip to content

Commit 2b620be

Browse files
committed
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.
1 parent 3d0e6be commit 2b620be

File tree

4 files changed

+19
-10
lines changed

4 files changed

+19
-10
lines changed

compiler/rustc_ast/src/ast.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -779,8 +779,7 @@ pub enum PatKind {
779779
Ident(BindingAnnotation, Ident, Option<P<Pat>>),
780780

781781
/// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`).
782-
/// The `bool` is `true` in the presence of a `..`.
783-
Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, /* recovered */ bool),
782+
Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, PatFieldsRest),
784783

785784
/// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
786785
TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
@@ -837,6 +836,15 @@ pub enum PatKind {
837836
MacCall(P<MacCall>),
838837
}
839838

839+
/// Whether the `..` is present in a struct fields pattern.
840+
#[derive(Clone, Encodable, Decodable, Debug, PartialEq)]
841+
pub enum PatFieldsRest {
842+
/// `module::StructName { field, ..}`
843+
Rest,
844+
/// `module::StructName { field }`
845+
None,
846+
}
847+
840848
/// The kind of borrow in an `AddrOf` expression,
841849
/// e.g., `&place` or `&raw const place`.
842850
#[derive(Clone, Copy, PartialEq, Eq, Debug)]

compiler/rustc_ast_lowering/src/pat.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
8282
span: self.lower_span(f.span),
8383
}
8484
}));
85-
break hir::PatKind::Struct(qpath, fs, *etc);
85+
break hir::PatKind::Struct(qpath, fs, *etc == ast::PatFieldsRest::Rest);
8686
}
8787
PatKind::Tuple(pats) => {
8888
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple");

compiler/rustc_ast_pretty/src/pprust/state.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1427,7 +1427,7 @@ impl<'a> State<'a> {
14271427
}
14281428
self.nbsp();
14291429
self.word("{");
1430-
let empty = fields.is_empty() && !etc;
1430+
let empty = fields.is_empty() && *etc == ast::PatFieldsRest::None;
14311431
if !empty {
14321432
self.space();
14331433
}
@@ -1445,7 +1445,7 @@ impl<'a> State<'a> {
14451445
},
14461446
|f| f.pat.span,
14471447
);
1448-
if *etc {
1448+
if *etc == ast::PatFieldsRest::Rest {
14491449
if !fields.is_empty() {
14501450
self.word_space(",");
14511451
}

compiler/rustc_parse/src/parser/pat.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_ast::ptr::P;
1515
use rustc_ast::token::{self, Delimiter};
1616
use rustc_ast::{
1717
self as ast, AttrVec, BindingAnnotation, ByRef, Expr, ExprKind, MacCall, Mutability, Pat,
18-
PatField, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
18+
PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
1919
};
2020
use rustc_ast_pretty::pprust;
2121
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, PResult};
@@ -890,7 +890,8 @@ impl<'a> Parser<'a> {
890890
e.span_label(path.span, "while parsing the fields for this pattern");
891891
e.emit();
892892
self.recover_stmt();
893-
(ThinVec::new(), true)
893+
// When recovering, pretend we had `Foo { .. }`, to avoid cascading errors.
894+
(ThinVec::new(), PatFieldsRest::Rest)
894895
});
895896
self.bump();
896897
Ok(PatKind::Struct(qself, path, fields, etc))
@@ -964,9 +965,9 @@ impl<'a> Parser<'a> {
964965
}
965966

966967
/// Parses the fields of a struct-like pattern.
967-
fn parse_pat_fields(&mut self) -> PResult<'a, (ThinVec<PatField>, bool)> {
968+
fn parse_pat_fields(&mut self) -> PResult<'a, (ThinVec<PatField>, PatFieldsRest)> {
968969
let mut fields = ThinVec::new();
969-
let mut etc = false;
970+
let mut etc = PatFieldsRest::None;
970971
let mut ate_comma = true;
971972
let mut delayed_err: Option<DiagnosticBuilder<'a, ErrorGuaranteed>> = None;
972973
let mut first_etc_and_maybe_comma_span = None;
@@ -1000,7 +1001,7 @@ impl<'a> Parser<'a> {
10001001
|| self.check_noexpect(&token::DotDotDot)
10011002
|| self.check_keyword(kw::Underscore)
10021003
{
1003-
etc = true;
1004+
etc = PatFieldsRest::Rest;
10041005
let mut etc_sp = self.token.span;
10051006
if first_etc_and_maybe_comma_span.is_none() {
10061007
if let Some(comma_tok) = self

0 commit comments

Comments
 (0)