3 loc_set::{LocSet, LocSetMaxConflictsWith},
6 hash_map::{Entry, RawEntryMut},
9 use serde::{de, Deserialize, Serialize};
19 pub struct Interned<T: ?Sized> {
23 impl<T: ?Sized> Deref for Interned<T> {
26 fn deref(&self) -> &Self::Target {
31 impl<T: ?Sized> Clone for Interned<T> {
32 fn clone(&self) -> Self {
34 ptr: self.ptr.clone(),
39 impl<T: ?Sized> Hash for Interned<T> {
40 fn hash<H: Hasher>(&self, state: &mut H) {
41 Rc::as_ptr(&self.ptr).hash(state);
45 impl<T: ?Sized> Eq for Interned<T> {}
47 impl<T: ?Sized + fmt::Debug> fmt::Debug for Interned<T> {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53 impl<T: ?Sized + fmt::Display> fmt::Display for Interned<T> {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59 pub struct SerdeState {
60 global_state: Rc<GlobalState>,
61 inner: SerdeStateInner,
64 scoped_tls::scoped_thread_local!(static SERDE_STATE: SerdeState);
67 pub fn global_state(&self) -> &Rc<GlobalState> {
71 pub fn scope<R>(global_state: &Rc<GlobalState>, f: impl FnOnce() -> R) -> R {
74 global_state: global_state.clone(),
75 inner: SerdeStateInner::default(),
80 pub fn get_or_scope<R>(f: impl for<'a> FnOnce(&'a SerdeState) -> R) -> R {
81 if SERDE_STATE.is_set() {
84 GlobalState::get(|global_state| Self::scope(global_state, || SERDE_STATE.with(f)))
89 pub struct SerdeStateFor<T: ?Sized> {
90 de: RefCell<Vec<Interned<T>>>,
91 ser: RefCell<HashMap<Interned<T>, usize>>,
94 impl<T: ?Sized> Default for SerdeStateFor<T> {
95 fn default() -> Self {
97 de: Default::default(),
98 ser: Default::default(),
103 #[derive(Serialize, Deserialize)]
104 enum SerializedInterned<T> {
109 impl<T: ?Sized + Serialize + InternTarget> Serialize for Interned<T> {
110 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
112 S: serde::Serializer,
114 SerdeState::get_or_scope(|serde_state| {
115 let mut state = T::get_serde_state_for(serde_state).ser.borrow_mut();
116 let next_index = state.len();
117 match state.entry(self.clone()) {
118 Entry::Occupied(entry) => SerializedInterned::Old(*entry.get()),
119 Entry::Vacant(entry) => {
120 entry.insert(next_index);
121 SerializedInterned::<&T>::New(self)
124 .serialize(serializer)
129 impl<'de, T, Owned> Deserialize<'de> for Interned<T>
131 T: ?Sized + InternTarget + ToOwned<Owned = Owned>,
132 Owned: Deserialize<'de> + Intern<Target = T>,
134 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
136 D: serde::Deserializer<'de>,
138 SerdeState::get_or_scope(|serde_state| {
139 let mut state = T::get_serde_state_for(serde_state).de.borrow_mut();
140 match SerializedInterned::<Owned>::deserialize(deserializer)? {
141 SerializedInterned::Old(index) => state
144 .ok_or_else(|| <D::Error as de::Error>::custom("index out of range")),
145 SerializedInterned::New(value) => {
146 let retval = value.into_interned(&serde_state.global_state);
147 state.push(retval.clone());
155 impl<T: ?Sized> PartialEq for Interned<T> {
156 fn eq(&self, other: &Interned<T>) -> bool {
157 Rc::ptr_eq(&self.ptr, &other.ptr)
161 impl<T: ?Sized> PartialOrd for Interned<T> {
162 fn partial_cmp(&self, other: &Interned<T>) -> Option<Ordering> {
163 Some(self.cmp(other))
167 impl<T: ?Sized> Ord for Interned<T> {
168 fn cmp(&self, other: &Interned<T>) -> Ordering {
169 Rc::as_ptr(&self.ptr).cmp(&Rc::as_ptr(&other.ptr))
173 macro_rules! make_interners {
176 $(#[$impl_intern_target:ident intern_target])?
182 $($name: Interner<$ty>,)*
186 struct SerdeStateInner {
187 $($name: SerdeStateFor<$ty>,)*
191 $impl_intern_target InternTarget for $ty {
192 fn get_interner(global_state: &GlobalState) -> &Interner<Self> {
193 &global_state.interners.$name
196 fn get_serde_state_for(serde_state: &SerdeState) -> &SerdeStateFor<Self> {
197 &serde_state.inner.$name
206 #[impl intern_target]
208 #[impl intern_target]
209 loc_set_max_conflicts_with_loc_set: LocSetMaxConflictsWith<Interned<LocSet>>,
210 #[impl intern_target]
211 loc_set_max_conflicts_with_loc: LocSetMaxConflictsWith<Loc>,
214 pub struct GlobalState {
215 interners: Interners,
218 scoped_tls::scoped_thread_local!(static GLOBAL_STATE: Rc<GlobalState>);
222 pub fn scope<R>(f: impl FnOnce() -> R) -> R {
224 &Rc::new(GlobalState {
225 interners: Interners::default(),
230 pub fn get<R>(f: impl for<'a> FnOnce(&'a Rc<GlobalState>) -> R) -> R {
235 pub struct Interner<T: ?Sized>(RefCell<HashMap<Rc<T>, ()>>);
237 impl<T: ?Sized> Default for Interner<T> {
238 fn default() -> Self {
239 Self(Default::default())
243 pub struct InternInput<
245 T: ?Sized + Eq + Hash,
246 B: FnOnce(&Input) -> &T,
247 R: FnOnce(Input) -> Rc<T>,
254 impl<T: ?Sized + Eq + Hash> Interner<T> {
257 v: InternInput<Input, T, impl FnOnce(&Input) -> &T, impl FnOnce(Input) -> Rc<T>>,
264 match self.0.borrow_mut().raw_entry_mut().from_key(borrow(&input)) {
265 RawEntryMut::Occupied(entry) => Interned {
266 ptr: entry.key().clone(),
268 RawEntryMut::Vacant(entry) => Interned {
269 ptr: entry.insert(into_rc(input), ()).0.clone(),
275 pub trait InternTarget: Intern<Target = Self> + Hash + Eq {
276 fn get_interner(global_state: &GlobalState) -> &Interner<Self>;
277 fn get_serde_state_for(serde_state: &SerdeState) -> &SerdeStateFor<Self>;
278 fn into_interned(input: Self, global_state: &GlobalState) -> Interned<Self>
282 Self::get_interner(global_state).intern(InternInput {
288 fn rc_into_interned(input: Rc<Self>, global_state: &GlobalState) -> Interned<Self> {
289 Self::get_interner(global_state).intern(InternInput {
295 fn rc_to_interned(input: &Rc<Self>, global_state: &GlobalState) -> Interned<Self> {
296 Self::get_interner(global_state).intern(InternInput {
299 into_rc: |v| v.clone(),
304 impl<'a, T: arbitrary::Arbitrary<'a> + InternTarget> arbitrary::Arbitrary<'a> for Interned<T> {
305 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
306 let retval: T = u.arbitrary()?;
307 Ok(GlobalState::get(|global_state| {
308 retval.into_interned(global_state)
313 impl InternTarget for str {
314 fn get_interner(global_state: &GlobalState) -> &Interner<Self> {
315 &global_state.interners.str
317 fn get_serde_state_for(serde_state: &SerdeState) -> &SerdeStateFor<Self> {
318 &serde_state.inner.str
322 impl Intern for str {
325 fn to_rc_target(v: &Self) -> Rc<Self::Target> {
329 fn to_interned(&self, global_state: &GlobalState) -> Interned<Self::Target> {
330 Self::get_interner(global_state).intern(InternInput {
333 into_rc: Self::to_rc_target,
338 impl Intern for &'_ str {
341 fn to_rc_target(v: &Self) -> Rc<Self::Target> {
345 fn to_interned(&self, global_state: &GlobalState) -> Interned<Self::Target> {
346 Self::Target::to_interned(self, global_state)
349 fn into_interned(self, global_state: &GlobalState) -> Interned<Self::Target>
353 Self::Target::to_interned(self, global_state)
357 impl Intern for &'_ mut str {
360 fn to_rc_target(v: &Self) -> Rc<Self::Target> {
364 fn to_interned(&self, global_state: &GlobalState) -> Interned<Self::Target> {
365 Self::Target::to_interned(self, global_state)
368 fn into_interned(self, global_state: &GlobalState) -> Interned<Self::Target>
372 Self::Target::to_interned(self, global_state)
376 impl Intern for String {
379 fn to_rc_target(v: &Self) -> Rc<Self::Target> {
383 fn to_interned(&self, global_state: &GlobalState) -> Interned<Self::Target> {
384 Self::Target::to_interned(self, global_state)
387 fn into_rc_target(v: Self) -> Rc<Self::Target>
394 fn into_interned(self, global_state: &GlobalState) -> Interned<Self::Target>
398 Self::Target::to_interned(&self, global_state)
403 type Target: ?Sized + InternTarget;
404 fn into_rc_target(v: Self) -> Rc<Self::Target>
408 Self::to_rc_target(&v)
410 fn to_rc_target(v: &Self) -> Rc<Self::Target>;
411 fn into_interned(self, global_state: &GlobalState) -> Interned<Self::Target>
415 <<Self as Intern>::Target as InternTarget>::rc_into_interned(
416 Self::into_rc_target(self),
420 fn to_interned(&self, global_state: &GlobalState) -> Interned<Self::Target> {
421 Self::Target::rc_into_interned(Self::to_rc_target(self), global_state)
425 impl<T: ?Sized + InternTarget> Intern for Rc<T> {
428 fn to_rc_target(v: &Self) -> Rc<Self::Target> {
432 fn into_rc_target(v: Self) -> Rc<Self::Target>
440 impl<T: Clone + InternTarget> Intern for T {
443 fn to_rc_target(v: &Self) -> Rc<Self::Target> {
447 fn into_rc_target(v: Self) -> Rc<Self::Target>
454 fn into_interned(self, global_state: &GlobalState) -> Interned<Self::Target>
458 InternTarget::into_interned(self, global_state)
461 fn to_interned(&self, global_state: &GlobalState) -> Interned<Self::Target> {
462 InternTarget::get_interner(global_state).intern(InternInput {
465 into_rc: |v| v.clone().into(),