use std::borrow::Borrow; use std::cell::RefCell; use std::hash::Hash; use std::thread::LocalKey; use erg_common::dict::Dict; use crate::ty::Type; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct SubtypePair { pub sub: Type, pub sup: Type, } impl SubtypePair { pub const fn new(sub: Type, sup: Type) -> Self { Self { sub, sup } } } /// Caches type relationships. /// The cost of searching for subtype relations of a class, for example, is not small. /// Some relationships are cached because they tend to be queried many times. #[derive(Debug, Default)] pub struct TypeCmpCache { cache: Dict, } impl TypeCmpCache { pub fn new() -> Self { Self::default() } pub fn get(&self, pair: &Q) -> Option where SubtypePair: Borrow, { self.cache.get(pair).copied() } pub fn register(&mut self, pair: SubtypePair, b: bool) { self.cache.insert(pair, b); } } thread_local! { static TYPE_CACHE: RefCell = RefCell::new(TypeCmpCache::default()); } #[derive(Debug)] pub struct GlobalTypeCmpCache(LocalKey>); pub static GLOBAL_TYPE_CACHE: GlobalTypeCmpCache = GlobalTypeCmpCache(TYPE_CACHE); impl GlobalTypeCmpCache { pub fn get(&'static self, pair: &Q) -> Option where SubtypePair: Borrow, { self.0.with(|s| s.borrow().get(pair)) } pub fn register(&'static self, pair: SubtypePair, b: bool) { self.0.with(|s| s.borrow_mut().register(pair, b)); } }