From c00b4ba5efbaa80785cb58dca0389d0e6d7af284 Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 14 Oct 2025 22:29:56 +0800 Subject: [PATCH] Fix ICE caused by associated_item_def_ids on wrong type in resolve diag --- compiler/rustc_resolve/src/lib.rs | 50 ++++++++++++------- .../struct-fields-ice-147325.rs | 11 ++++ .../struct-fields-ice-147325.stderr | 22 ++++++++ 3 files changed, 65 insertions(+), 18 deletions(-) create mode 100644 tests/ui/structs/default-field-values/struct-fields-ice-147325.rs create mode 100644 tests/ui/structs/default-field-values/struct-fields-ice-147325.stderr diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index d9c3f4089a0fb..efb4bbfa2b72e 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -2332,30 +2332,44 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn field_idents(&self, def_id: DefId) -> Option> { match def_id.as_local() { Some(def_id) => self.field_names.get(&def_id).cloned(), - None => Some( - self.tcx - .associated_item_def_ids(def_id) - .iter() - .map(|&def_id| { - Ident::new(self.tcx.item_name(def_id), self.tcx.def_span(def_id)) - }) - .collect(), - ), + None if matches!( + self.tcx.def_kind(def_id), + DefKind::Struct | DefKind::Union | DefKind::Variant + ) => + { + Some( + self.tcx + .associated_item_def_ids(def_id) + .iter() + .map(|&def_id| { + Ident::new(self.tcx.item_name(def_id), self.tcx.def_span(def_id)) + }) + .collect(), + ) + } + _ => None, } } fn field_defaults(&self, def_id: DefId) -> Option> { match def_id.as_local() { Some(def_id) => self.field_defaults.get(&def_id).cloned(), - None => Some( - self.tcx - .associated_item_def_ids(def_id) - .iter() - .filter_map(|&def_id| { - self.tcx.default_field(def_id).map(|_| self.tcx.item_name(def_id)) - }) - .collect(), - ), + None if matches!( + self.tcx.def_kind(def_id), + DefKind::Struct | DefKind::Union | DefKind::Variant + ) => + { + Some( + self.tcx + .associated_item_def_ids(def_id) + .iter() + .filter_map(|&def_id| { + self.tcx.default_field(def_id).map(|_| self.tcx.item_name(def_id)) + }) + .collect(), + ) + } + _ => None, } } diff --git a/tests/ui/structs/default-field-values/struct-fields-ice-147325.rs b/tests/ui/structs/default-field-values/struct-fields-ice-147325.rs new file mode 100644 index 0000000000000..fc68060a96271 --- /dev/null +++ b/tests/ui/structs/default-field-values/struct-fields-ice-147325.rs @@ -0,0 +1,11 @@ +// ICE #147325: When the user mistakenly uses struct syntax to construct an enum, +// the field_idents and field_defaults functions will trigger an error + +mod m { + struct Priv1; +} + +fn main() { + Option { field1: m::Priv1 } //~ ERROR expected struct, variant or union type, found enum + //~^ ERROR unit struct `Priv1` is private +} diff --git a/tests/ui/structs/default-field-values/struct-fields-ice-147325.stderr b/tests/ui/structs/default-field-values/struct-fields-ice-147325.stderr new file mode 100644 index 0000000000000..7193a7112b445 --- /dev/null +++ b/tests/ui/structs/default-field-values/struct-fields-ice-147325.stderr @@ -0,0 +1,22 @@ +error[E0574]: expected struct, variant or union type, found enum `Option` + --> $DIR/struct-fields-ice-147325.rs:9:5 + | +LL | Option { field1: m::Priv1 } + | ^^^^^^ not a struct, variant or union type + +error[E0603]: unit struct `Priv1` is private + --> $DIR/struct-fields-ice-147325.rs:9:25 + | +LL | Option { field1: m::Priv1 } + | ^^^^^ private unit struct + | +note: the unit struct `Priv1` is defined here + --> $DIR/struct-fields-ice-147325.rs:5:5 + | +LL | struct Priv1; + | ^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0574, E0603. +For more information about an error, try `rustc --explain E0574`.