From 4e03c51f7d693258cdffc9d6b66e7930cbe8509f Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 4 Mar 2024 11:34:10 +0000 Subject: [PATCH] hir_analysis: enums return `None` in `find_field` Unnamed union fields with enums are checked for, but if `find_field` causes an ICE then the compiler won't get to that point. Signed-off-by: David Wood --- compiler/rustc_hir_analysis/src/collect.rs | 7 ++- .../unnamed-enum-field-issue-121757.rs | 25 +++++++++++ .../unnamed-enum-field-issue-121757.stderr | 45 +++++++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 tests/ui/union/unnamed-fields/unnamed-enum-field-issue-121757.rs create mode 100644 tests/ui/union/unnamed-fields/unnamed-enum-field-issue-121757.stderr diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index b6e2695590c13..2cc37651ef521 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -791,7 +791,12 @@ fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) { } fn find_field(tcx: TyCtxt<'_>, (def_id, ident): (DefId, Ident)) -> Option { - tcx.adt_def(def_id).non_enum_variant().fields.iter_enumerated().find_map(|(idx, field)| { + let adt = tcx.adt_def(def_id); + if adt.is_enum() { + return None; + } + + adt.non_enum_variant().fields.iter_enumerated().find_map(|(idx, field)| { if field.is_unnamed() { let field_ty = tcx.type_of(field.did).instantiate_identity(); let adt_def = field_ty.ty_adt_def().expect("expect Adt for unnamed field"); diff --git a/tests/ui/union/unnamed-fields/unnamed-enum-field-issue-121757.rs b/tests/ui/union/unnamed-fields/unnamed-enum-field-issue-121757.rs new file mode 100644 index 0000000000000..5d15ec4cffdb9 --- /dev/null +++ b/tests/ui/union/unnamed-fields/unnamed-enum-field-issue-121757.rs @@ -0,0 +1,25 @@ +type NodeId = u32; +struct Type<'a>(std::marker::PhantomData::<&'a ()>); + +type Ast<'ast> = &'ast AstStructure<'ast>; + +struct AstStructure<'ast> { +//~^ ERROR struct with unnamed fields must have `#[repr(C)]` representation + id: NodeId, + _: AstKind<'ast> +//~^ ERROR unnamed fields are not yet fully implemented [E0658] +//~^^ ERROR unnamed fields can only have struct or union types +} + +enum AstKind<'ast> { + ExprInt, + ExprLambda(Ast<'ast>), +} + +fn compute_types<'tcx,'ast>(ast: Ast<'ast>) -> Type<'tcx> +{ + match ast.kind {} +//~^ ERROR no field `kind` on type `&'ast AstStructure<'ast>` [E0609] +} + +fn main() {} diff --git a/tests/ui/union/unnamed-fields/unnamed-enum-field-issue-121757.stderr b/tests/ui/union/unnamed-fields/unnamed-enum-field-issue-121757.stderr new file mode 100644 index 0000000000000..4ea910202de98 --- /dev/null +++ b/tests/ui/union/unnamed-fields/unnamed-enum-field-issue-121757.stderr @@ -0,0 +1,45 @@ +error[E0658]: unnamed fields are not yet fully implemented + --> $DIR/unnamed-enum-field-issue-121757.rs:9:5 + | +LL | _: AstKind<'ast> + | ^ + | + = note: see issue #49804 for more information + = help: add `#![feature(unnamed_fields)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: struct with unnamed fields must have `#[repr(C)]` representation + --> $DIR/unnamed-enum-field-issue-121757.rs:6:1 + | +LL | struct AstStructure<'ast> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ struct `AstStructure` defined here + | +note: unnamed field defined here + --> $DIR/unnamed-enum-field-issue-121757.rs:9:5 + | +LL | _: AstKind<'ast> + | ^^^^^^^^^^^^^^^^ +help: add `#[repr(C)]` to this struct + | +LL + #[repr(C)] +LL | struct AstStructure<'ast> { + | + +error: unnamed fields can only have struct or union types + --> $DIR/unnamed-enum-field-issue-121757.rs:9:5 + | +LL | _: AstKind<'ast> + | ^^^^^^^^^^^^^^^^ + +error[E0609]: no field `kind` on type `&'ast AstStructure<'ast>` + --> $DIR/unnamed-enum-field-issue-121757.rs:21:15 + | +LL | match ast.kind {} + | ^^^^ unknown field + | + = note: available fields are: `id`, `_` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0609, E0658. +For more information about an error, try `rustc --explain E0609`.