diff options
Diffstat (limited to 'compiler/rustc_ast_lowering/src/lib.rs')
| -rw-r--r-- | compiler/rustc_ast_lowering/src/lib.rs | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 5f7439060b3..480072ce705 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1288,17 +1288,44 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { TyKind::Err => { hir::TyKind::Err(self.dcx().span_delayed_bug(t.span, "TyKind::Err lowered")) } - // FIXME(unnamed_fields): IMPLEMENTATION IN PROGRESS - #[allow(rustc::untranslatable_diagnostic)] - #[allow(rustc::diagnostic_outside_of_impl)] - TyKind::AnonStruct(ref _fields) => { - hir::TyKind::Err(self.dcx().span_err(t.span, "anonymous structs are unimplemented")) - } - // FIXME(unnamed_fields): IMPLEMENTATION IN PROGRESS - #[allow(rustc::untranslatable_diagnostic)] - #[allow(rustc::diagnostic_outside_of_impl)] - TyKind::AnonUnion(ref _fields) => { - hir::TyKind::Err(self.dcx().span_err(t.span, "anonymous unions are unimplemented")) + // 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: false }; + // 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)), |
