Skip to main content

rustc_metadata/
eii.rs

1use rustc_data_structures::fx::FxIndexMap;
2use rustc_hir::attrs::{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
8// basically the map below but flattened out
9pub(crate) type EiiMapEncodedKeyValue = (DefId, (EiiDecl, Vec<(DefId, EiiImpl)>));
10
11pub(crate) type EiiMap = FxIndexMap<
12    DefId, // the defid of the foreign item associated with the eii
13    (
14        // the corresponding declaration
15        EiiDecl,
16        // all the given implementations, indexed by defid.
17        // We expect there to be only one, but collect them all to give errors if there are more
18        // (or if there are none) in the final crate we build.
19        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    // iterate over all items in the current crate
27    for id in tcx.hir_crate_items(()).eiis() {
28        for i in {

    #[allow(deprecated)]
    {
        {
            'done:
                {
                for i in tcx.get_all_attrs(id) {
                    #[allow(unused_imports)]
                    use rustc_hir::attrs::AttributeKind::*;
                    let i: &rustc_hir::Attribute = i;
                    match i {
                        rustc_hir::Attribute::Parsed(EiiImpls(e)) => {
                            break 'done Some(e);
                        }
                        rustc_hir::Attribute::Unparsed(..) =>
                            {}
                            #[deny(unreachable_patterns)]
                            _ => {}
                    }
                }
                None
            }
        }
    }
}find_attr!(tcx, id, EiiImpls(e) => e).into_iter().flatten() {
29            let decl = match i.resolution {
30                EiiImplResolution::Macro(macro_defid) => {
31                    // 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)
32                    let Some(decl) = {

    #[allow(deprecated)]
    {
        {
            'done:
                {
                for i in tcx.get_all_attrs(macro_defid) {
                    #[allow(unused_imports)]
                    use rustc_hir::attrs::AttributeKind::*;
                    let i: &rustc_hir::Attribute = i;
                    match i {
                        rustc_hir::Attribute::Parsed(EiiDeclaration(d)) => {
                            break 'done Some(*d);
                        }
                        rustc_hir::Attribute::Unparsed(..) =>
                            {}
                            #[deny(unreachable_patterns)]
                            _ => {}
                    }
                }
                None
            }
        }
    }
}find_attr!(tcx, macro_defid, EiiDeclaration(d) => *d) else {
33                        // skip if it doesn't have eii_declaration (if we resolved to another macro that's not an EII)
34                        tcx.dcx()
35                            .span_delayed_bug(i.span, "resolved to something that's not an EII");
36                        continue;
37                    };
38                    decl
39                }
40                EiiImplResolution::Known(decl) => decl,
41                EiiImplResolution::Error(_eg) => continue,
42            };
43
44            // FIXME(eii) remove extern target from encoded decl
45            eiis.entry(decl.foreign_item)
46                .or_insert_with(|| (decl, Default::default()))
47                .1
48                .insert(id.into(), *i);
49        }
50
51        // if we find a new declaration, add it to the list without a known implementation
52        if let Some(decl) = {

    #[allow(deprecated)]
    {
        {
            'done:
                {
                for i in tcx.get_all_attrs(id) {
                    #[allow(unused_imports)]
                    use rustc_hir::attrs::AttributeKind::*;
                    let i: &rustc_hir::Attribute = i;
                    match i {
                        rustc_hir::Attribute::Parsed(EiiDeclaration(d)) => {
                            break 'done Some(*d);
                        }
                        rustc_hir::Attribute::Unparsed(..) =>
                            {}
                            #[deny(unreachable_patterns)]
                            _ => {}
                    }
                }
                None
            }
        }
    }
}find_attr!(tcx, id, EiiDeclaration(d) => *d) {
53            eiis.entry(decl.foreign_item).or_insert((decl, Default::default()));
54        }
55    }
56
57    eiis
58}