rapx/
def_id.rs

1extern crate indexmap;
2
3use indexmap::IndexMap;
4use rustc_hir::def_id::DefId;
5use rustc_middle::ty::TyCtxt;
6use rustc_public::{rustc_internal, CrateDef};
7use std::sync::OnceLock;
8
9static INIT: OnceLock<Intrinsics> = OnceLock::new();
10
11struct Intrinsics {
12    map: IndexMap<&'static str, DefId>,
13}
14
15pub fn init(tcx: TyCtxt) {
16    INIT.get_or_init(|| init_inner(tcx));
17}
18
19fn init_inner(tcx: TyCtxt) -> Intrinsics {
20    const CRATES: &[&str] = &["core", "std", "alloc"];
21
22    let mut map = IndexMap::with_capacity(INTRINSICS.len());
23    for krate in rustc_public::external_crates() {
24        if !CRATES.iter().any(|name| *name == krate.name) {
25            continue;
26        }
27        for fn_def in krate.fn_defs() {
28            let fn_name = fn_def.name();
29            if let Some(name) = INTRINSICS
30                .iter()
31                .find_map(|&name| (name == fn_name).then_some(name))
32            {
33                // if INTRINSICS.iter().any(|name| fn_name.contains(name)) {
34                let def_id = rustc_internal::internal(tcx, fn_def.def_id());
35                if map.contains_key(name) {
36                    panic!("DefId of {fn_name} has been inserted: {def_id:?}");
37                } else {
38                    map.insert(name, def_id);
39                }
40            }
41        }
42    }
43
44    map.sort_unstable_by(|a, _, b, _| a.cmp(b));
45    assert_eq!(
46        INTRINSICS.len(),
47        map.len(),
48        "Intrinsic functions is incompletely retrieved.\n\
49         INTRINSICS = {INTRINSICS:#?}\nmap ={map:#?}"
50    );
51    // rap_info!("Intrinsic = {map:#?}");
52    Intrinsics { map }
53}
54
55macro_rules! intrinsics {
56    ($( $id:ident : $call:literal ,)+ ) => {
57        const INTRINSICS: &[&str] = &[$($call,)+];
58        $(
59            pub fn $id() -> DefId {
60                *INIT.get().expect("Intrinsics DefIds haven't been initialized.").map.get($call)
61                    .unwrap_or_else(|| panic!("Failed to retrieve the DefId of {}.", $call))
62            }
63        )+
64    };
65}
66
67intrinsics! {
68    assume_init_drop: "std::mem::MaybeUninit::<T>::assume_init_drop",
69    call_mut: "std::ops::FnMut::call_mut",
70    clone: "std::clone::Clone::clone",
71    copy_from: "std::ptr::mut_ptr::<impl *mut T>::copy_from",
72    copy_from_nonoverlapping: "std::ptr::mut_ptr::<impl *mut T>::copy_from_nonoverlapping",
73    copy_to: "std::ptr::const_ptr::<impl *const T>::copy_to",
74    copy_to_nonoverlapping: "std::ptr::const_ptr::<impl *const T>::copy_to_nonoverlapping",
75    dealloc: "std::alloc::dealloc",
76    drop: "std::mem::drop",
77    drop_in_place: "std::ptr::drop_in_place",
78    manually_drop: "std::mem::ManuallyDrop::<T>::drop",
79}
80
81/// rustc_public DefId to internal DefId
82pub fn to_internal<T: CrateDef>(val: &T, tcx: TyCtxt) -> DefId {
83    rustc_internal::internal(tcx, val.def_id())
84}