turn panics into span_delayed_bug to make sure this pattern doesn't go unnoticed

This commit is contained in:
Jana Dönszelmann 2025-12-19 18:24:15 +01:00
parent 3c8265a29f
commit 5e5c724194
No known key found for this signature in database
4 changed files with 26 additions and 11 deletions

View file

@ -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

View file

@ -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");
}
}
}

View file

@ -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

View file

@ -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() {}