rustc_middle/ty/
impls_ty.rs

1//! This module contains `HashStable` implementations for various data types
2//! from `rustc_middle::ty` in no particular order.
3
4use std::cell::RefCell;
5use std::ptr;
6
7use rustc_data_structures::fingerprint::Fingerprint;
8use rustc_data_structures::fx::FxHashMap;
9use rustc_data_structures::stable_hasher::{
10    HashStable, HashingControls, StableHasher, ToStableHashKey,
11};
12use rustc_query_system::ich::StableHashingContext;
13use tracing::trace;
14
15use crate::middle::region;
16use crate::{mir, ty};
17
18impl<'a, 'tcx, H, T> HashStable<StableHashingContext<'a>> for &'tcx ty::list::RawList<H, T>
19where
20    T: HashStable<StableHashingContext<'a>>,
21{
22    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
23        thread_local! {
24            static CACHE: RefCell<FxHashMap<(*const (), HashingControls), Fingerprint>> =
25                RefCell::new(Default::default());
26        }
27
28        let hash = CACHE.with(|cache| {
29            let key = (ptr::from_ref(*self).cast::<()>(), hcx.hashing_controls());
30            if let Some(&hash) = cache.borrow().get(&key) {
31                return hash;
32            }
33
34            let mut hasher = StableHasher::new();
35            self[..].hash_stable(hcx, &mut hasher);
36
37            let hash: Fingerprint = hasher.finish();
38            cache.borrow_mut().insert(key, hash);
39            hash
40        });
41
42        hash.hash_stable(hcx, hasher);
43    }
44}
45
46impl<'a, 'tcx, H, T> ToStableHashKey<StableHashingContext<'a>> for &'tcx ty::list::RawList<H, T>
47where
48    T: HashStable<StableHashingContext<'a>>,
49{
50    type KeyType = Fingerprint;
51
52    #[inline]
53    fn to_stable_hash_key(&self, hcx: &StableHashingContext<'a>) -> Fingerprint {
54        let mut hasher = StableHasher::new();
55        let mut hcx: StableHashingContext<'a> = hcx.clone();
56        self.hash_stable(&mut hcx, &mut hasher);
57        hasher.finish()
58    }
59}
60
61impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::GenericArg<'tcx> {
62    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
63        self.unpack().hash_stable(hcx, hasher);
64    }
65}
66
67// AllocIds get resolved to whatever they point to (to be stable)
68impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
69    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
70        ty::tls::with_opt(|tcx| {
71            trace!("hashing {:?}", *self);
72            let tcx = tcx.expect("can't hash AllocIds during hir lowering");
73            tcx.try_get_global_alloc(*self).hash_stable(hcx, hasher);
74        });
75    }
76}
77
78impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::CtfeProvenance {
79    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
80        self.into_parts().hash_stable(hcx, hasher);
81    }
82}
83
84impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope {
85    type KeyType = region::Scope;
86
87    #[inline]
88    fn to_stable_hash_key(&self, _: &StableHashingContext<'a>) -> region::Scope {
89        *self
90    }
91}