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