aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/intern.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/intern.rs')
-rw-r--r--crates/hir_def/src/intern.rs19
1 files changed, 15 insertions, 4 deletions
diff --git a/crates/hir_def/src/intern.rs b/crates/hir_def/src/intern.rs
index 2467e9299..abc304ef0 100644
--- a/crates/hir_def/src/intern.rs
+++ b/crates/hir_def/src/intern.rs
@@ -5,7 +5,7 @@
5use std::{ 5use std::{
6 collections::HashMap, 6 collections::HashMap,
7 fmt::{self, Debug}, 7 fmt::{self, Debug},
8 hash::{BuildHasherDefault, Hash}, 8 hash::{BuildHasherDefault, Hash, Hasher},
9 ops::Deref, 9 ops::Deref,
10 sync::Arc, 10 sync::Arc,
11}; 11};
@@ -20,7 +20,6 @@ type InternMap<T> = DashMap<Arc<T>, (), BuildHasherDefault<FxHasher>>;
20type Guard<T> = 20type Guard<T> =
21 RwLockWriteGuard<'static, HashMap<Arc<T>, SharedValue<()>, BuildHasherDefault<FxHasher>>>; 21 RwLockWriteGuard<'static, HashMap<Arc<T>, SharedValue<()>, BuildHasherDefault<FxHasher>>>;
22 22
23#[derive(Hash)]
24pub struct Interned<T: Internable + ?Sized> { 23pub struct Interned<T: Internable + ?Sized> {
25 arc: Arc<T>, 24 arc: Arc<T>,
26} 25}
@@ -137,6 +136,13 @@ impl PartialEq for Interned<str> {
137 136
138impl Eq for Interned<str> {} 137impl Eq for Interned<str> {}
139 138
139impl<T: Internable + ?Sized> Hash for Interned<T> {
140 fn hash<H: Hasher>(&self, state: &mut H) {
141 // NOTE: Cast disposes vtable pointer / slice/str length.
142 state.write_usize(Arc::as_ptr(&self.arc) as *const () as usize)
143 }
144}
145
140impl<T: Internable + ?Sized> AsRef<T> for Interned<T> { 146impl<T: Internable + ?Sized> AsRef<T> for Interned<T> {
141 #[inline] 147 #[inline]
142 fn as_ref(&self) -> &T { 148 fn as_ref(&self) -> &T {
@@ -185,7 +191,10 @@ pub trait Internable: Hash + Eq + 'static {
185 fn storage() -> &'static InternStorage<Self>; 191 fn storage() -> &'static InternStorage<Self>;
186} 192}
187 193
188macro_rules! impl_internable { 194/// Implements `Internable` for a given list of types, making them usable with `Interned`.
195#[macro_export]
196#[doc(hidden)]
197macro_rules! _impl_internable {
189 ( $($t:path),+ $(,)? ) => { $( 198 ( $($t:path),+ $(,)? ) => { $(
190 impl Internable for $t { 199 impl Internable for $t {
191 fn storage() -> &'static InternStorage<Self> { 200 fn storage() -> &'static InternStorage<Self> {
@@ -196,10 +205,12 @@ macro_rules! impl_internable {
196 )+ }; 205 )+ };
197} 206}
198 207
208pub use crate::_impl_internable as impl_internable;
209
199impl_internable!( 210impl_internable!(
200 crate::type_ref::TypeRef, 211 crate::type_ref::TypeRef,
201 crate::type_ref::TraitRef, 212 crate::type_ref::TraitRef,
202 crate::path::ModPath, 213 crate::path::ModPath,
203 GenericParams, 214 GenericParams,
204 str 215 str,
205); 216);