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 cee794ee98/compiler/rustc_parse/src/parser/pat.rs (L890-L897)
for the only place this is constructed.
r? ``@compiler-errors``
This commit is contained in:
commit
bdc4480914
@ -754,8 +754,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>>),
|
||||
@ -812,6 +811,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)]
|
||||
|
@ -82,7 +82,7 @@ fn lower_pat_mut(&mut self, mut pattern: &Pat) -> hir::Pat<'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");
|
||||
|
@ -1427,7 +1427,7 @@ fn print_pat(&mut self, pat: &ast::Pat) {
|
||||
}
|
||||
self.nbsp();
|
||||
self.word("{");
|
||||
let empty = fields.is_empty() && !etc;
|
||||
let empty = fields.is_empty() && *etc == ast::PatFieldsRest::None;
|
||||
if !empty {
|
||||
self.space();
|
||||
}
|
||||
@ -1445,7 +1445,7 @@ fn print_pat(&mut self, pat: &ast::Pat) {
|
||||
},
|
||||
|f| f.pat.span,
|
||||
);
|
||||
if *etc {
|
||||
if *etc == ast::PatFieldsRest::Rest {
|
||||
if !fields.is_empty() {
|
||||
self.word_space(",");
|
||||
}
|
||||
|
@ -491,7 +491,7 @@ pub fn pat_struct(
|
||||
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))
|
||||
|
@ -15,7 +15,7 @@
|
||||
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, PResult};
|
||||
@ -891,7 +891,8 @@ fn parse_pat_struct(&mut self, qself: Option<P<QSelf>>, path: Path) -> PResult<'
|
||||
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))
|
||||
@ -965,9 +966,9 @@ fn parse_pat_box(&mut self) -> PResult<'a, PatKind> {
|
||||
}
|
||||
|
||||
/// 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>> = None;
|
||||
let mut first_etc_and_maybe_comma_span = None;
|
||||
@ -1001,7 +1002,7 @@ fn parse_pat_fields(&mut self) -> PResult<'a, (ThinVec<PatField>, bool)> {
|
||||
|| 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
|
||||
|
@ -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 {
|
||||
|
@ -259,9 +259,15 @@ fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>
|
||||
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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user