about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir/src/hir.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs10
-rw-r--r--tests/ui/union/unnamed-fields/anon-struct-in-enum-issue-121446.rs11
-rw-r--r--tests/ui/union/unnamed-fields/anon-struct-in-enum-issue-121446.stderr16
4 files changed, 41 insertions, 1 deletions
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index fcb15925f6a..78e7c636a3e 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3004,6 +3004,11 @@ impl<'hir> Item<'hir> {
         matches!(self.kind, ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..))
     }
 
+    /// Check if this is an [`ItemKind::Struct`] or [`ItemKind::Union`].
+    pub fn is_struct_or_union(&self) -> bool {
+        matches!(self.kind, ItemKind::Struct(..) | ItemKind::Union(..))
+    }
+
     expect_methods_self_kind! {
         expect_extern_crate, Option<Symbol>, ItemKind::ExternCrate(s), *s;
 
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 642009dfa48..e9c9ec6ba53 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -1025,7 +1025,15 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
 
     let is_anonymous = item.ident.name == kw::Empty;
     let repr = if is_anonymous {
-        tcx.adt_def(tcx.local_parent(def_id)).repr()
+        let parent = tcx.local_parent(def_id);
+        if let Node::Item(item) = tcx.hir_node_by_def_id(parent)
+            && item.is_struct_or_union()
+        {
+            tcx.adt_def(parent).repr()
+        } else {
+            tcx.dcx().span_delayed_bug(item.span, "anonymous field inside non struct/union");
+            ty::ReprOptions::default()
+        }
     } else {
         tcx.repr_options_of_def(def_id)
     };
diff --git a/tests/ui/union/unnamed-fields/anon-struct-in-enum-issue-121446.rs b/tests/ui/union/unnamed-fields/anon-struct-in-enum-issue-121446.rs
new file mode 100644
index 00000000000..00f9bfd5cdf
--- /dev/null
+++ b/tests/ui/union/unnamed-fields/anon-struct-in-enum-issue-121446.rs
@@ -0,0 +1,11 @@
+#![crate_type = "lib"]
+#![feature(unnamed_fields)]
+#![allow(unused, incomplete_features)]
+
+enum K {
+    M {
+        _ : struct { field: u8 },
+        //~^ error: unnamed fields are not allowed outside of structs or unions
+        //~| error: anonymous structs are not allowed outside of unnamed struct or union fields
+    }
+}
diff --git a/tests/ui/union/unnamed-fields/anon-struct-in-enum-issue-121446.stderr b/tests/ui/union/unnamed-fields/anon-struct-in-enum-issue-121446.stderr
new file mode 100644
index 00000000000..43843141e2e
--- /dev/null
+++ b/tests/ui/union/unnamed-fields/anon-struct-in-enum-issue-121446.stderr
@@ -0,0 +1,16 @@
+error: unnamed fields are not allowed outside of structs or unions
+  --> $DIR/anon-struct-in-enum-issue-121446.rs:7:9
+   |
+LL |         _ : struct { field: u8 },
+   |         -^^^^^^^^^^^^^^^^^^^^^^^
+   |         |
+   |         unnamed field declared here
+
+error: anonymous structs are not allowed outside of unnamed struct or union fields
+  --> $DIR/anon-struct-in-enum-issue-121446.rs:7:13
+   |
+LL |         _ : struct { field: u8 },
+   |             ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
+
+error: aborting due to 2 previous errors
+