8347: Minor interning improvements r=jonas-schievink a=jonas-schievink

bors r+

Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
This commit is contained in:
bors[bot] 2021-04-05 17:17:07 +00:00 committed by GitHub
commit 467a5c6cd1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -5,7 +5,7 @@
use std::{ use std::{
collections::HashMap, collections::HashMap,
fmt::{self, Debug}, fmt::{self, Debug},
hash::{BuildHasherDefault, Hash}, hash::{BuildHasherDefault, Hash, Hasher},
ops::Deref, ops::Deref,
sync::Arc, sync::Arc,
}; };
@ -20,7 +20,6 @@ type InternMap<T> = DashMap<Arc<T>, (), BuildHasherDefault<FxHasher>>;
type Guard<T> = type Guard<T> =
RwLockWriteGuard<'static, HashMap<Arc<T>, SharedValue<()>, BuildHasherDefault<FxHasher>>>; RwLockWriteGuard<'static, HashMap<Arc<T>, SharedValue<()>, BuildHasherDefault<FxHasher>>>;
#[derive(Hash)]
pub struct Interned<T: Internable + ?Sized> { pub struct Interned<T: Internable + ?Sized> {
arc: Arc<T>, arc: Arc<T>,
} }
@ -137,6 +136,13 @@ impl PartialEq for Interned<str> {
impl Eq for Interned<str> {} impl Eq for Interned<str> {}
impl<T: Internable + ?Sized> Hash for Interned<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
// NOTE: Cast disposes vtable pointer / slice/str length.
state.write_usize(Arc::as_ptr(&self.arc) as *const () as usize)
}
}
impl<T: Internable + ?Sized> AsRef<T> for Interned<T> { impl<T: Internable + ?Sized> AsRef<T> for Interned<T> {
#[inline] #[inline]
fn as_ref(&self) -> &T { fn as_ref(&self) -> &T {
@ -185,7 +191,10 @@ pub trait Internable: Hash + Eq + 'static {
fn storage() -> &'static InternStorage<Self>; fn storage() -> &'static InternStorage<Self>;
} }
macro_rules! impl_internable { /// Implements `Internable` for a given list of types, making them usable with `Interned`.
#[macro_export]
#[doc(hidden)]
macro_rules! _impl_internable {
( $($t:path),+ $(,)? ) => { $( ( $($t:path),+ $(,)? ) => { $(
impl Internable for $t { impl Internable for $t {
fn storage() -> &'static InternStorage<Self> { fn storage() -> &'static InternStorage<Self> {
@ -196,10 +205,12 @@ macro_rules! impl_internable {
)+ }; )+ };
} }
pub use crate::_impl_internable as impl_internable;
impl_internable!( impl_internable!(
crate::type_ref::TypeRef, crate::type_ref::TypeRef,
crate::type_ref::TraitRef, crate::type_ref::TraitRef,
crate::path::ModPath, crate::path::ModPath,
GenericParams, GenericParams,
str str,
); );