1use rustc_data_structures::fx::FxIndexMap;
2use rustc_hir::attrs::{AttributeKind, EiiDecl, EiiImpl, EiiImplResolution};
3use rustc_hir::def_id::DefId;
4use rustc_hir::find_attr;
5use rustc_middle::query::LocalCrate;
6use rustc_middle::ty::TyCtxt;
7
8pub(crate) type EiiMapEncodedKeyValue = (DefId, (EiiDecl, Vec<(DefId, EiiImpl)>));
10
11pub(crate) type EiiMap = FxIndexMap<
12 DefId, (
14 EiiDecl,
16 FxIndexMap<DefId, EiiImpl>,
20 ),
21>;
22
23pub(crate) fn collect<'tcx>(tcx: TyCtxt<'tcx>, LocalCrate: LocalCrate) -> EiiMap {
24 let mut eiis = EiiMap::default();
25
26 for id in tcx.hir_crate_items(()).eiis() {
28 for i in
29 find_attr!(tcx.get_all_attrs(id), AttributeKind::EiiImpls(e) => e).into_iter().flatten()
30 {
31 let decl = match i.resolution {
32 EiiImplResolution::Macro(macro_defid) => {
33 let Some(decl) = find_attr!(tcx.get_all_attrs(macro_defid), AttributeKind::EiiDeclaration(d) => *d)
35 else {
36 tcx.dcx()
38 .span_delayed_bug(i.span, "resolved to something that's not an EII");
39 continue;
40 };
41 decl
42 }
43 EiiImplResolution::Known(decl) => decl,
44 EiiImplResolution::Error(_eg) => continue,
45 };
46
47 eiis.entry(decl.foreign_item)
49 .or_insert_with(|| (decl, Default::default()))
50 .1
51 .insert(id.into(), *i);
52 }
53
54 if let Some(decl) =
56 find_attr!(tcx.get_all_attrs(id), AttributeKind::EiiDeclaration(d) => *d)
57 {
58 eiis.entry(decl.foreign_item).or_insert((decl, Default::default()));
59 }
60 }
61
62 eiis
63}