1use std::fmt;
2use std::ops::Deref;
3use std::sync::Arc;
4
5use pretty::{DocAllocator, DocBuilder};
6
7use crate::ast::EmptyEnv;
8use crate::symbol::{Symbol, SymbolRef};
9use crate::types::{ToDoc, Walker};
10
11pub trait KindEnv {
13 fn find_kind(&self, type_name: &SymbolRef) -> Option<ArcKind>;
15}
16
17impl<'a, T: ?Sized + KindEnv> KindEnv for &'a T {
18 fn find_kind(&self, id: &SymbolRef) -> Option<ArcKind> {
19 (**self).find_kind(id)
20 }
21}
22
23impl KindEnv for EmptyEnv<Symbol> {
24 fn find_kind(&self, _id: &SymbolRef) -> Option<ArcKind> {
25 None
26 }
27}
28
29#[derive(Clone, Debug, Eq, PartialEq, Hash)]
37#[cfg_attr(feature = "serde_derive", derive(DeserializeState, SerializeState))]
38#[cfg_attr(
39 feature = "serde_derive",
40 serde(serialize_state = "crate::serialization::SeSeed")
41)]
42#[cfg_attr(feature = "serde_derive", serde(de_parameters = "S"))]
43#[cfg_attr(feature = "serde_derive", serde(deserialize_state = "S"))]
44#[cfg_attr(
45 feature = "serde_derive",
46 serde(bound(deserialize = "S: AsMut<crate::serialization::NodeMap>"))
47)]
48pub enum Kind {
49 Hole,
50 Error,
51 Variable(u32),
53 Type,
55 Row,
57 Function(
59 #[cfg_attr(feature = "serde_derive", serde(state))] ArcKind,
60 #[cfg_attr(feature = "serde_derive", serde(state))] ArcKind,
61 ),
62}
63
64impl Default for Kind {
65 fn default() -> Self {
66 Kind::Hole
67 }
68}
69
70impl Kind {
71 pub fn hole() -> ArcKind {
72 ArcKind::new(Kind::Hole)
73 }
74
75 pub fn error() -> ArcKind {
76 ArcKind::new(Kind::Error)
77 }
78
79 pub fn variable(v: u32) -> ArcKind {
80 ArcKind::new(Kind::Variable(v))
81 }
82
83 pub fn typ() -> ArcKind {
84 ArcKind::new(Kind::Type)
85 }
86
87 pub fn row() -> ArcKind {
88 ArcKind::new(Kind::Row)
89 }
90
91 pub fn function(l: ArcKind, r: ArcKind) -> ArcKind {
92 ArcKind::new(Kind::Function(l, r))
93 }
94}
95
96#[derive(PartialEq, Copy, Clone, PartialOrd)]
97enum Prec {
98 Top,
100 Function,
103}
104
105struct DisplayKind<'a>(Prec, &'a Kind);
106
107impl fmt::Display for Kind {
108 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
109 write!(f, "{}", DisplayKind(Prec::Top, self))
110 }
111}
112
113impl<'a, A, B, E> ToDoc<'a, A, B, E> for ArcKind {
114 fn to_doc(&'a self, allocator: &'a A, _: E) -> DocBuilder<'a, A, B>
115 where
116 A: DocAllocator<'a, B>,
117 {
118 allocator.text(self.to_string())
119 }
120}
121
122impl<'a> fmt::Display for DisplayKind<'a> {
123 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
124 match *self.1 {
125 Kind::Hole => "_".fmt(f),
126 Kind::Error => "!".fmt(f),
127 Kind::Variable(i) => i.fmt(f),
128 Kind::Type => "Type".fmt(f),
129 Kind::Row => "Row".fmt(f),
130 Kind::Function(ref arg, ref ret) => match self.0 {
131 Prec::Function => write!(f, "({} -> {})", DisplayKind(Prec::Function, arg), ret),
132 Prec::Top => write!(f, "{} -> {}", DisplayKind(Prec::Function, arg), ret),
133 },
134 }
135 }
136}
137
138#[derive(Clone, Default, Eq, PartialEq, Hash)]
140pub struct ArcKind(Arc<Kind>);
141
142#[cfg(feature = "serde")]
143impl<'de, S> crate::serde::de::DeserializeState<'de, S> for ArcKind
144where
145 S: AsMut<crate::serialization::NodeMap>,
146{
147 fn deserialize_state<D>(seed: &mut S, deserializer: D) -> Result<ArcKind, D::Error>
148 where
149 D: crate::serde::Deserializer<'de>,
150 {
151 use crate::serde::de::DeserializeSeed;
152 crate::serialization::SharedSeed::new(seed)
153 .deserialize(deserializer)
154 .map(ArcKind)
155 }
156}
157
158impl ArcKind {
159 pub fn new(kind: Kind) -> ArcKind {
160 ArcKind(Arc::new(kind))
161 }
162
163 pub fn make_mut(kind: &mut ArcKind) -> &mut Kind {
164 Arc::make_mut(&mut kind.0)
165 }
166
167 pub fn strong_count(kind: &ArcKind) -> usize {
168 Arc::strong_count(&kind.0)
169 }
170}
171
172impl Deref for ArcKind {
173 type Target = Kind;
174
175 fn deref(&self) -> &Kind {
176 &self.0
177 }
178}
179
180impl From<Kind> for ArcKind {
181 fn from(kind: Kind) -> ArcKind {
182 ArcKind(Arc::new(kind))
183 }
184}
185
186impl fmt::Debug for ArcKind {
187 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
188 self.0.fmt(f)
189 }
190}
191
192impl fmt::Display for ArcKind {
193 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
194 self.0.fmt(f)
195 }
196}
197
198type_cache! { KindCache() () { ArcKind, Kind } row hole error typ }
199
200impl<'a, F: ?Sized> Walker<'a, ArcKind> for F
201where
202 F: FnMut(&ArcKind),
203{
204 fn walk(&mut self, typ: &'a ArcKind) {
205 self(typ);
206 walk_kind(typ, self)
207 }
208}
209
210pub fn walk_kind<'a, F: ?Sized>(k: &'a ArcKind, f: &mut F)
211where
212 F: Walker<'a, ArcKind>,
213{
214 match **k {
215 Kind::Function(ref a, ref r) => {
216 f.walk(a);
217 f.walk(r);
218 }
219 Kind::Hole | Kind::Error | Kind::Variable(_) | Kind::Type | Kind::Row => (),
220 }
221}