Skip to content

Commit bdc4480

Browse files
authored
Rollup merge of #119231 - aDotInTheVoid:PatKind-struct-bool-docs, r=compiler-errors
Clairify `ast::PatKind::Struct` presese of `..` by using an enum instead of a bool The bool is mainly used for when a `..` is present, but it is also set on recovery to avoid errors. The doc comment not describes both of these cases. 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. r? ``@compiler-errors``
2 parents edcbcc7 + 1349d86 commit bdc4480

File tree

7 files changed

+30
-15
lines changed

7 files changed

+30
-15
lines changed

compiler/rustc_ast/src/ast.rs

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

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

760759
/// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
761760
TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
@@ -812,6 +811,15 @@ pub enum PatKind {
812811
MacCall(P<MacCall>),
813812
}
814813

814+
/// Whether the `..` is present in a struct fields pattern.
815+
#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)]
816+
pub enum PatFieldsRest {
817+
/// `module::StructName { field, ..}`
818+
Rest,
819+
/// `module::StructName { field }`
820+
None,
821+
}
822+
815823
/// The kind of borrow in an `AddrOf` expression,
816824
/// e.g., `&place` or `&raw const place`.
817825
#[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_expand/src/build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ impl<'a> ExtCtxt<'a> {
491491
path: ast::Path,
492492
field_pats: ThinVec<ast::PatField>,
493493
) -> P<ast::Pat> {
494-
self.pat(span, PatKind::Struct(None, path, field_pats, false))
494+
self.pat(span, PatKind::Struct(None, path, field_pats, ast::PatFieldsRest::None))
495495
}
496496
pub fn pat_tuple(&self, span: Span, pats: ThinVec<P<ast::Pat>>) -> P<ast::Pat> {
497497
self.pat(span, PatKind::Tuple(pats))

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, PResult};
@@ -891,7 +891,8 @@ impl<'a> Parser<'a> {
891891
e.span_label(path.span, "while parsing the fields for this pattern");
892892
e.emit();
893893
self.recover_stmt();
894-
(ThinVec::new(), true)
894+
// When recovering, pretend we had `Foo { .. }`, to avoid cascading errors.
895+
(ThinVec::new(), PatFieldsRest::Rest)
895896
});
896897
self.bump();
897898
Ok(PatKind::Struct(qself, path, fields, etc))
@@ -965,9 +966,9 @@ impl<'a> Parser<'a> {
965966
}
966967

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

src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ fn extend_with_struct_pat(
293293
qself1: &Option<P<ast::QSelf>>,
294294
path1: &ast::Path,
295295
fps1: &mut [ast::PatField],
296-
rest1: bool,
296+
rest1: ast::PatFieldsRest,
297297
start: usize,
298298
alternatives: &mut ThinVec<P<Pat>>,
299299
) -> bool {

src/tools/rustfmt/src/patterns.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -259,9 +259,15 @@ impl Rewrite for Pat {
259259
None,
260260
None,
261261
),
262-
PatKind::Struct(ref qself, ref path, ref fields, ellipsis) => {
263-
rewrite_struct_pat(qself, path, fields, ellipsis, self.span, context, shape)
264-
}
262+
PatKind::Struct(ref qself, ref path, ref fields, rest) => rewrite_struct_pat(
263+
qself,
264+
path,
265+
fields,
266+
rest == ast::PatFieldsRest::Rest,
267+
self.span,
268+
context,
269+
shape,
270+
),
265271
PatKind::MacCall(ref mac) => {
266272
rewrite_macro(mac, None, context, shape, MacroPosition::Pat)
267273
}

0 commit comments

Comments
 (0)