about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-09-29 22:17:30 -0400
committerMichael Goulet <michael@errs.io>2024-10-01 13:55:46 -0400
commit40465d2449f3d9a36c86b94885f58ed3ee2a99f0 (patch)
treea98bcd2bbf0fe57748eba20e2c90eaf96c4471d8
parente3a0da18633a8cfb5263bb975747352690b01fcf (diff)
downloadrust-40465d2449f3d9a36c86b94885f58ed3ee2a99f0.tar.gz
rust-40465d2449f3d9a36c86b94885f58ed3ee2a99f0.zip
Remove anon struct and union types
-rw-r--r--compiler/rustc_ast/src/ast.rs8
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs4
-rw-r--r--compiler/rustc_ast/src/util/classify.rs6
-rw-r--r--compiler/rustc_ast/src/visit.rs3
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs40
-rw-r--r--compiler/rustc_ast_passes/messages.ftl4
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs17
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs9
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs8
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/clone.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/mod.rs2
-rw-r--r--compiler/rustc_feature/src/removed.rs2
-rw-r--r--compiler/rustc_parse/src/parser/item.rs2
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs47
-rw-r--r--compiler/rustc_passes/src/hir_stats.rs2
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs23
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs18
-rw-r--r--src/tools/rustfmt/src/types.rs2
-rw-r--r--src/tools/rustfmt/tests/target/anonymous-types.rs31
19 files changed, 3 insertions, 227 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 37f429cce44..4a92cc881fa 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2167,10 +2167,6 @@ pub enum TyKind {
     Never,
     /// A tuple (`(A, B, C, D,...)`).
     Tup(ThinVec<P<Ty>>),
-    /// An anonymous struct type i.e. `struct { foo: Type }`.
-    AnonStruct(NodeId, ThinVec<FieldDef>),
-    /// An anonymous union type i.e. `union { bar: Type }`.
-    AnonUnion(NodeId, ThinVec<FieldDef>),
     /// A path (`module::module::...::Type`), optionally
     /// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`.
     ///
@@ -2227,10 +2223,6 @@ impl TyKind {
             None
         }
     }
-
-    pub fn is_anon_adt(&self) -> bool {
-        matches!(self, TyKind::AnonStruct(..) | TyKind::AnonUnion(..))
-    }
 }
 
 /// Syntax used to declare a trait object.
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 104f84f26e0..a59eed4125c 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -519,10 +519,6 @@ pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) {
             visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Impl));
         }
         TyKind::MacCall(mac) => vis.visit_mac_call(mac),
-        TyKind::AnonStruct(id, fields) | TyKind::AnonUnion(id, fields) => {
-            vis.visit_id(id);
-            fields.flat_map_in_place(|field| vis.flat_map_field_def(field));
-        }
     }
     visit_lazy_tts(vis, tokens);
     vis.visit_span(span);
diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs
index 1a80a9ccdbf..a517f17c82c 100644
--- a/compiler/rustc_ast/src/util/classify.rs
+++ b/compiler/rustc_ast/src/util/classify.rs
@@ -287,12 +287,6 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> {
             | ast::TyKind::Pat(..)
             | ast::TyKind::Dummy
             | ast::TyKind::Err(..) => break None,
-
-            // These end in brace, but cannot occur in a let-else statement.
-            // They are only parsed as fields of a data structure. For the
-            // purpose of denying trailing braces in the expression of a
-            // let-else, we can disregard these.
-            ast::TyKind::AnonStruct(..) | ast::TyKind::AnonUnion(..) => break None,
         }
     }
 }
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 9f9c3d8c392..4dcadb8517e 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -535,9 +535,6 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
         TyKind::Err(_guar) => {}
         TyKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
         TyKind::Never | TyKind::CVarArgs => {}
-        TyKind::AnonStruct(_id, ref fields) | TyKind::AnonUnion(_id, ref fields) => {
-            walk_list!(visitor, visit_field_def, fields);
-        }
     }
     V::Result::output()
 }
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index c6cb7aa7dd5..e38374281f7 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1264,46 +1264,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         let kind = match &t.kind {
             TyKind::Infer => hir::TyKind::Infer,
             TyKind::Err(guar) => hir::TyKind::Err(*guar),
-            // Lower the anonymous structs or unions in a nested lowering context.
-            //
-            // ```
-            // struct Foo {
-            //     _: union {
-            // //     ^__________________  <-- within the nested lowering context,
-            //         /* fields */ //   |     we lower all fields defined into an
-            //     } //                  |     owner node of struct or union item
-            // //  ^_____________________|
-            // }
-            // ```
-            TyKind::AnonStruct(node_id, fields) | TyKind::AnonUnion(node_id, fields) => {
-                // Here its `def_id` is created in `build_reduced_graph`.
-                let def_id = self.local_def_id(*node_id);
-                debug!(?def_id);
-                let owner_id = hir::OwnerId { def_id };
-                self.with_hir_id_owner(*node_id, |this| {
-                    let fields = this.arena.alloc_from_iter(
-                        fields.iter().enumerate().map(|f| this.lower_field_def(f)),
-                    );
-                    let span = t.span;
-                    let variant_data =
-                        hir::VariantData::Struct { fields, recovered: ast::Recovered::No };
-                    // FIXME: capture the generics from the outer adt.
-                    let generics = hir::Generics::empty();
-                    let kind = match t.kind {
-                        TyKind::AnonStruct(..) => hir::ItemKind::Struct(variant_data, generics),
-                        TyKind::AnonUnion(..) => hir::ItemKind::Union(variant_data, generics),
-                        _ => unreachable!(),
-                    };
-                    hir::OwnerNode::Item(this.arena.alloc(hir::Item {
-                        ident: Ident::new(kw::Empty, span),
-                        owner_id,
-                        kind,
-                        span: this.lower_span(span),
-                        vis_span: this.lower_span(span.shrink_to_lo()),
-                    }))
-                });
-                hir::TyKind::AnonAdt(hir::ItemId { owner_id })
-            }
             TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
             TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
             TyKind::Ref(region, mt) => {
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl
index 0146a8d9082..7cfbd6c6c6c 100644
--- a/compiler/rustc_ast_passes/messages.ftl
+++ b/compiler/rustc_ast_passes/messages.ftl
@@ -1,7 +1,3 @@
-ast_passes_anon_struct_or_union_not_allowed =
-    anonymous {$struct_or_union}s are not allowed outside of unnamed struct or union fields
-    .label = anonymous {$struct_or_union} declared here
-
 ast_passes_assoc_const_without_body =
     associated constant in `impl` without body
     .suggestion = provide a definition for the constant
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index b3d91d881c4..f99654a9a65 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -244,9 +244,6 @@ impl<'a> AstValidator<'a> {
                     }
                 }
             }
-            TyKind::AnonStruct(_, ref fields) | TyKind::AnonUnion(_, ref fields) => {
-                walk_list!(self, visit_struct_field_def, fields)
-            }
             _ => visit::walk_ty(self, t),
         }
     }
@@ -293,15 +290,6 @@ impl<'a> AstValidator<'a> {
         }
     }
 
-    fn deny_anon_struct_or_union(&self, ty: &Ty) {
-        let struct_or_union = match &ty.kind {
-            TyKind::AnonStruct(..) => "struct",
-            TyKind::AnonUnion(..) => "union",
-            _ => return,
-        };
-        self.dcx().emit_err(errors::AnonStructOrUnionNotAllowed { struct_or_union, span: ty.span });
-    }
-
     fn check_trait_fn_not_const(&self, constness: Const, parent: &TraitOrTraitImpl) {
         let Const::Yes(span) = constness else {
             return;
@@ -865,14 +853,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
 
     fn visit_ty(&mut self, ty: &'a Ty) {
         self.visit_ty_common(ty);
-        self.deny_anon_struct_or_union(ty);
         self.walk_ty(ty)
     }
 
-    fn visit_field_def(&mut self, field: &'a FieldDef) {
-        visit::walk_field_def(self, field)
-    }
-
     fn visit_item(&mut self, item: &'a Item) {
         if item.attrs.iter().any(|attr| attr.is_proc_macro_attr()) {
             self.has_proc_macro_decls = true;
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 07515897c69..c60925b3049 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -815,15 +815,6 @@ pub(crate) struct NegativeBoundWithParentheticalNotation {
 }
 
 #[derive(Diagnostic)]
-#[diag(ast_passes_anon_struct_or_union_not_allowed)]
-pub(crate) struct AnonStructOrUnionNotAllowed {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-    pub struct_or_union: &'static str,
-}
-
-#[derive(Diagnostic)]
 #[diag(ast_passes_match_arm_with_no_body)]
 pub(crate) struct MatchArmWithNoBody {
     #[primary_span]
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 7e07ccf28a0..01713a9beca 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1174,14 +1174,6 @@ impl<'a> State<'a> {
                 }
                 self.pclose();
             }
-            ast::TyKind::AnonStruct(_, fields) => {
-                self.head("struct");
-                self.print_record_struct_body(fields, ty.span);
-            }
-            ast::TyKind::AnonUnion(_, fields) => {
-                self.head("union");
-                self.print_record_struct_body(fields, ty.span);
-            }
             ast::TyKind::Paren(typ) => {
                 self.popen();
                 self.print_type(typ);
diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs
index dde696fca61..f79227d52a8 100644
--- a/compiler/rustc_builtin_macros/src/deriving/clone.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs
@@ -113,7 +113,7 @@ fn cs_clone_simple(
                 // Already produced an assertion for this type.
                 // Anonymous structs or unions must be eliminated as they cannot be
                 // type parameters.
-            } else if !field.ty.kind.is_anon_adt() {
+            } else {
                 // let _: AssertParamIsClone<FieldTy>;
                 super::assert_ty_bounds(cx, &mut stmts, field.ty.clone(), field.span, &[
                     sym::clone,
diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs
index d5ee5e430d5..e884c0ec718 100644
--- a/compiler/rustc_builtin_macros/src/deriving/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs
@@ -124,8 +124,6 @@ fn assert_ty_bounds(
     span: Span,
     assert_path: &[Symbol],
 ) {
-    // Deny anonymous structs or unions to avoid weird errors.
-    assert!(!ty.kind.is_anon_adt(), "Anonymous structs or unions cannot be type parameters");
     // Generate statement `let _: assert_path<ty>;`.
     let span = cx.with_def_site_ctxt(span);
     let assert_path = cx.path_all(span, true, cx.std_path(assert_path), vec![GenericArg::Type(ty)]);
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index 276814dd0d9..85bc1460b3e 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -217,7 +217,7 @@ declare_features! (
     /// Allows using items which are missing stability attributes
     (removed, unmarked_api, "1.0.0", None, None),
     /// Allows unnamed fields of struct and union type
-    (removed, unnamed_fields, "1.74.0", Some(49804)),
+    (removed, unnamed_fields, "CURRENT_RUSTC_VERSION", Some(49804), Some("feature needs redesign")),
     (removed, unsafe_no_drop_flag, "1.0.0", None, None),
     /// Allows `union` fields that don't implement `Copy` as long as they don't have any drop glue.
     (removed, untagged_unions, "1.13.0", Some(55149),
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 13681c00f8e..36733726564 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1984,7 +1984,7 @@ impl<'a> Parser<'a> {
             }
         }
         self.expect_field_ty_separator()?;
-        let ty = self.parse_ty_for_field_def()?;
+        let ty = self.parse_ty()?;
         if self.token == token::Colon && self.look_ahead(1, |t| *t != token::Colon) {
             self.dcx().emit_err(errors::SingleColonStructType { span: self.token.span });
         }
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index a8ed8b5df9c..625a4cabdf2 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -128,17 +128,6 @@ impl<'a> Parser<'a> {
         )
     }
 
-    /// Parse a type suitable for a field definition.
-    /// The difference from `parse_ty` is that this version
-    /// allows anonymous structs and unions.
-    pub(super) fn parse_ty_for_field_def(&mut self) -> PResult<'a, P<Ty>> {
-        if self.can_begin_anon_struct_or_union() {
-            self.parse_anon_struct_or_union()
-        } else {
-            self.parse_ty()
-        }
-    }
-
     /// Parse a type suitable for a function or function pointer parameter.
     /// The difference from `parse_ty` is that this version allows `...`
     /// (`CVarArgs`) at the top level of the type.
@@ -382,37 +371,6 @@ impl<'a> Parser<'a> {
         if allow_qpath_recovery { self.maybe_recover_from_bad_qpath(ty) } else { Ok(ty) }
     }
 
-    /// Parse an anonymous struct or union (only for field definitions):
-    /// ```ignore (feature-not-ready)
-    /// #[repr(C)]
-    /// struct Foo {
-    ///     _: struct { // anonymous struct
-    ///         x: u32,
-    ///         y: f64,
-    ///     }
-    ///     _: union { // anonymous union
-    ///         z: u32,
-    ///         w: f64,
-    ///     }
-    /// }
-    /// ```
-    fn parse_anon_struct_or_union(&mut self) -> PResult<'a, P<Ty>> {
-        assert!(self.token.is_keyword(kw::Union) || self.token.is_keyword(kw::Struct));
-        let is_union = self.token.is_keyword(kw::Union);
-
-        let lo = self.token.span;
-        self.bump();
-
-        let (fields, _recovered) =
-            self.parse_record_struct_body(if is_union { "union" } else { "struct" }, lo, false)?;
-        let span = lo.to(self.prev_token.span);
-        self.psess.gated_spans.gate(sym::unnamed_fields, span);
-        let id = ast::DUMMY_NODE_ID;
-        let kind =
-            if is_union { TyKind::AnonUnion(id, fields) } else { TyKind::AnonStruct(id, fields) };
-        Ok(self.mk_ty(span, kind))
-    }
-
     /// Parses either:
     /// - `(TYPE)`, a parenthesized type.
     /// - `(TYPE,)`, a tuple with a single field of type TYPE.
@@ -813,11 +771,6 @@ impl<'a> Parser<'a> {
         Ok(bounds)
     }
 
-    pub(super) fn can_begin_anon_struct_or_union(&mut self) -> bool {
-        (self.token.is_keyword(kw::Struct) || self.token.is_keyword(kw::Union))
-            && self.look_ahead(1, |t| t == &token::OpenDelim(Delimiter::Brace))
-    }
-
     /// Can the current token begin a bound?
     fn can_begin_bound(&mut self) -> bool {
         self.check_path()
diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs
index 903fb114744..e89838b22ab 100644
--- a/compiler/rustc_passes/src/hir_stats.rs
+++ b/compiler/rustc_passes/src/hir_stats.rs
@@ -583,8 +583,6 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
             BareFn,
             Never,
             Tup,
-            AnonStruct,
-            AnonUnion,
             Path,
             Pat,
             TraitObject,
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index a9ea268e51a..ae7389342ec 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -724,29 +724,6 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
         // Record field names for error reporting.
         self.insert_field_idents(def_id, fields);
         self.insert_field_visibilities_local(def_id.to_def_id(), fields);
-
-        for field in fields {
-            match &field.ty.kind {
-                ast::TyKind::AnonStruct(id, nested_fields)
-                | ast::TyKind::AnonUnion(id, nested_fields) => {
-                    let feed = self.r.feed(*id);
-                    let local_def_id = feed.key();
-                    let def_id = local_def_id.to_def_id();
-                    let def_kind = self.r.tcx.def_kind(local_def_id);
-                    let res = Res::Def(def_kind, def_id);
-                    self.build_reduced_graph_for_struct_variant(
-                        &nested_fields,
-                        Ident::empty(),
-                        feed,
-                        res,
-                        // Anonymous adts inherit visibility from their parent adts.
-                        adt_vis,
-                        field.ty.span,
-                    );
-                }
-                _ => {}
-            }
-        }
     }
 
     /// Constructs the reduced graph for one item.
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index 98662385434..0047f2c4b51 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -105,22 +105,6 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
             let name = field.ident.map_or_else(|| sym::integer(index(self)), |ident| ident.name);
             let def = self.create_def(field.id, name, DefKind::Field, field.span);
             self.with_parent(def, |this| visit::walk_field_def(this, field));
-            self.visit_anon_adt(&field.ty);
-        }
-    }
-
-    fn visit_anon_adt(&mut self, ty: &'a Ty) {
-        let def_kind = match &ty.kind {
-            TyKind::AnonStruct(..) => DefKind::Struct,
-            TyKind::AnonUnion(..) => DefKind::Union,
-            _ => return,
-        };
-        match &ty.kind {
-            TyKind::AnonStruct(node_id, _) | TyKind::AnonUnion(node_id, _) => {
-                let def_id = self.create_def(*node_id, kw::Empty, def_kind, ty.span);
-                self.with_parent(def_id, |this| visit::walk_ty(this, ty));
-            }
-            _ => {}
         }
     }
 
@@ -476,8 +460,6 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
     fn visit_ty(&mut self, ty: &'a Ty) {
         match &ty.kind {
             TyKind::MacCall(..) => self.visit_macro_invoc(ty.id),
-            // Anonymous structs or unions are visited later after defined.
-            TyKind::AnonStruct(..) | TyKind::AnonUnion(..) => {}
             TyKind::ImplTrait(id, _) => {
                 // HACK: pprust breaks strings with newlines when the type
                 // gets too long. We don't want these to show up in compiler
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index 07b483b2b37..f75c4f0fad7 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -951,8 +951,6 @@ impl Rewrite for ast::Ty {
             ast::TyKind::Tup(ref items) => {
                 rewrite_tuple(context, items.iter(), self.span, shape, items.len() == 1)
             }
-            ast::TyKind::AnonStruct(..) => Ok(context.snippet(self.span).to_owned()),
-            ast::TyKind::AnonUnion(..) => Ok(context.snippet(self.span).to_owned()),
             ast::TyKind::Path(ref q_self, ref path) => {
                 rewrite_path(context, PathContext::Type, q_self, path, shape)
             }
diff --git a/src/tools/rustfmt/tests/target/anonymous-types.rs b/src/tools/rustfmt/tests/target/anonymous-types.rs
deleted file mode 100644
index e8c2d83878c..00000000000
--- a/src/tools/rustfmt/tests/target/anonymous-types.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Test for issue 85480
-// Pretty print anonymous struct and union types
-
-// pp-exact
-// pretty-compare-only
-
-struct Foo {
-    _: union  {
-        _: struct  {
-            a: u8,
-            b: u16,
-        },
-        c: u32,
-    },
-    d: u64,
-    e: f32,
-}
-
-// Test for https://github.com/rust-lang/rust/issues/117942
-struct Foo {
-    _: union  {
-        #[rustfmt::skip]
-    f: String,
-    },
-    #[rustfmt::skip]
-    _: struct {
-    g: i32,
-    },
-}
-
-fn main() {}