]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_data_structures/sharded.rs
Rollup merge of #69324 - estebank:ice-break-backport-bad-placeholder-type, r=Centril
[rust.git] / src / librustc_data_structures / sharded.rs
index 8b85d97a1d4fe235390bbae7dcb88fab62ca9023..15d1e2dd0b644c08086e60a9c8b82586fda0589d 100644 (file)
@@ -69,12 +69,21 @@ pub fn get_shard_by_value<K: Hash + ?Sized>(&self, val: &K) -> &Lock<T> {
     /// `hash` can be computed with any hasher, so long as that hasher is used
     /// consistently for each `Sharded` instance.
     #[inline]
-    pub fn get_shard_by_hash(&self, hash: u64) -> &Lock<T> {
+    pub fn get_shard_index_by_hash(&self, hash: u64) -> usize {
         let hash_len = mem::size_of::<usize>();
         // Ignore the top 7 bits as hashbrown uses these and get the next SHARD_BITS highest bits.
         // hashbrown also uses the lowest bits, so we can't use those
         let bits = (hash >> (hash_len * 8 - 7 - SHARD_BITS)) as usize;
-        let i = bits % SHARDS;
+        bits % SHARDS
+    }
+
+    #[inline]
+    pub fn get_shard_by_hash(&self, hash: u64) -> &Lock<T> {
+        &self.shards[self.get_shard_index_by_hash(hash)].0
+    }
+
+    #[inline]
+    pub fn get_shard_by_index(&self, i: usize) -> &Lock<T> {
         &self.shards[i].0
     }
 
@@ -137,6 +146,20 @@ pub fn intern<Q>(&self, value: Q, make: impl FnOnce(Q) -> K) -> K
     }
 }
 
+pub trait IntoPointer {
+    /// Returns a pointer which outlives `self`.
+    fn into_pointer(&self) -> *const ();
+}
+
+impl<K: Eq + Hash + Copy + IntoPointer> ShardedHashMap<K, ()> {
+    pub fn contains_pointer_to<T: Hash + IntoPointer>(&self, value: &T) -> bool {
+        let hash = make_hash(&value);
+        let shard = self.get_shard_by_hash(hash).lock();
+        let value = value.into_pointer();
+        shard.raw_entry().from_hash(hash, |entry| entry.into_pointer() == value).is_some()
+    }
+}
+
 #[inline]
 fn make_hash<K: Hash + ?Sized>(val: &K) -> u64 {
     let mut state = FxHasher::default();