spade_typeinference/
shared.rs

1use std::sync::{atomic::AtomicU64, RwLock};
2
3use serde::{Deserialize, Serialize};
4
5use crate::{equation::TypeVar, GenericLists, HashMap};
6
7#[derive(Serialize, Deserialize)]
8pub struct SharedTypeStateInner {
9    // List of the mapping between generic parameters and type vars.
10    // The key is the index of the expression for which this generic list is associated. (if this
11    // is a generic list for a call whose expression id is x to f<A, B>, then generic_lists[x] will
12    // be {A: <type var>, b: <type var>}
13    // Managed here because unification must update *all* TypeVars in existence.
14    generic_lists: GenericLists,
15
16    /// All types are referred to by their index to allow type vars changing inside
17    /// the type state while the types are "out in the wild". The TypeVarID is an index
18    /// into this type_vars list which is used to look up the actual type as currently
19    /// seen by the type state
20    type_vars: Vec<TypeVar>,
21}
22
23#[derive(Serialize, Deserialize)]
24pub struct SharedTypeState {
25    inner: RwLock<SharedTypeStateInner>,
26
27    // NOTE: This is kind of redundant, we could use TypeVarIDs instead of having dedicated
28    // numbers for unknown types.
29    pub next_typeid: AtomicU64,
30
31    pub next_annon_generic_list: AtomicU64,
32}
33
34impl SharedTypeState {
35    pub fn new() -> Self {
36        Self {
37            inner: RwLock::new(SharedTypeStateInner {
38                generic_lists: HashMap::new(),
39                type_vars: vec![],
40            }),
41            next_typeid: AtomicU64::new(0),
42            next_annon_generic_list: AtomicU64::new(0),
43        }
44    }
45
46    pub fn modify_type_vars<T, F: FnOnce(&mut Vec<TypeVar>) -> T>(&self, f: F) -> T {
47        (f)(&mut self.inner.write().unwrap().type_vars)
48    }
49
50    pub fn read_type_vars<T, F: FnOnce(&Vec<TypeVar>) -> T>(&self, f: F) -> T {
51        (f)(&self.inner.read().unwrap().type_vars)
52    }
53
54    pub fn modify_generic_lists<T, F: FnOnce(&mut GenericLists) -> T>(&self, f: F) -> T {
55        (f)(&mut self.inner.write().unwrap().generic_lists)
56    }
57
58    pub fn read_generic_lists<T, F: FnOnce(&GenericLists) -> T>(&self, f: F) -> T {
59        (f)(&self.inner.read().unwrap().generic_lists)
60    }
61}