Skip to content

Commit 48d9772

Browse files
committed
Check for accessing unnamed field in find_field
1 parent 6f72620 commit 48d9772

File tree

4 files changed

+17
-8
lines changed

4 files changed

+17
-8
lines changed

compiler/rustc_hir_analysis/src/collect.rs

+4
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,10 @@ fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
793793
fn find_field(tcx: TyCtxt<'_>, (def_id, ident): (DefId, Ident)) -> Option<FieldIdx> {
794794
tcx.adt_def(def_id).non_enum_variant().fields.iter_enumerated().find_map(|(idx, field)| {
795795
if field.is_unnamed() {
796+
// Users can't write `expr._`, but derive macros can
797+
if ident.name == kw::Underscore {
798+
return Some(idx);
799+
}
796800
let field_ty = tcx.type_of(field.did).instantiate_identity();
797801
let adt_def = field_ty.ty_adt_def().expect("expect Adt for unnamed field");
798802
tcx.find_field((adt_def.did(), ident)).map(|_| idx)

compiler/rustc_middle/src/query/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2225,6 +2225,8 @@ rustc_queries! {
22252225
separate_provide_extern
22262226
}
22272227

2228+
/// Find a field with a given name on the given def (must be a struct or union). Will
2229+
/// recurse into unnamed fields if present.
22282230
query find_field((def_id, ident): (DefId, rustc_span::symbol::Ident)) -> Option<rustc_target::abi::FieldIdx> {
22292231
desc { |tcx| "find the index of maybe nested field `{ident}` in `{}`", tcx.def_path_str(def_id) }
22302232
}

tests/ui/union/unnamed-fields/restrict_type_hir.rs

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ enum BadEnum {
1818
}
1919

2020
#[repr(C)]
21+
#[derive(Debug)]
2122
enum BadEnum2 {
2223
A,
2324
B,
@@ -26,7 +27,9 @@ enum BadEnum2 {
2627
type MyStruct = A;
2728
type MyI32 = i32;
2829

30+
// Derive to check if accessing fields will ICE (#121263)
2931
#[repr(C)]
32+
#[derive(Debug)]
3033
struct L {
3134
_: i32, //~ ERROR unnamed fields can only have struct or union types
3235
_: MyI32, //~ ERROR unnamed fields can only have struct or union types

tests/ui/union/unnamed-fields/restrict_type_hir.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11
error: unnamed fields can only have struct or union types
2-
--> $DIR/restrict_type_hir.rs:31:5
2+
--> $DIR/restrict_type_hir.rs:34:5
33
|
44
LL | _: i32,
55
| ^^^^^^
66

77
error: unnamed fields can only have struct or union types
8-
--> $DIR/restrict_type_hir.rs:32:5
8+
--> $DIR/restrict_type_hir.rs:35:5
99
|
1010
LL | _: MyI32,
1111
| ^^^^^^^^
1212

1313
error: unnamed fields can only have struct or union types
14-
--> $DIR/restrict_type_hir.rs:33:5
14+
--> $DIR/restrict_type_hir.rs:36:5
1515
|
1616
LL | _: BadEnum,
1717
| ^^^^^^^^^^
1818

1919
error: unnamed fields can only have struct or union types
20-
--> $DIR/restrict_type_hir.rs:34:5
20+
--> $DIR/restrict_type_hir.rs:37:5
2121
|
2222
LL | _: BadEnum2,
2323
| ^^^^^^^^^^^
2424

2525
error: named type of unnamed field must have `#[repr(C)]` representation
26-
--> $DIR/restrict_type_hir.rs:36:5
26+
--> $DIR/restrict_type_hir.rs:39:5
2727
|
2828
LL | _: dep::BadStruct,
2929
| ^^^^^^^^^^^^^^^^^ unnamed field defined here
@@ -41,19 +41,19 @@ LL | pub struct BadStruct(());
4141
|
4242

4343
error: unnamed fields can only have struct or union types
44-
--> $DIR/restrict_type_hir.rs:37:5
44+
--> $DIR/restrict_type_hir.rs:40:5
4545
|
4646
LL | _: dep::BadEnum,
4747
| ^^^^^^^^^^^^^^^
4848

4949
error: unnamed fields can only have struct or union types
50-
--> $DIR/restrict_type_hir.rs:38:5
50+
--> $DIR/restrict_type_hir.rs:41:5
5151
|
5252
LL | _: dep::BadEnum2,
5353
| ^^^^^^^^^^^^^^^^
5454

5555
error: unnamed fields can only have struct or union types
56-
--> $DIR/restrict_type_hir.rs:39:5
56+
--> $DIR/restrict_type_hir.rs:42:5
5757
|
5858
LL | _: dep::BadAlias,
5959
| ^^^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)