Skip to content

Commit

Permalink
bool->enum for ast::PatKind::Struct presence of ..
Browse files Browse the repository at this point in the history
  • Loading branch information
aDotInTheVoid committed Dec 23, 2023
1 parent 3d0e6be commit 03bed27
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 16 deletions.
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);
}
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
11 changes: 7 additions & 4 deletions src/tools/rustfmt/src/patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ fn rewrite_struct_pat(
qself: &Option<ptr::P<ast::QSelf>>,
path: &ast::Path,
fields: &[ast::PatField],
ellipsis: bool,
ellipsis: ast::PatFieldsRest,
span: Span,
context: &RewriteContext<'_>,
shape: Shape,
Expand All @@ -285,11 +285,14 @@ fn rewrite_struct_pat(
let path_shape = shape.sub_width(2)?;
let path_str = rewrite_path(context, PathContext::Expr, qself, path, path_shape)?;

if fields.is_empty() && !ellipsis {
if fields.is_empty() && ellipsis == ast::PatFieldsRest::None {
return Some(format!("{path_str} {{}}"));
}

let (ellipsis_str, terminator) = if ellipsis { (", ..", "..") } else { ("", "}") };
let (ellipsis_str, terminator) = match ellipsis {
ast::PatFieldsRest::Rest => (", ..", ".."),
ast::PatFieldsRest::None => ("", "}"),
};

// 3 = ` { `, 2 = ` }`.
let (h_shape, v_shape) =
Expand Down Expand Up @@ -324,7 +327,7 @@ fn rewrite_struct_pat(

let has_trailing_comma = fmt.needs_trailing_separator();

if ellipsis {
if ellipsis == ast::PatFieldsRest::Rest {
if fields_str.contains('\n') || fields_str.len() > one_line_width {
// Add a missing trailing comma.
if !has_trailing_comma {
Expand Down

0 comments on commit 03bed27

Please sign in to comment.