Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clairify ast::PatKind::Struct presese of .. by using an enum instead of a bool #119231

Merged
merged 1 commit into from
Dec 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>>),
Expand Down Expand Up @@ -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)]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a follow-up perhaps

}
PatKind::Tuple(pats) => {
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple");
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand All @@ -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(",");
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_expand/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_parse/src/parser/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
12 changes: 9 additions & 3 deletions src/tools/rustfmt/src/patterns.rs
aDotInTheVoid marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
Loading