Skip to content

Commit 4d5c4e5

Browse files
authoredFeb 23, 2024
Rollup merge of #121470 - clubby789:anon-struct-in-enum, r=fmease
Don't ICE on anonymous struct in enum variant Fixes #121446 Computing `adt_def` for the anon struct calls `adt_def` on the parent to find its repr. If the parent is a non-item (e.g. an enum variant) we should have already emitted at least one error, so we just use the repr of the anonymous struct to avoid an ICE. cc ``@frank-king``
2 parents 26cb6c7 + 35a9e73 commit 4d5c4e5

File tree

4 files changed

+41
-1
lines changed

4 files changed

+41
-1
lines changed
 

Diff for: ‎compiler/rustc_hir/src/hir.rs

+5
Original file line numberDiff line numberDiff line change
@@ -3004,6 +3004,11 @@ impl<'hir> Item<'hir> {
30043004
matches!(self.kind, ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..))
30053005
}
30063006

3007+
/// Check if this is an [`ItemKind::Struct`] or [`ItemKind::Union`].
3008+
pub fn is_struct_or_union(&self) -> bool {
3009+
matches!(self.kind, ItemKind::Struct(..) | ItemKind::Union(..))
3010+
}
3011+
30073012
expect_methods_self_kind! {
30083013
expect_extern_crate, Option<Symbol>, ItemKind::ExternCrate(s), *s;
30093014

Diff for: ‎compiler/rustc_hir_analysis/src/collect.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1025,7 +1025,15 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
10251025

10261026
let is_anonymous = item.ident.name == kw::Empty;
10271027
let repr = if is_anonymous {
1028-
tcx.adt_def(tcx.local_parent(def_id)).repr()
1028+
let parent = tcx.local_parent(def_id);
1029+
if let Node::Item(item) = tcx.hir_node_by_def_id(parent)
1030+
&& item.is_struct_or_union()
1031+
{
1032+
tcx.adt_def(parent).repr()
1033+
} else {
1034+
tcx.dcx().span_delayed_bug(item.span, "anonymous field inside non struct/union");
1035+
ty::ReprOptions::default()
1036+
}
10291037
} else {
10301038
tcx.repr_options_of_def(def_id)
10311039
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![crate_type = "lib"]
2+
#![feature(unnamed_fields)]
3+
#![allow(unused, incomplete_features)]
4+
5+
enum K {
6+
M {
7+
_ : struct { field: u8 },
8+
//~^ error: unnamed fields are not allowed outside of structs or unions
9+
//~| error: anonymous structs are not allowed outside of unnamed struct or union fields
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error: unnamed fields are not allowed outside of structs or unions
2+
--> $DIR/anon-struct-in-enum-issue-121446.rs:7:9
3+
|
4+
LL | _ : struct { field: u8 },
5+
| -^^^^^^^^^^^^^^^^^^^^^^^
6+
| |
7+
| unnamed field declared here
8+
9+
error: anonymous structs are not allowed outside of unnamed struct or union fields
10+
--> $DIR/anon-struct-in-enum-issue-121446.rs:7:13
11+
|
12+
LL | _ : struct { field: u8 },
13+
| ^^^^^^^^^^^^^^^^^^^^ anonymous struct declared here
14+
15+
error: aborting due to 2 previous errors
16+

0 commit comments

Comments
 (0)
Please sign in to comment.