Skip to main content

rustc_symbol_mangling/
export.rs

1use rustc_abi::IntegerType;
2use rustc_data_structures::debug_assert_matches;
3use rustc_data_structures::stable_hasher::StableHasher;
4use rustc_hashes::Hash128;
5use rustc_hir::def::DefKind;
6use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
7use rustc_span::symbol::{Symbol, sym};
8
9trait AbiHashStable<'tcx> {
10    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher);
11}
12macro_rules! default_hash_impl {
13    ($($t:ty,)+) => {
14        $(impl<'tcx> AbiHashStable<'tcx> for $t {
15            #[inline]
16            fn abi_hash(&self, _tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
17                ::std::hash::Hash::hash(self, hasher);
18            }
19        })*
20    };
21}
22
23impl<'tcx> AbiHashStable<'tcx> for usize {
    #[inline]
    fn abi_hash(&self, _tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
        ::std::hash::Hash::hash(self, hasher);
    }
}default_hash_impl! { u8, u64, usize, }
24
25impl<'tcx> AbiHashStable<'tcx> for bool {
26    #[inline]
27    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
28        (if *self { 1u8 } else { 0u8 }).abi_hash(tcx, hasher);
29    }
30}
31
32impl<'tcx> AbiHashStable<'tcx> for str {
33    #[inline]
34    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
35        self.as_bytes().abi_hash(tcx, hasher);
36    }
37}
38
39impl<'tcx> AbiHashStable<'tcx> for Symbol {
40    #[inline]
41    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
42        self.as_str().abi_hash(tcx, hasher);
43    }
44}
45
46impl<'tcx, T: AbiHashStable<'tcx>> AbiHashStable<'tcx> for [T] {
47    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
48        self.len().abi_hash(tcx, hasher);
49        for item in self {
50            item.abi_hash(tcx, hasher);
51        }
52    }
53}
54
55impl<'tcx> AbiHashStable<'tcx> for Ty<'tcx> {
56    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
57        match self.kind() {
58            ty::Bool => sym::bool.abi_hash(tcx, hasher),
59            ty::Char => sym::char.abi_hash(tcx, hasher),
60            ty::Int(int_ty) => int_ty.name_str().abi_hash(tcx, hasher),
61            ty::Uint(uint_ty) => uint_ty.name_str().abi_hash(tcx, hasher),
62            ty::Float(float_ty) => float_ty.name_str().abi_hash(tcx, hasher),
63
64            ty::Adt(adt_def, args) => {
65                adt_def.is_struct().abi_hash(tcx, hasher);
66                adt_def.is_enum().abi_hash(tcx, hasher);
67                adt_def.is_union().abi_hash(tcx, hasher);
68
69                if let Some(align) = adt_def.repr().align {
70                    align.bits().abi_hash(tcx, hasher);
71                }
72
73                if let Some(integer) = adt_def.repr().int {
74                    match integer {
75                        IntegerType::Pointer(sign) => sign.abi_hash(tcx, hasher),
76                        IntegerType::Fixed(integer, sign) => {
77                            integer.int_ty_str().abi_hash(tcx, hasher);
78                            sign.abi_hash(tcx, hasher);
79                        }
80                    }
81                }
82
83                if let Some(pack) = adt_def.repr().pack {
84                    pack.bits().abi_hash(tcx, hasher);
85                }
86
87                adt_def.repr().c().abi_hash(tcx, hasher);
88
89                for variant in adt_def.variants() {
90                    variant.name.abi_hash(tcx, hasher);
91                    for field in &variant.fields {
92                        field.name.abi_hash(tcx, hasher);
93                        let field_ty = tcx.type_of(field.did).instantiate_identity();
94                        field_ty.abi_hash(tcx, hasher);
95                    }
96                }
97                args.abi_hash(tcx, hasher);
98            }
99
100            ty::Tuple(args) if args.len() == 0 => {}
101
102            // FIXME: Not yet supported.
103            ty::Foreign(_)
104            | ty::Ref(_, _, _)
105            | ty::Str
106            | ty::Array(_, _)
107            | ty::Pat(_, _)
108            | ty::Slice(_)
109            | ty::RawPtr(_, _)
110            | ty::FnDef(_, _)
111            | ty::FnPtr(_, _)
112            | ty::Dynamic(_, _)
113            | ty::Closure(_, _)
114            | ty::CoroutineClosure(_, _)
115            | ty::Coroutine(_, _)
116            | ty::CoroutineWitness(_, _)
117            | ty::Never
118            | ty::Tuple(_)
119            | ty::Alias(_, _)
120            | ty::Param(_)
121            | ty::Bound(_, _)
122            | ty::Placeholder(_)
123            | ty::Infer(_)
124            | ty::UnsafeBinder(_) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
125
126            ty::Error(_) => {}
127        }
128    }
129}
130
131impl<'tcx> AbiHashStable<'tcx> for ty::FnSig<'tcx> {
132    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
133        for ty in self.inputs_and_output {
134            ty.abi_hash(tcx, hasher);
135        }
136        self.safety.is_safe().abi_hash(tcx, hasher);
137    }
138}
139
140impl<'tcx> AbiHashStable<'tcx> for ty::GenericArg<'tcx> {
141    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
142        self.kind().abi_hash(tcx, hasher);
143    }
144}
145
146impl<'tcx> AbiHashStable<'tcx> for ty::GenericArgKind<'tcx> {
147    fn abi_hash(&self, tcx: TyCtxt<'tcx>, hasher: &mut StableHasher) {
148        match self {
149            ty::GenericArgKind::Type(t) => t.abi_hash(tcx, hasher),
150            ty::GenericArgKind::Lifetime(_) | ty::GenericArgKind::Const(_) => ::core::panicking::panic("not implemented")unimplemented!(),
151        }
152    }
153}
154
155pub(crate) fn compute_hash_of_export_fn<'tcx>(
156    tcx: TyCtxt<'tcx>,
157    instance: Instance<'tcx>,
158) -> String {
159    let def_id = instance.def_id();
160    if true {
    match tcx.def_kind(def_id) {
        DefKind::Fn | DefKind::AssocFn => {}
        ref left_val => {
            ::core::panicking::assert_matches_failed(left_val,
                "DefKind::Fn | DefKind::AssocFn",
                ::core::option::Option::None);
        }
    };
};debug_assert_matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn);
161
162    let args = instance.args;
163    let sig_ty = tcx.fn_sig(def_id).instantiate(tcx, args);
164    let sig_ty = tcx.instantiate_bound_regions_with_erased(sig_ty);
165
166    let hash = {
167        let mut hasher = StableHasher::new();
168        sig_ty.abi_hash(tcx, &mut hasher);
169        hasher.finish::<Hash128>()
170    };
171
172    hash.as_u128().to_string()
173}