From 5e5c724194594c9af85d6678aef90ebc4a3428b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Fri, 19 Dec 2025 18:24:15 +0100 Subject: [PATCH] turn panics into `span_delayed_bug` to make sure this pattern doesn't go unnoticed --- .../rustc_codegen_ssa/src/codegen_attrs.rs | 11 +++++++--- .../rustc_hir_analysis/src/check/wfcheck.rs | 4 +--- compiler/rustc_metadata/src/eii.rs | 20 +++++++++++++++---- .../eii/duplicate/eii_conflict_with_macro.rs | 2 +- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 74f4662118b6..2ad5792de3c0 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -285,11 +285,16 @@ fn process_builtin_attrs( } AttributeKind::EiiImpls(impls) => { for i in impls { - let extern_item = find_attr!( + let Some(extern_item) = find_attr!( tcx.get_all_attrs(i.eii_macro), AttributeKind::EiiExternTarget(target) => target.eii_extern_target - ) - .expect("eii should have declaration macro with extern target attribute"); + ) else { + tcx.dcx().span_delayed_bug( + i.span, + "resolved to something that's not an EII", + ); + continue; + }; // this is to prevent a bug where a single crate defines both the default and explicit implementation // for an EII. In that case, both of them may be part of the same final object file. I'm not 100% sure diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 725294dfd377..8cc3fab128e2 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1213,9 +1213,7 @@ fn check_eiis(tcx: TyCtxt<'_>, def_id: LocalDefId) { *span, ); } else { - panic!( - "EII impl macro {eii_macro:?} did not have an eii extern target attribute pointing to a foreign function" - ) + tcx.dcx().span_delayed_bug(*span, "resolved to something that's not an EII"); } } } diff --git a/compiler/rustc_metadata/src/eii.rs b/compiler/rustc_metadata/src/eii.rs index 5558ff930851..3f60f528776f 100644 --- a/compiler/rustc_metadata/src/eii.rs +++ b/compiler/rustc_metadata/src/eii.rs @@ -1,4 +1,5 @@ use rustc_data_structures::fx::FxIndexMap; +use rustc_data_structures::indexmap::map::Entry; use rustc_hir::attrs::{AttributeKind, EiiDecl, EiiImpl}; use rustc_hir::def_id::DefId; use rustc_hir::find_attr; @@ -28,11 +29,22 @@ pub(crate) fn collect<'tcx>(tcx: TyCtxt<'tcx>, LocalCrate: LocalCrate) -> EiiMap for i in find_attr!(tcx.get_all_attrs(id), AttributeKind::EiiImpls(e) => e).into_iter().flatten() { - eiis.entry(i.eii_macro) - .or_insert_with(|| { + let registered_impls = match eiis.entry(i.eii_macro) { + Entry::Occupied(o) => &mut o.into_mut().1, + Entry::Vacant(v) => { // find the decl for this one if it wasn't in yet (maybe it's from the local crate? not very useful but not illegal) - (find_attr!(tcx.get_all_attrs(i.eii_macro), AttributeKind::EiiExternTarget(d) => *d).unwrap(), Default::default()) - }).1.insert(id.into(), *i); + let Some(decl) = find_attr!(tcx.get_all_attrs(i.eii_macro), AttributeKind::EiiExternTarget(d) => *d) + else { + // skip if it doesn't have eii_extern_target (if we resolved to another macro that's not an EII) + tcx.dcx() + .span_delayed_bug(i.span, "resolved to something that's not an EII"); + continue; + }; + &mut v.insert((decl, Default::default())).1 + } + }; + + registered_impls.insert(id.into(), *i); } // if we find a new declaration, add it to the list without a known implementation diff --git a/tests/ui/eii/duplicate/eii_conflict_with_macro.rs b/tests/ui/eii/duplicate/eii_conflict_with_macro.rs index 4012ea268799..deee2346552f 100644 --- a/tests/ui/eii/duplicate/eii_conflict_with_macro.rs +++ b/tests/ui/eii/duplicate/eii_conflict_with_macro.rs @@ -1,6 +1,6 @@ //@ compile-flags: --crate-type rlib #![feature(extern_item_impls)] -macro_rules! foo_impl {} +macro_rules! foo_impl { () => {} } #[eii] fn foo_impl() {}