Skip to content

Commit

Permalink
Rollup merge of #121470 - clubby789:anon-struct-in-enum, r=fmease
Browse files Browse the repository at this point in the history
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``
  • Loading branch information
matthiaskrgr authored Feb 23, 2024
2 parents 26cb6c7 + 35a9e73 commit 4d5c4e5
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 1 deletion.
5 changes: 5 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
10 changes: 9 additions & 1 deletion compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
};
Expand Down
11 changes: 11 additions & 0 deletions tests/ui/union/unnamed-fields/anon-struct-in-enum-issue-121446.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 4d5c4e5

Please sign in to comment.