1 use hashbrown::{hash_map::RawEntryMut, HashMap};
14 loc_set::{LocSet, LocSetMaxConflictsWith},
18 pub struct Interned<T: ?Sized> {
22 impl<T: ?Sized> Deref for Interned<T> {
25 fn deref(&self) -> &Self::Target {
30 impl<T: ?Sized> Hash for Interned<T> {
31 fn hash<H: Hasher>(&self, state: &mut H) {
32 Rc::as_ptr(&self.ptr).hash(state);
36 impl<T: ?Sized> Eq for Interned<T> {}
38 impl<T: ?Sized + fmt::Debug> fmt::Debug for Interned<T> {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44 impl<T: ?Sized + fmt::Display> fmt::Display for Interned<T> {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 impl<T: ?Sized + Serialize> Serialize for Interned<T> {
51 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
55 self.ptr.serialize(serializer)
59 impl<T: ?Sized> PartialEq for Interned<T> {
60 fn eq(&self, other: &Interned<T>) -> bool {
61 Rc::ptr_eq(&self.ptr, &other.ptr)
65 impl<T: ?Sized> PartialOrd for Interned<T> {
66 fn partial_cmp(&self, other: &Interned<T>) -> Option<Ordering> {
71 impl<T: ?Sized> Ord for Interned<T> {
72 fn cmp(&self, other: &Interned<T>) -> Ordering {
73 Rc::as_ptr(&self.ptr).cmp(&Rc::as_ptr(&other.ptr))
80 loc_set: Interner<LocSet>,
81 loc_set_max_conflicts_with_loc_set: Interner<LocSetMaxConflictsWith<Interned<LocSet>>>,
82 loc_set_max_conflicts_with_loc: Interner<LocSetMaxConflictsWith<Loc>>,
85 pub struct GlobalState {
89 scoped_tls::scoped_thread_local!(static GLOBAL_STATE: GlobalState);
92 pub fn scope<R>(f: impl FnOnce() -> R) -> R {
95 interners: Interners::default(),
100 pub fn get<R>(f: impl for<'a> FnOnce(&'a GlobalState) -> R) -> R {
105 pub struct Interner<T: ?Sized>(RefCell<HashMap<Rc<T>, ()>>);
107 impl<T: ?Sized> Default for Interner<T> {
108 fn default() -> Self {
109 Self(Default::default())
113 pub struct InternInput<
115 T: ?Sized + Eq + Hash,
116 B: FnOnce(&Input) -> &T,
117 R: FnOnce(Input) -> Rc<T>,
124 impl<T: ?Sized + Eq + Hash> Interner<T> {
127 v: InternInput<Input, T, impl FnOnce(&Input) -> &T, impl FnOnce(Input) -> Rc<T>>,
134 match self.0.borrow_mut().raw_entry_mut().from_key(borrow(&input)) {
135 RawEntryMut::Occupied(entry) => Interned {
136 ptr: entry.key().clone(),
138 RawEntryMut::Vacant(entry) => Interned {
139 ptr: entry.insert(into_rc(input), ()).0.clone(),
145 pub trait InternTarget: Intern<Target = Self> + Hash + Eq {
146 fn get_interner(global_state: &GlobalState) -> &Interner<Self>;
147 fn into_interned(input: Self, global_state: &GlobalState) -> Interned<Self>
151 Self::get_interner(global_state).intern(InternInput {
157 fn rc_into_interned(input: Rc<Self>, global_state: &GlobalState) -> Interned<Self> {
158 Self::get_interner(global_state).intern(InternInput {
164 fn rc_to_interned(input: &Rc<Self>, global_state: &GlobalState) -> Interned<Self> {
165 Self::get_interner(global_state).intern(InternInput {
168 into_rc: |v| v.clone(),
173 impl InternTarget for str {
174 fn get_interner(global_state: &GlobalState) -> &Interner<Self> {
175 &global_state.interners.str
179 impl Intern for str {
182 fn to_rc_target(v: &Self) -> Rc<Self::Target> {
186 fn to_interned(&self, global_state: &GlobalState) -> Interned<Self::Target> {
187 Self::get_interner(global_state).intern(InternInput {
190 into_rc: Self::to_rc_target,
195 impl Intern for &'_ str {
198 fn to_rc_target(v: &Self) -> Rc<Self::Target> {
202 fn to_interned(&self, global_state: &GlobalState) -> Interned<Self::Target> {
203 Self::Target::to_interned(self, global_state)
206 fn into_interned(self, global_state: &GlobalState) -> Interned<Self::Target>
210 Self::Target::to_interned(self, global_state)
214 impl Intern for &'_ mut str {
217 fn to_rc_target(v: &Self) -> Rc<Self::Target> {
221 fn to_interned(&self, global_state: &GlobalState) -> Interned<Self::Target> {
222 Self::Target::to_interned(self, global_state)
225 fn into_interned(self, global_state: &GlobalState) -> Interned<Self::Target>
229 Self::Target::to_interned(self, global_state)
233 impl Intern for String {
236 fn to_rc_target(v: &Self) -> Rc<Self::Target> {
240 fn to_interned(&self, global_state: &GlobalState) -> Interned<Self::Target> {
241 Self::Target::to_interned(self, global_state)
244 fn into_rc_target(v: Self) -> Rc<Self::Target>
251 fn into_interned(self, global_state: &GlobalState) -> Interned<Self::Target>
255 Self::Target::to_interned(&self, global_state)
260 type Target: ?Sized + InternTarget;
261 fn into_rc_target(v: Self) -> Rc<Self::Target>
265 Self::to_rc_target(&v)
267 fn to_rc_target(v: &Self) -> Rc<Self::Target>;
268 fn into_interned(self, global_state: &GlobalState) -> Interned<Self::Target>
272 <<Self as Intern>::Target as InternTarget>::rc_into_interned(
273 Self::into_rc_target(self),
277 fn to_interned(&self, global_state: &GlobalState) -> Interned<Self::Target> {
278 Self::Target::rc_into_interned(Self::to_rc_target(self), global_state)
282 impl<T: ?Sized + InternTarget> Intern for Rc<T> {
285 fn to_rc_target(v: &Self) -> Rc<Self::Target> {
289 fn into_rc_target(v: Self) -> Rc<Self::Target>
297 impl<T: Clone + InternTarget> Intern for T {
300 fn to_rc_target(v: &Self) -> Rc<Self::Target> {
304 fn into_rc_target(v: Self) -> Rc<Self::Target>
311 fn into_interned(self, global_state: &GlobalState) -> Interned<Self::Target>
315 InternTarget::into_interned(self, global_state)
318 fn to_interned(&self, global_state: &GlobalState) -> Interned<Self::Target> {
319 InternTarget::get_interner(global_state).intern(InternInput {
322 into_rc: |v| v.clone().into(),
327 impl InternTarget for LocSet {
328 fn get_interner(global_state: &GlobalState) -> &Interner<Self> {
329 &global_state.interners.loc_set
333 impl InternTarget for LocSetMaxConflictsWith<Interned<LocSet>> {
334 fn get_interner(global_state: &GlobalState) -> &Interner<Self> {
335 &global_state.interners.loc_set_max_conflicts_with_loc_set
339 impl InternTarget for LocSetMaxConflictsWith<Loc> {
340 fn get_interner(global_state: &GlobalState) -> &Interner<Self> {
341 &global_state.interners.loc_set_max_conflicts_with_loc