1
Fork 0

bool->enum for ast::PatKind::Struct presence of ..

See cee794ee98/compiler/rustc_parse/src/parser/pat.rs (L890-L897) for the only place this is constructed.
This commit is contained in:
Alona Enraght-Moony 2023-12-22 23:29:20 +00:00
parent 3d0e6bed60
commit 1349d86c72
7 changed files with 30 additions and 15 deletions

View file

@ -779,8 +779,7 @@ pub enum PatKind {
Ident(BindingAnnotation, Ident, Option<P<Pat>>), Ident(BindingAnnotation, Ident, Option<P<Pat>>),
/// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`). /// 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>, PatFieldsRest),
Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, /* recovered */ bool),
/// A tuple struct/variant pattern (`Variant(x, y, .., z)`). /// A tuple struct/variant pattern (`Variant(x, y, .., z)`).
TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>), TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>),
@ -837,6 +836,15 @@ pub enum PatKind {
MacCall(P<MacCall>), 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, /// The kind of borrow in an `AddrOf` expression,
/// e.g., `&place` or `&raw const place`. /// e.g., `&place` or `&raw const place`.
#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Debug)]

View file

@ -82,7 +82,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
span: self.lower_span(f.span), 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) => { PatKind::Tuple(pats) => {
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple"); let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple");

View file

@ -1427,7 +1427,7 @@ impl<'a> State<'a> {
} }
self.nbsp(); self.nbsp();
self.word("{"); self.word("{");
let empty = fields.is_empty() && !etc; let empty = fields.is_empty() && *etc == ast::PatFieldsRest::None;
if !empty { if !empty {
self.space(); self.space();
} }
@ -1445,7 +1445,7 @@ impl<'a> State<'a> {
}, },
|f| f.pat.span, |f| f.pat.span,
); );
if *etc { if *etc == ast::PatFieldsRest::Rest {
if !fields.is_empty() { if !fields.is_empty() {
self.word_space(","); self.word_space(",");
} }

View file

@ -488,7 +488,7 @@ impl<'a> ExtCtxt<'a> {
path: ast::Path, path: ast::Path,
field_pats: ThinVec<ast::PatField>, field_pats: ThinVec<ast::PatField>,
) -> P<ast::Pat> { ) -> 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> { pub fn pat_tuple(&self, span: Span, pats: ThinVec<P<ast::Pat>>) -> P<ast::Pat> {
self.pat(span, PatKind::Tuple(pats)) self.pat(span, PatKind::Tuple(pats))

View file

@ -15,7 +15,7 @@ use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter}; use rustc_ast::token::{self, Delimiter};
use rustc_ast::{ use rustc_ast::{
self as ast, AttrVec, BindingAnnotation, ByRef, Expr, ExprKind, MacCall, Mutability, Pat, 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_ast_pretty::pprust;
use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, PResult}; 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.span_label(path.span, "while parsing the fields for this pattern");
e.emit(); e.emit();
self.recover_stmt(); self.recover_stmt();
(ThinVec::new(), true) // When recovering, pretend we had `Foo { .. }`, to avoid cascading errors.
(ThinVec::new(), PatFieldsRest::Rest)
}); });
self.bump(); self.bump();
Ok(PatKind::Struct(qself, path, fields, etc)) Ok(PatKind::Struct(qself, path, fields, etc))
@ -964,9 +965,9 @@ impl<'a> Parser<'a> {
} }
/// Parses the fields of a struct-like pattern. /// 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 fields = ThinVec::new();
let mut etc = false; let mut etc = PatFieldsRest::None;
let mut ate_comma = true; let mut ate_comma = true;
let mut delayed_err: Option<DiagnosticBuilder<'a, ErrorGuaranteed>> = None; let mut delayed_err: Option<DiagnosticBuilder<'a, ErrorGuaranteed>> = None;
let mut first_etc_and_maybe_comma_span = 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_noexpect(&token::DotDotDot)
|| self.check_keyword(kw::Underscore) || self.check_keyword(kw::Underscore)
{ {
etc = true; etc = PatFieldsRest::Rest;
let mut etc_sp = self.token.span; let mut etc_sp = self.token.span;
if first_etc_and_maybe_comma_span.is_none() { if first_etc_and_maybe_comma_span.is_none() {
if let Some(comma_tok) = self if let Some(comma_tok) = self

View file

@ -293,7 +293,7 @@ fn extend_with_struct_pat(
qself1: &Option<P<ast::QSelf>>, qself1: &Option<P<ast::QSelf>>,
path1: &ast::Path, path1: &ast::Path,
fps1: &mut [ast::PatField], fps1: &mut [ast::PatField],
rest1: bool, rest1: ast::PatFieldsRest,
start: usize, start: usize,
alternatives: &mut ThinVec<P<Pat>>, alternatives: &mut ThinVec<P<Pat>>,
) -> bool { ) -> bool {

View file

@ -259,9 +259,15 @@ impl Rewrite for Pat {
None, None,
None, None,
), ),
PatKind::Struct(ref qself, ref path, ref fields, ellipsis) => { PatKind::Struct(ref qself, ref path, ref fields, rest) => rewrite_struct_pat(
rewrite_struct_pat(qself, path, fields, ellipsis, self.span, context, shape) qself,
} path,
fields,
rest == ast::PatFieldsRest::Rest,
self.span,
context,
shape,
),
PatKind::MacCall(ref mac) => { PatKind::MacCall(ref mac) => {
rewrite_macro(mac, None, context, shape, MacroPosition::Pat) rewrite_macro(mac, None, context, shape, MacroPosition::Pat)
} }