1
Fork 0

Rollup merge of #119145 - aDotInTheVoid:variantdata-struct-struct, r=compiler-errors

Give `VariantData::Struct`  named fields, to clairfy `recovered`.

Implements https://github.com/rust-lang/rust/pull/119121#discussion_r1431467066. Supersedes #119121

This way, it's clear what the bool fields means, instead of having to find where it's generated. Changes both ast and hir.

r? `@compiler-errors`
This commit is contained in:
Matthias Krüger 2023-12-20 21:18:59 +01:00 committed by GitHub
commit d0d814ff48
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 51 additions and 40 deletions

View file

@ -2788,7 +2788,11 @@ pub enum VariantData {
/// Struct variant. /// Struct variant.
/// ///
/// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`. /// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
Struct(ThinVec<FieldDef>, bool), Struct {
fields: ThinVec<FieldDef>,
// FIXME: investigate making this a `Option<ErrorGuaranteed>`
recovered: bool,
},
/// Tuple variant. /// Tuple variant.
/// ///
/// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`. /// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`.
@ -2803,7 +2807,7 @@ impl VariantData {
/// Return the fields of this variant. /// Return the fields of this variant.
pub fn fields(&self) -> &[FieldDef] { pub fn fields(&self) -> &[FieldDef] {
match self { match self {
VariantData::Struct(fields, ..) | VariantData::Tuple(fields, _) => fields, VariantData::Struct { fields, .. } | VariantData::Tuple(fields, _) => fields,
_ => &[], _ => &[],
} }
} }
@ -2811,7 +2815,7 @@ impl VariantData {
/// Return the `NodeId` of this variant's constructor, if it has one. /// Return the `NodeId` of this variant's constructor, if it has one.
pub fn ctor_node_id(&self) -> Option<NodeId> { pub fn ctor_node_id(&self) -> Option<NodeId> {
match *self { match *self {
VariantData::Struct(..) => None, VariantData::Struct { .. } => None,
VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id), VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
} }
} }

View file

@ -976,7 +976,7 @@ pub fn noop_visit_where_predicate<T: MutVisitor>(pred: &mut WherePredicate, vis:
pub fn noop_visit_variant_data<T: MutVisitor>(vdata: &mut VariantData, vis: &mut T) { pub fn noop_visit_variant_data<T: MutVisitor>(vdata: &mut VariantData, vis: &mut T) {
match vdata { match vdata {
VariantData::Struct(fields, ..) => { VariantData::Struct { fields, .. } => {
fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); fields.flat_map_in_place(|field| vis.flat_map_field_def(field));
} }
VariantData::Tuple(fields, id) => { VariantData::Tuple(fields, id) => {

View file

@ -661,11 +661,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
vdata: &VariantData, vdata: &VariantData,
) -> hir::VariantData<'hir> { ) -> hir::VariantData<'hir> {
match vdata { match vdata {
VariantData::Struct(fields, recovered) => hir::VariantData::Struct( VariantData::Struct { fields, recovered } => hir::VariantData::Struct {
self.arena fields: self
.arena
.alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f))), .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f))),
*recovered, recovered: *recovered,
), },
VariantData::Tuple(fields, id) => { VariantData::Tuple(fields, id) => {
let ctor_id = self.lower_node_id(*id); let ctor_id = self.lower_node_id(*id);
self.alias_attrs(ctor_id, parent_id); self.alias_attrs(ctor_id, parent_id);

View file

@ -1000,7 +1000,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
} }
} }
ItemKind::Struct(vdata, generics) => match vdata { ItemKind::Struct(vdata, generics) => match vdata {
VariantData::Struct(fields, ..) => { VariantData::Struct { fields, .. } => {
self.visit_vis(&item.vis); self.visit_vis(&item.vis);
self.visit_ident(item.ident); self.visit_ident(item.ident);
self.visit_generics(generics); self.visit_generics(generics);
@ -1016,7 +1016,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.dcx().emit_err(errors::FieldlessUnion { span: item.span }); self.dcx().emit_err(errors::FieldlessUnion { span: item.span });
} }
match vdata { match vdata {
VariantData::Struct(fields, ..) => { VariantData::Struct { fields, .. } => {
self.visit_vis(&item.vis); self.visit_vis(&item.vis);
self.visit_ident(item.ident); self.visit_ident(item.ident);
self.visit_generics(generics); self.visit_generics(generics);

View file

@ -500,7 +500,7 @@ impl<'a> State<'a> {
self.end(); self.end();
self.end(); // Close the outer-box. self.end(); // Close the outer-box.
} }
ast::VariantData::Struct(fields, ..) => { ast::VariantData::Struct { fields, .. } => {
self.print_where_clause(&generics.where_clause); self.print_where_clause(&generics.where_clause);
self.print_record_struct_body(fields, span); self.print_record_struct_body(fields, span);
} }

View file

@ -188,7 +188,7 @@ fn cs_clone(
} }
let expr = match *vdata { let expr = match *vdata {
VariantData::Struct(..) => { VariantData::Struct { .. } => {
let fields = all_fields let fields = all_fields
.iter() .iter()
.map(|field| { .map(|field| {

View file

@ -71,7 +71,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
(false, 0) (false, 0)
} }
ast::VariantData::Tuple(..) => (false, 1), ast::VariantData::Tuple(..) => (false, 1),
ast::VariantData::Struct(..) => (true, 2), ast::VariantData::Struct { .. } => (true, 2),
}; };
// The number of fields that can be handled without an array. // The number of fields that can be handled without an array.
@ -226,7 +226,7 @@ fn show_fieldless_enum(
debug_assert!(fields.is_empty()); debug_assert!(fields.is_empty());
cx.pat_tuple_struct(span, variant_path, ThinVec::new()) cx.pat_tuple_struct(span, variant_path, ThinVec::new())
} }
ast::VariantData::Struct(fields, _) => { ast::VariantData::Struct { fields, .. } => {
debug_assert!(fields.is_empty()); debug_assert!(fields.is_empty());
cx.pat_struct(span, variant_path, ThinVec::new()) cx.pat_struct(span, variant_path, ThinVec::new())
} }

View file

@ -1485,7 +1485,7 @@ impl<'a> TraitDef<'a> {
let struct_path = struct_path.clone(); let struct_path = struct_path.clone();
match *struct_def { match *struct_def {
VariantData::Struct(..) => { VariantData::Struct { .. } => {
let field_pats = pieces_iter let field_pats = pieces_iter
.map(|(sp, ident, pat)| { .map(|(sp, ident, pat)| {
if ident.is_none() { if ident.is_none() {

View file

@ -174,7 +174,7 @@ pub fn placeholder(
}]), }]),
AstFragmentKind::Variants => AstFragment::Variants(smallvec![ast::Variant { AstFragmentKind::Variants => AstFragment::Variants(smallvec![ast::Variant {
attrs: Default::default(), attrs: Default::default(),
data: ast::VariantData::Struct(Default::default(), false), data: ast::VariantData::Struct { fields: Default::default(), recovered: false },
disr_expr: None, disr_expr: None,
id, id,
ident, ident,

View file

@ -603,7 +603,7 @@ impl CtorKind {
match *vdata { match *vdata {
ast::VariantData::Tuple(_, node_id) => Some((CtorKind::Fn, node_id)), ast::VariantData::Tuple(_, node_id) => Some((CtorKind::Fn, node_id)),
ast::VariantData::Unit(node_id) => Some((CtorKind::Const, node_id)), ast::VariantData::Unit(node_id) => Some((CtorKind::Const, node_id)),
ast::VariantData::Struct(..) => None, ast::VariantData::Struct { .. } => None,
} }
} }
} }

View file

@ -2848,7 +2848,11 @@ pub enum VariantData<'hir> {
/// A struct variant. /// A struct variant.
/// ///
/// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`. /// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
Struct(&'hir [FieldDef<'hir>], /* recovered */ bool), Struct {
fields: &'hir [FieldDef<'hir>],
// FIXME: investigate making this a `Option<ErrorGuaranteed>`
recovered: bool,
},
/// A tuple variant. /// A tuple variant.
/// ///
/// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`. /// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`.
@ -2863,7 +2867,7 @@ impl<'hir> VariantData<'hir> {
/// Return the fields of this variant. /// Return the fields of this variant.
pub fn fields(&self) -> &'hir [FieldDef<'hir>] { pub fn fields(&self) -> &'hir [FieldDef<'hir>] {
match *self { match *self {
VariantData::Struct(ref fields, ..) | VariantData::Tuple(ref fields, ..) => fields, VariantData::Struct { fields, .. } | VariantData::Tuple(fields, ..) => fields,
_ => &[], _ => &[],
} }
} }
@ -2872,7 +2876,7 @@ impl<'hir> VariantData<'hir> {
match *self { match *self {
VariantData::Tuple(_, hir_id, def_id) => Some((CtorKind::Fn, hir_id, def_id)), VariantData::Tuple(_, hir_id, def_id) => Some((CtorKind::Fn, hir_id, def_id)),
VariantData::Unit(hir_id, def_id) => Some((CtorKind::Const, hir_id, def_id)), VariantData::Unit(hir_id, def_id) => Some((CtorKind::Const, hir_id, def_id)),
VariantData::Struct(..) => None, VariantData::Struct { .. } => None,
} }
} }

View file

@ -814,7 +814,7 @@ fn convert_variant(
}) })
.collect(); .collect();
let recovered = match def { let recovered = match def {
hir::VariantData::Struct(_, r) => *r, hir::VariantData::Struct { recovered, .. } => *recovered,
_ => false, _ => false,
}; };
ty::VariantDef::new( ty::VariantDef::new(

View file

@ -481,7 +481,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
}, },
Node::Ctor(def) | Node::Variant(Variant { data: def, .. }) => match def { Node::Ctor(def) | Node::Variant(Variant { data: def, .. }) => match def {
VariantData::Unit(..) | VariantData::Struct(..) => { VariantData::Unit(..) | VariantData::Struct { .. } => {
tcx.type_of(tcx.hir().get_parent_item(hir_id)).instantiate_identity() tcx.type_of(tcx.hir().get_parent_item(hir_id)).instantiate_identity()
} }
VariantData::Tuple(..) => { VariantData::Tuple(..) => {

View file

@ -741,7 +741,7 @@ impl<'a> State<'a> {
self.end(); self.end();
self.end() // close the outer-box self.end() // close the outer-box
} }
hir::VariantData::Struct(..) => { hir::VariantData::Struct { .. } => {
self.print_where_clause(generics); self.print_where_clause(generics);
self.nbsp(); self.nbsp();
self.bopen(); self.bopen();

View file

@ -1484,7 +1484,7 @@ impl<'a> Parser<'a> {
(thin_vec![], true) (thin_vec![], true)
} }
}; };
VariantData::Struct(fields, recovered) VariantData::Struct { fields, recovered }
} else if this.check(&token::OpenDelim(Delimiter::Parenthesis)) { } else if this.check(&token::OpenDelim(Delimiter::Parenthesis)) {
let body = match this.parse_tuple_struct_body() { let body = match this.parse_tuple_struct_body() {
Ok(body) => body, Ok(body) => body,
@ -1569,7 +1569,7 @@ impl<'a> Parser<'a> {
class_name.span, class_name.span,
generics.where_clause.has_where_token, generics.where_clause.has_where_token,
)?; )?;
VariantData::Struct(fields, recovered) VariantData::Struct { fields, recovered }
} }
// No `where` so: `struct Foo<T>;` // No `where` so: `struct Foo<T>;`
} else if self.eat(&token::Semi) { } else if self.eat(&token::Semi) {
@ -1581,7 +1581,7 @@ impl<'a> Parser<'a> {
class_name.span, class_name.span,
generics.where_clause.has_where_token, generics.where_clause.has_where_token,
)?; )?;
VariantData::Struct(fields, recovered) VariantData::Struct { fields, recovered }
// Tuple-style struct definition with optional where-clause. // Tuple-style struct definition with optional where-clause.
} else if self.token == token::OpenDelim(Delimiter::Parenthesis) { } else if self.token == token::OpenDelim(Delimiter::Parenthesis) {
let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID); let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID);
@ -1610,14 +1610,14 @@ impl<'a> Parser<'a> {
class_name.span, class_name.span,
generics.where_clause.has_where_token, generics.where_clause.has_where_token,
)?; )?;
VariantData::Struct(fields, recovered) VariantData::Struct { fields, recovered }
} else if self.token == token::OpenDelim(Delimiter::Brace) { } else if self.token == token::OpenDelim(Delimiter::Brace) {
let (fields, recovered) = self.parse_record_struct_body( let (fields, recovered) = self.parse_record_struct_body(
"union", "union",
class_name.span, class_name.span,
generics.where_clause.has_where_token, generics.where_clause.has_where_token,
)?; )?;
VariantData::Struct(fields, recovered) VariantData::Struct { fields, recovered }
} else { } else {
let token_str = super::token_descr(&self.token); let token_str = super::token_descr(&self.token);
let msg = format!("expected `where` or `{{` after union name, found {token_str}"); let msg = format!("expected `where` or `{{` after union name, found {token_str}");

View file

@ -2479,8 +2479,8 @@ fn clean_variant_data<'tcx>(
.map(|disr| Discriminant { expr: Some(disr.body), value: disr.def_id.to_def_id() }); .map(|disr| Discriminant { expr: Some(disr.body), value: disr.def_id.to_def_id() });
let kind = match variant { let kind = match variant {
hir::VariantData::Struct(..) => VariantKind::Struct(VariantStruct { hir::VariantData::Struct { fields, .. } => VariantKind::Struct(VariantStruct {
fields: variant.fields().iter().map(|x| clean_field(x, cx)).collect(), fields: fields.iter().map(|x| clean_field(x, cx)).collect(),
}), }),
hir::VariantData::Tuple(..) => { hir::VariantData::Tuple(..) => {
VariantKind::Tuple(variant.fields().iter().map(|x| clean_field(x, cx)).collect()) VariantKind::Tuple(variant.fields().iter().map(|x| clean_field(x, cx)).collect())

View file

@ -436,7 +436,7 @@ impl LateLintPass<'_> for ItemNameRepetitions {
{ {
match item.kind { match item.kind {
ItemKind::Enum(def, _) => check_variant(cx, self.enum_threshold, &def, item_name, item.span), ItemKind::Enum(def, _) => check_variant(cx, self.enum_threshold, &def, item_name, item.span),
ItemKind::Struct(VariantData::Struct(fields, _), _) => { ItemKind::Struct(VariantData::Struct { fields, .. }, _) => {
check_fields(cx, self.struct_threshold, item, fields); check_fields(cx, self.struct_threshold, item, fields);
}, },
_ => (), _ => (),

View file

@ -103,7 +103,7 @@ impl EarlyLintPass for ManualNonExhaustiveStruct {
if let ast::ItemKind::Struct(variant_data, _) = &item.kind { if let ast::ItemKind::Struct(variant_data, _) = &item.kind {
let (fields, delimiter) = match variant_data { let (fields, delimiter) = match variant_data {
ast::VariantData::Struct(fields, _) => (&**fields, '{'), ast::VariantData::Struct { fields, .. } => (&**fields, '{'),
ast::VariantData::Tuple(fields, _) => (&**fields, '('), ast::VariantData::Tuple(fields, _) => (&**fields, '('),
ast::VariantData::Unit(_) => return, ast::VariantData::Unit(_) => return,
}; };

View file

@ -546,7 +546,9 @@ pub fn eq_variant_data(l: &VariantData, r: &VariantData) -> bool {
use VariantData::*; use VariantData::*;
match (l, r) { match (l, r) {
(Unit(_), Unit(_)) => true, (Unit(_), Unit(_)) => true,
(Struct(l, _), Struct(r, _)) | (Tuple(l, _), Tuple(r, _)) => over(l, r, eq_struct_field), (Struct { fields: l, .. }, Struct { fields: r, .. }) | (Tuple(l, _), Tuple(r, _)) => {
over(l, r, eq_struct_field)
},
_ => false, _ => false,
} }
} }

View file

@ -200,7 +200,7 @@ fn item_search_pat(item: &Item<'_>) -> (Pat, Pat) {
ItemKind::ForeignMod { .. } => (Pat::Str("extern"), Pat::Str("}")), ItemKind::ForeignMod { .. } => (Pat::Str("extern"), Pat::Str("}")),
ItemKind::TyAlias(..) | ItemKind::OpaqueTy(_) => (Pat::Str("type"), Pat::Str(";")), ItemKind::TyAlias(..) | ItemKind::OpaqueTy(_) => (Pat::Str("type"), Pat::Str(";")),
ItemKind::Enum(..) => (Pat::Str("enum"), Pat::Str("}")), ItemKind::Enum(..) => (Pat::Str("enum"), Pat::Str("}")),
ItemKind::Struct(VariantData::Struct(..), _) => (Pat::Str("struct"), Pat::Str("}")), ItemKind::Struct(VariantData::Struct { .. }, _) => (Pat::Str("struct"), Pat::Str("}")),
ItemKind::Struct(..) => (Pat::Str("struct"), Pat::Str(";")), ItemKind::Struct(..) => (Pat::Str("struct"), Pat::Str(";")),
ItemKind::Union(..) => (Pat::Str("union"), Pat::Str("}")), ItemKind::Union(..) => (Pat::Str("union"), Pat::Str("}")),
ItemKind::Trait(_, Unsafety::Unsafe, ..) ItemKind::Trait(_, Unsafety::Unsafe, ..)
@ -255,7 +255,7 @@ fn field_def_search_pat(def: &FieldDef<'_>) -> (Pat, Pat) {
fn variant_search_pat(v: &Variant<'_>) -> (Pat, Pat) { fn variant_search_pat(v: &Variant<'_>) -> (Pat, Pat) {
match v.data { match v.data {
VariantData::Struct(..) => (Pat::Sym(v.ident.name), Pat::Str("}")), VariantData::Struct { .. } => (Pat::Sym(v.ident.name), Pat::Str("}")),
VariantData::Tuple(..) => (Pat::Sym(v.ident.name), Pat::Str("")), VariantData::Tuple(..) => (Pat::Sym(v.ident.name), Pat::Str("")),
VariantData::Unit(..) => (Pat::Sym(v.ident.name), Pat::Sym(v.ident.name)), VariantData::Unit(..) => (Pat::Sym(v.ident.name), Pat::Sym(v.ident.name)),
} }

View file

@ -666,7 +666,7 @@ impl<'a> FmtVisitor<'a> {
let span = mk_sp(lo, field.span.lo()); let span = mk_sp(lo, field.span.lo());
let variant_body = match field.data { let variant_body = match field.data {
ast::VariantData::Tuple(..) | ast::VariantData::Struct(..) => format_struct( ast::VariantData::Tuple(..) | ast::VariantData::Struct { .. } => format_struct(
&context, &context,
&StructParts::from_variant(field, &context), &StructParts::from_variant(field, &context),
self.block_indent, self.block_indent,
@ -1092,7 +1092,7 @@ fn enum_variant_span(variant: &ast::Variant, context: &RewriteContext<'_>) -> Sp
if let Some(ref anon_const) = variant.disr_expr { if let Some(ref anon_const) = variant.disr_expr {
let span_before_consts = variant.span.until(anon_const.value.span); let span_before_consts = variant.span.until(anon_const.value.span);
let hi = match &variant.data { let hi = match &variant.data {
Struct(..) => context Struct { .. } => context
.snippet_provider .snippet_provider
.span_after_last(span_before_consts, "}"), .span_after_last(span_before_consts, "}"),
Tuple(..) => context Tuple(..) => context
@ -1112,12 +1112,12 @@ fn format_struct(
offset: Indent, offset: Indent,
one_line_width: Option<usize>, one_line_width: Option<usize>,
) -> Option<String> { ) -> Option<String> {
match *struct_parts.def { match struct_parts.def {
ast::VariantData::Unit(..) => format_unit_struct(context, struct_parts, offset), ast::VariantData::Unit(..) => format_unit_struct(context, struct_parts, offset),
ast::VariantData::Tuple(ref fields, _) => { ast::VariantData::Tuple(fields, _) => {
format_tuple_struct(context, struct_parts, fields, offset) format_tuple_struct(context, struct_parts, fields, offset)
} }
ast::VariantData::Struct(ref fields, _) => { ast::VariantData::Struct { fields, .. } => {
format_struct_struct(context, struct_parts, fields, offset, one_line_width) format_struct_struct(context, struct_parts, fields, offset, one_line_width)
} }
} }