1use std::{
2 borrow::{Borrow, Cow},
3 cell::RefCell,
4 cmp::Ordering,
5 fmt,
6 hash::{Hash, Hasher},
7 iter::FromIterator,
8 iter::{self, FusedIterator},
9 marker::PhantomData,
10 mem,
11 ops::{Deref, DerefMut},
12 rc::Rc,
13 sync::Arc,
14};
15
16use {
17 itertools::Itertools,
18 pretty::{Arena, Doc, DocAllocator, DocBuilder},
19 smallvec::SmallVec,
20};
21
22use gluon_codegen::AstClone;
23
24use crate::{
25 ast::{AstClone, EmptyEnv, HasMetadata, IdentEnv},
26 fnv::FnvMap,
27 kind::{ArcKind, Kind, KindCache, KindEnv},
28 merge::{merge, merge_collect},
29 metadata::Metadata,
30 pos::{BytePos, HasSpan, Span, Spanned},
31 source::Source,
32 symbol::{Name, Symbol, SymbolRef},
33};
34
35#[cfg(feature = "serde")]
36use crate::{
37 serde::{de::DeserializeState, ser::SerializeState},
38 serialization::{SeSeed, Seed},
39};
40
41use self::pretty_print::Printer;
42pub use self::{
43 flags::Flags,
44 pretty_print::{Filter, TypeFormatter},
45};
46pub use crate::ast::KindedIdent;
47
48mod flags;
49pub mod pretty_print;
50
51macro_rules! forward_eq_hash {
52 (<$($param: ident),*> for $typ: ty { $field: ident }) => {
53 impl<$($param),*> Eq for $typ where $($param : Eq),* {}
54
55 impl<$($param),*> PartialEq for $typ
56 where $($param : PartialEq),*
57 {
58 fn eq(&self, other: &Self) -> bool {
59 self.$field == other.$field
60 }
61 }
62
63 impl<$($param),*> Hash for $typ
64 where $($param : Hash),*
65 {
66 fn hash<H>(&self, state: &mut H)
67 where
68 H: std::hash::Hasher,
69 {
70 self.$field.hash(state)
71 }
72 }
73 }
74}
75
76pub trait AsId<Id>
77where
78 Id: ?Sized,
79{
80 fn as_id(&self) -> &Id;
81}
82
83impl<Id> AsId<Id> for Id
84where
85 Id: ?Sized,
86{
87 fn as_id(&self) -> &Id {
88 self
89 }
90}
91
92impl<T, Pos> AsId<T> for Spanned<T, Pos> {
93 fn as_id(&self) -> &T {
94 &self.value
95 }
96}
97
98pub trait TypeEnv: KindEnv {
100 type Type;
101 fn find_type(&self, id: &SymbolRef) -> Option<Self::Type>;
103
104 fn find_type_info(&self, id: &SymbolRef) -> Option<Alias<Symbol, Self::Type>>;
106}
107
108impl<'a, T: ?Sized + TypeEnv> TypeEnv for &'a T {
109 type Type = T::Type;
110
111 fn find_type(&self, id: &SymbolRef) -> Option<Self::Type> {
112 (**self).find_type(id)
113 }
114
115 fn find_type_info(&self, id: &SymbolRef) -> Option<Alias<Symbol, Self::Type>> {
116 (**self).find_type_info(id)
117 }
118}
119
120impl TypeEnv for EmptyEnv<Symbol> {
121 type Type = ArcType;
122
123 fn find_type(&self, _id: &SymbolRef) -> Option<ArcType> {
124 None
125 }
126
127 fn find_type_info(&self, _id: &SymbolRef) -> Option<Alias<Symbol, ArcType>> {
128 None
129 }
130}
131
132pub trait PrimitiveEnv: TypeEnv {
135 fn get_bool(&self) -> ArcType;
136}
137
138impl<'a, T: ?Sized + PrimitiveEnv> PrimitiveEnv for &'a T {
139 fn get_bool(&self) -> ArcType {
140 (**self).get_bool()
141 }
142}
143
144type_cache! {
145 TypeCache(Id, T)
146 where [T: TypeExt<Id = Id>, T::Types: Default + Extend<T>,]
147 (kind_cache: crate::kind::KindCache)
148 { T, Type }
149 hole opaque error int byte float string char
150 function_builtin array_builtin unit empty_row
151}
152
153impl<Id, T> TypeCache<Id, T>
154where
155 T: TypeExt<Id = Id> + From<Type<Id, T>> + Clone,
156 T::Types: Default + Extend<T>,
157{
158 pub fn function<I>(&self, args: I, ret: T) -> T
159 where
160 I: IntoIterator<Item = T>,
161 I::IntoIter: DoubleEndedIterator<Item = T>,
162 {
163 args.into_iter().rev().fold(ret, |body, arg| {
164 T::from(Type::Function(ArgType::Explicit, arg, body))
165 })
166 }
167
168 pub fn function_implicit<I>(&self, args: I, ret: T) -> T
169 where
170 I: IntoIterator<Item = T>,
171 I::IntoIter: DoubleEndedIterator<Item = T>,
172 {
173 args.into_iter().rev().fold(ret, |body, arg| {
174 T::from(Type::Function(ArgType::Implicit, arg, body))
175 })
176 }
177
178 pub fn tuple<S, I>(&self, symbols: &mut S, elems: I) -> T
179 where
180 S: ?Sized + IdentEnv<Ident = Id>,
181 T::SpannedId: From<Id>,
182 I: IntoIterator<Item = T>,
183 {
184 let fields: Vec<_> = elems
185 .into_iter()
186 .enumerate()
187 .map(|(i, typ)| Field {
188 name: symbols.from_str(&format!("_{}", i)).into(),
189 typ,
190 })
191 .collect();
192 if fields.is_empty() {
193 self.unit()
194 } else {
195 self.record(vec![], fields)
196 }
197 }
198
199 pub fn variant(&self, fields: Vec<Field<T::SpannedId, T>>) -> T {
200 self.poly_variant(fields, self.empty_row())
201 }
202
203 pub fn poly_variant(&self, fields: Vec<Field<T::SpannedId, T>>, rest: T) -> T {
204 Type::poly_variant(fields, rest)
205 }
206
207 pub fn record(
208 &self,
209 types: Vec<Field<T::SpannedId, Alias<Id, T>>>,
210 fields: Vec<Field<T::SpannedId, T>>,
211 ) -> T {
212 Type::poly_record(types, fields, self.empty_row())
213 }
214
215 pub fn effect(&self, fields: Vec<Field<T::SpannedId, T>>) -> T {
216 self.poly_effect(fields, self.empty_row())
217 }
218
219 pub fn poly_effect(&self, fields: Vec<Field<T::SpannedId, T>>, rest: T) -> T {
220 Type::poly_effect(fields, rest)
221 }
222
223 pub fn array(&self, typ: T) -> T {
224 Type::app(self.array_builtin(), collect![typ])
225 }
226}
227
228impl<Id, T> TypeCache<Id, T>
229where
230 T: TypeExt<Id = Id> + Clone,
231 T::Types: Default + Extend<T> + FromIterator<T>,
232{
233 pub fn builtin_type(&self, typ: BuiltinType) -> T {
234 match typ {
235 BuiltinType::String => self.string(),
236 BuiltinType::Byte => self.byte(),
237 BuiltinType::Char => self.char(),
238 BuiltinType::Int => self.int(),
239 BuiltinType::Float => self.float(),
240 BuiltinType::Array => self.array_builtin(),
241 BuiltinType::Function => self.function_builtin(),
242 }
243 }
244}
245
246#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
248#[cfg_attr(feature = "serde_derive", derive(Deserialize, Serialize))]
249pub enum BuiltinType {
250 String,
252 Byte,
254 Char,
256 Int,
258 Float,
260 Array,
262 Function,
264}
265
266impl BuiltinType {
267 pub fn symbol(self) -> &'static SymbolRef {
268 SymbolRef::new(self.to_str())
269 }
270}
271
272impl ::std::str::FromStr for BuiltinType {
273 type Err = ();
274 fn from_str(x: &str) -> Result<BuiltinType, ()> {
275 let t = match x {
276 "Int" => BuiltinType::Int,
277 "Byte" => BuiltinType::Byte,
278 "Float" => BuiltinType::Float,
279 "String" => BuiltinType::String,
280 "Char" => BuiltinType::Char,
281 "Array" => BuiltinType::Array,
282 "->" => BuiltinType::Function,
283 _ => return Err(()),
284 };
285 Ok(t)
286 }
287}
288
289impl BuiltinType {
290 pub fn to_str(self) -> &'static str {
291 match self {
292 BuiltinType::String => "String",
293 BuiltinType::Byte => "Byte",
294 BuiltinType::Char => "Char",
295 BuiltinType::Int => "Int",
296 BuiltinType::Float => "Float",
297 BuiltinType::Array => "Array",
298 BuiltinType::Function => "->",
299 }
300 }
301}
302
303#[derive(Clone, Debug)]
304#[cfg_attr(feature = "serde_derive", derive(DeserializeState, SerializeState))]
305#[cfg_attr(feature = "serde_derive", serde(serialize_state = "SeSeed"))]
306#[cfg_attr(feature = "serde_derive", serde(deserialize_state = "Seed<Id, T>"))]
307#[cfg_attr(feature = "serde_derive", serde(de_parameters = "Id, T"))]
308pub struct TypeVariable {
309 #[cfg_attr(feature = "serde_derive", serde(state))]
310 pub kind: ArcKind,
311 pub id: u32,
312}
313
314forward_eq_hash! { <> for TypeVariable { id } }
315
316#[derive(Clone, Debug, AstClone)]
317#[cfg_attr(feature = "serde_derive", derive(DeserializeState, SerializeState))]
318#[cfg_attr(feature = "serde_derive", serde(deserialize_state = "Seed<Id, T>"))]
319#[cfg_attr(
320 feature = "serde_derive",
321 serde(bound(deserialize = "
322 Id: DeserializeState<'de, Seed<Id, T>> + Clone + ::std::any::Any"))
323)]
324#[cfg_attr(feature = "serde_derive", serde(de_parameters = "T"))]
325#[cfg_attr(feature = "serde_derive", serde(serialize_state = "SeSeed"))]
326#[cfg_attr(
327 feature = "serde_derive",
328 serde(bound(serialize = "Id: SerializeState<SeSeed>"))
329)]
330pub struct Skolem<Id> {
331 #[cfg_attr(feature = "serde_derive", serde(state))]
332 pub name: Id,
333 pub id: u32,
334 #[cfg_attr(feature = "serde_derive", serde(state))]
335 pub kind: ArcKind,
336}
337
338forward_eq_hash! { <Id> for Skolem<Id> { id } }
339
340#[derive(Clone, Debug, Eq, PartialEq, Hash, AstClone)]
343#[cfg_attr(feature = "serde_derive", derive(DeserializeState, SerializeState))]
344#[cfg_attr(feature = "serde_derive", serde(deserialize_state = "Seed<Id, T>"))]
345#[cfg_attr(
346 feature = "serde_derive",
347 serde(bound(deserialize = "
348 Id: DeserializeState<'de, Seed<Id, T>> + Clone + ::std::any::Any"))
349)]
350#[cfg_attr(feature = "serde_derive", serde(de_parameters = "T"))]
351#[cfg_attr(feature = "serde_derive", serde(serialize_state = "SeSeed"))]
352#[cfg_attr(
353 feature = "serde_derive",
354 serde(bound(serialize = "Id: SerializeState<SeSeed>"))
355)]
356pub struct Generic<Id> {
357 #[cfg_attr(feature = "serde_derive", serde(state))]
358 pub id: Id,
359 #[cfg_attr(feature = "serde_derive", serde(state))]
360 pub kind: ArcKind,
361}
362
363impl<Id> Generic<Id> {
364 pub fn new(id: Id, kind: ArcKind) -> Generic<Id> {
365 Generic { id, kind }
366 }
367}
368
369#[derive(Clone, Debug, Eq, PartialEq, Hash, AstClone)]
372#[cfg_attr(feature = "serde_derive", derive(DeserializeState, SerializeState))]
373#[cfg_attr(feature = "serde_derive", serde(deserialize_state = "Seed<Id, T>"))]
374#[cfg_attr(
375 feature = "serde_derive",
376 serde(bound(deserialize = "
377 T: DeserializeState<'de, Seed<Id, T>> + TypePtr<Id = Id> + Clone + From<Type<Id, T>> + ::std::any::Any,
378 Id: DeserializeState<'de, Seed<Id, T>> + Clone + ::std::any::Any"))
379)]
380#[cfg_attr(feature = "serde_derive", serde(serialize_state = "SeSeed"))]
381#[cfg_attr(
382 feature = "serde_derive",
383 serde(bound(serialize = "T: SerializeState<SeSeed> + TypePtr<Id = Id>"))
384)]
385pub struct Alias<Id, T> {
386 #[cfg_attr(feature = "serde_derive", serde(state))]
387 _typ: T,
388 #[cfg_attr(feature = "serde_derive", serde(skip))]
389 _marker: PhantomData<Id>,
390}
391
392impl<Id, T> Deref for Alias<Id, T>
393where
394 T: TypePtr<Id = Id>,
395{
396 type Target = AliasRef<Id, T>;
397
398 fn deref(&self) -> &Self::Target {
399 match *self._typ {
400 Type::Alias(ref alias) => alias,
401 _ => unreachable!(),
402 }
403 }
404}
405
406impl<Id, T> DerefMut for Alias<Id, T>
407where
408 T: TypePtr<Id = Id> + DerefMut<Target = Type<Id, T>>,
409{
410 fn deref_mut(&mut self) -> &mut Self::Target {
411 match *self._typ {
412 Type::Alias(ref mut alias) => alias,
413 _ => unreachable!(),
414 }
415 }
416}
417
418impl<Id, T> From<AliasData<Id, T>> for Alias<Id, T>
419where
420 T: TypeExt<Id = Id> + From<Type<Id, T>>,
421 T::Types: Clone + Default + Extend<T>,
422{
423 fn from(data: AliasData<Id, T>) -> Alias<Id, T> {
424 Alias {
425 _typ: Type::alias(data.name, data.args, data.typ),
426 _marker: PhantomData,
427 }
428 }
429}
430
431impl<Id, T> From<AliasRef<Id, T>> for Alias<Id, T>
432where
433 T: TypePtr<Id = Id> + From<Type<Id, T>>,
434{
435 fn from(data: AliasRef<Id, T>) -> Alias<Id, T> {
436 Alias {
437 _typ: Type::Alias(data).into(),
438 _marker: PhantomData,
439 }
440 }
441}
442
443impl<Id, T> AsRef<T> for Alias<Id, T> {
444 fn as_ref(&self) -> &T {
445 &self._typ
446 }
447}
448
449impl<Id, T> Alias<Id, T>
450where
451 T: TypePtr<Id = Id>,
452{
453 pub fn new_with(
454 context: &mut (impl TypeContext<Id, T> + ?Sized),
455 name: Id,
456 args: T::Generics,
457 typ: T,
458 ) -> Self {
459 Alias {
460 _typ: context.alias(name, args, typ),
461 _marker: PhantomData,
462 }
463 }
464}
465
466impl<Id, T> Alias<Id, T>
467where
468 T: TypeExt<Id = Id> + From<Type<Id, T>>,
469 T::Types: Clone + Default + Extend<T>,
470{
471 pub fn new(name: Id, args: T::Generics, typ: T) -> Alias<Id, T> {
472 Alias {
473 _typ: Type::alias(name, args, typ),
474 _marker: PhantomData,
475 }
476 }
477
478 pub fn group(group: Vec<AliasData<Id, T>>) -> Vec<Alias<Id, T>> {
479 let group = Arc::<[_]>::from(group);
480 (0..group.len())
481 .map(|index| Alias {
482 _typ: T::from(Type::Alias(AliasRef {
483 index,
484 group: group.clone(),
485 })),
486 _marker: PhantomData,
487 })
488 .collect()
489 }
490}
491
492impl<Id, T> Alias<Id, T> {
493 pub fn as_type(&self) -> &T {
494 &self._typ
495 }
496
497 pub fn into_type(self) -> T {
498 self._typ
499 }
500}
501
502impl<Id, T> Alias<Id, T>
503where
504 T: TypeExt<Id = Id> + Clone,
505 T::Types: Clone + Default + Extend<T>,
506 T::Generics: Clone,
507 T::Fields: Clone,
508 Id: Clone + PartialEq,
509 T::SpannedId: Clone + PartialEq,
510{
511 pub fn typ(&self, interner: &mut impl TypeContext<Id, T>) -> Cow<T> {
513 match *self._typ {
514 Type::Alias(ref alias) => alias.typ(interner),
515 _ => unreachable!(),
516 }
517 }
518
519 pub fn unpack_canonical_alias<'b>(
520 &'b self,
521 canonical_alias_type: &'b T,
522 mut un_alias: impl FnMut(&'b AliasRef<Id, T>) -> Cow<'b, T>,
523 ) -> (Cow<'b, [Generic<Id>]>, &'b AliasRef<Id, T>, Cow<'b, T>) {
524 match **canonical_alias_type {
525 Type::App(ref func, _) => match **func {
526 Type::Alias(ref alias) => (Cow::Borrowed(&[]), alias, un_alias(alias)),
527 _ => (Cow::Borrowed(&[]), &**self, Cow::Borrowed(func)),
528 },
529 Type::Alias(ref alias) => (Cow::Borrowed(&[]), alias, un_alias(alias)),
530 Type::Forall(ref params, ref typ) => {
531 let mut params = Cow::Borrowed(¶ms[..]);
532 let (more_params, canonical_alias, inner_type) =
533 self.unpack_canonical_alias(typ, un_alias);
534 if !more_params.is_empty() {
535 params.to_mut().extend(more_params.iter().cloned());
536 }
537 (params, canonical_alias, inner_type)
538 }
539 _ => (
540 Cow::Borrowed(&[]),
541 &**self,
542 Cow::Borrowed(canonical_alias_type),
543 ),
544 }
545 }
546}
547
548#[derive(Clone, AstClone)]
551#[cfg_attr(feature = "serde_derive", derive(DeserializeState, SerializeState))]
552#[cfg_attr(feature = "serde_derive", serde(deserialize_state = "Seed<Id, T>"))]
553#[cfg_attr(
554 feature = "serde_derive",
555 serde(bound(
556 deserialize = "
557 T: DeserializeState<'de, Seed<Id, T>> + TypePtr<Id = Id> + Clone + From<Type<Id, T>> + ::std::any::Any,
558 Id: DeserializeState<'de, Seed<Id, T>> + Clone + ::std::any::Any,
559 T::Generics: Default + Extend<Generic<Id>> + Clone,
560 ",
561 serialize = "
562 T: TypePtr<Id = Id> + SerializeState<SeSeed>,
563 Id: SerializeState<SeSeed>,
564 "
565 ))
566)]
567#[cfg_attr(feature = "serde_derive", serde(serialize_state = "SeSeed"))]
568#[gluon(ast_clone_bounds = "T::Generics: AstClone<'ast, Id>")]
569pub struct AliasRef<Id, T>
570where
571 T: TypePtr<Id = Id>,
572{
573 index: usize,
575 #[cfg_attr(
576 feature = "serde_derive",
577 serde(deserialize_state_with = "crate::serialization::deserialize_group")
578 )]
579 #[cfg_attr(
580 feature = "serde_derive",
581 serde(serialize_state_with = "crate::serialization::shared::serialize")
582 )]
583 pub group: Arc<[AliasData<Id, T>]>,
585}
586
587impl<Id, T> fmt::Debug for AliasRef<Id, T>
588where
589 Id: fmt::Debug,
590 T: TypePtr<Id = Id> + fmt::Debug,
591 AliasData<Id, T>: fmt::Debug,
592{
593 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
594 (**self).fmt(f)
595 }
596}
597
598impl<Id, T> Eq for AliasRef<Id, T>
599where
600 T: TypePtr<Id = Id>,
601 AliasData<Id, T>: Eq,
602{
603}
604impl<Id, T> PartialEq for AliasRef<Id, T>
605where
606 T: TypePtr<Id = Id>,
607 AliasData<Id, T>: PartialEq,
608{
609 fn eq(&self, other: &Self) -> bool {
610 **self == **other
611 }
612}
613impl<Id, T> Hash for AliasRef<Id, T>
614where
615 T: TypePtr<Id = Id>,
616 AliasData<Id, T>: Hash,
617{
618 fn hash<H>(&self, state: &mut H)
619 where
620 H: std::hash::Hasher,
621 {
622 (**self).hash(state)
623 }
624}
625
626impl<Id, T> AliasRef<Id, T>
627where
628 T: TypePtr<Id = Id>,
629{
630 pub fn try_get_alias_mut(&mut self) -> Option<&mut AliasData<Id, T>> {
631 let index = self.index;
632 Arc::get_mut(&mut self.group).map(|group| &mut group[index])
633 }
634 pub(crate) fn try_get_alias(&self) -> Option<&AliasData<Id, T>> {
635 let index = self.index;
636 Some(&self.group[index])
637 }
638
639 #[doc(hidden)]
640 pub fn new(index: usize, group: Arc<[AliasData<Id, T>]>) -> Self {
641 AliasRef { index, group }
642 }
643
644 #[doc(hidden)]
645 pub fn index(&self) -> usize {
646 self.index
647 }
648}
649
650impl<Id, T> AliasRef<Id, T>
651where
652 T: TypeExt<Id = Id> + Clone,
653 T::Types: Clone + Default + Extend<T>,
654 T::Generics: Clone,
655 T::Fields: Clone,
656 Id: Clone + PartialEq,
657 T::SpannedId: Clone + PartialEq,
658{
659 pub fn typ(&self, interner: &mut impl TypeContext<Id, T>) -> Cow<T> {
660 match self.typ_(interner, &self.typ) {
661 Some(typ) => Cow::Owned(typ),
662 None => Cow::Borrowed(&self.typ),
663 }
664 }
665
666 fn typ_(&self, interner: &mut impl TypeContext<Id, T>, typ: &T) -> Option<T> {
667 if !typ.flags().intersects(Flags::HAS_IDENTS) {
668 return None;
669 }
670 match **typ {
671 Type::Ident(ref id) => {
672 let replacement = self
675 .group
676 .iter()
677 .position(|alias| alias.name == id.name)
678 .map(|index| {
679 interner.intern(Type::Alias(AliasRef {
680 index,
681 group: self.group.clone(),
682 }))
683 });
684 if replacement.is_none() {
685 info!("Alias group were not able to resolve an identifier");
686 }
687 replacement
688 }
689 _ => walk_move_type_opt(
690 typ,
691 &mut InternerVisitor::control(interner, |interner, typ: &T| {
692 self.typ_(interner, typ)
693 }),
694 ),
695 }
696 }
697}
698
699#[derive(Clone, Debug, Eq, PartialEq, Hash, AstClone)]
700#[cfg_attr(feature = "serde_derive", derive(DeserializeState, SerializeState))]
701#[cfg_attr(feature = "serde_derive", serde(deserialize_state = "Seed<Id, T>"))]
702#[cfg_attr(
703 feature = "serde_derive",
704 serde(bound(deserialize = "
705 T: TypePtr<Id = Id> + Clone + From<Type<Id, T>> + ::std::any::Any + DeserializeState<'de, Seed<Id, T>>,
706 T::Generics: Default + Extend<Generic<Id>>,
707 Id: DeserializeState<'de, Seed<Id, T>> + Clone + ::std::any::Any"))
708)]
709#[cfg_attr(feature = "serde_derive", serde(serialize_state = "SeSeed"))]
710#[cfg_attr(
711 feature = "serde_derive",
712 serde(bound(serialize = "
713 T: TypePtr<Id = Id> + SerializeState<SeSeed>,
714 Id: SerializeState<SeSeed>,
715 "))
716)]
717#[gluon(ast_clone_bounds = "T::Generics: AstClone<'ast, Id>")]
718pub struct AliasData<Id, T: TypePtr<Id = Id>> {
719 #[cfg_attr(feature = "serde_derive", serde(state))]
720 pub name: Id,
721 #[cfg_attr(
722 feature = "serde_derive",
723 serde(state_with = "crate::serialization::seq")
724 )]
725 args: T::Generics,
726 #[cfg_attr(feature = "serde_derive", serde(state))]
728 typ: T,
729 pub is_implicit: bool,
730}
731
732impl<Id, T> AliasData<Id, T>
733where
734 T: TypePtr<Id = Id>,
735{
736 pub fn unresolved_type(&self) -> &T {
739 &self.typ
740 }
741
742 pub fn unresolved_type_mut(&mut self) -> &mut T {
743 &mut self.typ
744 }
745
746 pub fn is_implicit(&self) -> bool {
747 self.is_implicit
748 }
749}
750
751impl<Id, T> AliasData<Id, T>
752where
753 T: TypePtr<Id = Id>,
754 Id: Clone,
755{
756 pub fn self_type(&self, context: &mut (impl TypeContext<Id, T> + ?Sized)) -> T {
757 let f = context.ident(KindedIdent {
758 name: self.name.clone(),
759 typ: self.typ.kind(&Default::default()).into_owned(),
760 });
761 let args = self
762 .params()
763 .iter()
764 .cloned()
765 .map(|g| context.generic(g))
766 .collect::<SmallVec<[_; 5]>>();
767 let args = context.intern_types(args);
768 context.app(f, args)
769 }
770}
771
772impl<Id, T> AliasData<Id, T>
773where
774 T: TypePtr<Id = Id>,
775{
776 pub fn new(name: Id, args: T::Generics, typ: T) -> AliasData<Id, T> {
777 AliasData {
778 name,
779 args,
780 typ,
781 is_implicit: false,
782 }
783 }
784}
785
786impl<Id, T> AliasData<Id, T>
787where
788 T: TypePtr<Id = Id>,
789{
790 pub fn params(&self) -> &[Generic<Id>] {
791 &self.args
792 }
793
794 pub fn params_mut(&mut self) -> &mut [Generic<Id>]
795 where
796 T::Generics: DerefMut<Target = [Generic<Id>]>,
797 {
798 &mut self.args
799 }
800
801 pub fn aliased_type(&self) -> &T {
802 &self.typ
803 }
804
805 pub fn kind<'k>(&'k self, cache: &'k KindCache) -> Cow<'k, ArcKind> {
806 let result_type = self.unresolved_type().kind(cache);
807 self.params().iter().rev().fold(result_type, |acc, param| {
808 Cow::Owned(Kind::function(param.kind.clone(), acc.into_owned()))
809 })
810 }
811}
812
813impl<Id, T> Deref for AliasRef<Id, T>
814where
815 T: TypePtr<Id = Id>,
816{
817 type Target = AliasData<Id, T>;
818
819 fn deref(&self) -> &Self::Target {
820 &self.group[self.index]
821 }
822}
823
824#[derive(Clone, Hash, Eq, PartialEq, Debug, AstClone)]
825#[cfg_attr(feature = "serde_derive", derive(DeserializeState, SerializeState))]
826#[cfg_attr(
827 feature = "serde_derive",
828 serde(deserialize_state = "Seed<FieldId, U>")
829)]
830#[cfg_attr(feature = "serde_derive", serde(de_parameters = "U"))]
831#[cfg_attr(
832 feature = "serde_derive",
833 serde(bound(deserialize = "
834 FieldId: DeserializeState<'de, Seed<FieldId, U>> + Clone + ::std::any::Any,
835 T: DeserializeState<'de, Seed<FieldId, U>>
836 "))
837)]
838#[cfg_attr(feature = "serde_derive", serde(serialize_state = "SeSeed"))]
839#[cfg_attr(
840 feature = "serde_derive",
841 serde(bound(serialize = "T: SerializeState<SeSeed>, FieldId: SerializeState<SeSeed>"))
842)]
843pub struct Field<FieldId, T = ArcType<FieldId>> {
844 #[cfg_attr(feature = "serde_derive", serde(state))]
845 pub name: FieldId,
846 #[cfg_attr(feature = "serde_derive", serde(state))]
847 pub typ: T,
848}
849
850pub type AppVec<T> = SmallVec<[T; 2]>;
855
856impl<SpId, T> Field<SpId, T> {
857 pub fn new(name: SpId, typ: T) -> Self {
858 Field { name, typ }
859 }
860
861 pub fn ctor_with<J, Id>(
862 context: &mut (impl TypeContext<Id, T> + ?Sized),
863 ctor_name: SpId,
864 elems: J,
865 ) -> Self
866 where
867 J: IntoIterator<Item = T>,
868 J::IntoIter: DoubleEndedIterator,
869 T: TypePtr<Id = Id>,
870 {
871 let opaque = context.opaque();
872 let typ = context.function_type(ArgType::Constructor, elems, opaque);
873 Field {
874 name: ctor_name,
875 typ,
876 }
877 }
878
879 pub fn ctor<J, Id>(ctor_name: SpId, elems: J) -> Self
880 where
881 J: IntoIterator<Item = T>,
882 J::IntoIter: DoubleEndedIterator,
883 T: TypeExt<Id = Id> + From<Type<Id, T>>,
884 T::Types: Default + Extend<T>,
885 {
886 let typ = Type::function_type(ArgType::Constructor, elems, Type::opaque());
887 Field {
888 name: ctor_name,
889 typ,
890 }
891 }
892}
893
894#[cfg_attr(feature = "serde_derive", derive(Deserialize, Serialize))]
895#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
896pub enum ArgType {
897 Explicit,
898 Implicit,
899 Constructor,
900}
901
902impl Default for ArgType {
903 fn default() -> Self {
904 Self::Explicit
905 }
906}
907
908#[derive(Clone, Debug, Eq, PartialEq, Hash, AstClone)]
915#[cfg_attr(feature = "serde_derive", derive(DeserializeState, SerializeState))]
916#[cfg_attr(feature = "serde_derive", serde(deserialize_state = "Seed<Id, T>"))]
917#[cfg_attr(
918 feature = "serde_derive",
919 serde(bound(
920 deserialize = "
921 T: Clone
922 + TypePtr<Id = Id>
923 + From<Type<Id, T>>
924 + std::any::Any
925 + DeserializeState<'de, Seed<Id, T>>,
926 T::Types: Default + Extend<T>,
927 T::Generics: Default + Extend<Generic<Id>> + Clone,
928 T::Fields: DeserializeState<'de, Seed<Id, T>>,
929 T::TypeFields: DeserializeState<'de, Seed<Id, T>>,
930 Id: DeserializeState<'de, Seed<Id, T>>
931 + Clone
932 + std::any::Any,
933 ",
934 serialize = "
935 T: TypePtr<Id = Id> + SerializeState<SeSeed>,
936 Id: SerializeState<SeSeed>,
937 T::Fields: SerializeState<SeSeed>,
938 T::TypeFields: SerializeState<SeSeed>,
939 "
940 ))
941)]
942#[cfg_attr(feature = "serde_derive", serde(serialize_state = "SeSeed"))]
943#[gluon(ast_clone_bounds = "T::Generics: AstClone<'ast, Id>,
944 T::Types: AstClone<'ast, Id>,
945 T::Fields: AstClone<'ast, Id>,
946 T::TypeFields: AstClone<'ast, Id>")]
947pub enum Type<Id, T: TypePtr<Id = Id> = ArcType<Id>> {
948 Hole,
950 Opaque,
952 Error,
954 Builtin(BuiltinType),
956 Forall(
958 #[cfg_attr(
959 feature = "serde_derive",
960 serde(state_with = "crate::serialization::seq")
961 )]
962 T::Generics,
963 #[cfg_attr(feature = "serde_derive", serde(state))] T,
964 ),
965 App(
968 #[cfg_attr(feature = "serde_derive", serde(state))] T,
969 #[cfg_attr(
970 feature = "serde_derive",
971 serde(state_with = "crate::serialization::seq")
972 )]
973 T::Types,
974 ),
975 Function(
977 ArgType,
978 #[cfg_attr(feature = "serde_derive", serde(state))] T,
979 #[cfg_attr(feature = "serde_derive", serde(state))] T,
980 ),
981 Record(#[cfg_attr(feature = "serde_derive", serde(state))] T),
983 Variant(#[cfg_attr(feature = "serde_derive", serde(state))] T),
985 Effect(#[cfg_attr(feature = "serde_derive", serde(state))] T),
987 EmptyRow,
989 ExtendRow {
991 #[cfg_attr(feature = "serde_derive", serde(state))]
993 fields: T::Fields,
994 #[cfg_attr(feature = "serde_derive", serde(state))]
996 rest: T,
997 },
998 ExtendTypeRow {
1000 #[cfg_attr(feature = "serde_derive", serde(state))]
1002 types: T::TypeFields,
1003 #[cfg_attr(feature = "serde_derive", serde(state))]
1005 rest: T,
1006 },
1007 Ident(#[cfg_attr(feature = "serde_derive", serde(state))] KindedIdent<Id>),
1014 Projection(
1015 #[cfg_attr(
1016 feature = "serde_derive",
1017 serde(state_with = "crate::serialization::seq")
1018 )]
1019 AppVec<Id>,
1020 ),
1021 Variable(#[cfg_attr(feature = "serde_derive", serde(state))] TypeVariable),
1024 Generic(#[cfg_attr(feature = "serde_derive", serde(state))] Generic<Id>),
1027 Alias(#[cfg_attr(feature = "serde_derive", serde(state))] AliasRef<Id, T>),
1028 Skolem(#[cfg_attr(feature = "serde_derive", serde(state))] Skolem<Id>),
1029}
1030
1031impl<Id, T> Default for Type<Id, T>
1032where
1033 T: TypePtr<Id = Id>,
1034{
1035 fn default() -> Self {
1036 Type::Hole
1037 }
1038}
1039
1040impl<Id, T> Type<Id, T>
1041where
1042 T: TypePtr<Id = Id>,
1043{
1044 pub fn as_variable(&self) -> Option<&TypeVariable> {
1045 match *self {
1046 Type::Variable(ref var) => Some(var),
1047 _ => None,
1048 }
1049 }
1050}
1051
1052impl<Id, T> Type<Id, T>
1053where
1054 T: From<Type<Id, T>> + TypeExt<Id = Id>,
1055 T::Types: Default + Extend<T>,
1056{
1057 pub fn hole() -> T {
1058 T::from(Type::Hole)
1059 }
1060
1061 pub fn opaque() -> T {
1062 T::from(Type::Opaque)
1063 }
1064
1065 pub fn error() -> T {
1066 T::from(Type::Error)
1067 }
1068
1069 pub fn builtin(typ: BuiltinType) -> T {
1070 T::from(Type::Builtin(typ))
1071 }
1072
1073 pub fn forall(params: Vec<Generic<Id>>, typ: T) -> T {
1074 if params.is_empty() {
1075 typ
1076 } else {
1077 T::from(Type::Forall(params, typ))
1078 }
1079 }
1080
1081 pub fn array(typ: T) -> T {
1082 Type::app(Type::array_builtin(), collect![typ])
1083 }
1084
1085 pub fn array_builtin() -> T {
1086 Type::builtin(BuiltinType::Array)
1087 }
1088
1089 pub fn app(id: T, args: T::Types) -> T {
1090 if args.is_empty() {
1091 id
1092 } else {
1093 T::from(Type::App(id, args))
1094 }
1095 }
1096
1097 pub fn variant(fields: Vec<Field<T::SpannedId, T>>) -> T {
1098 Type::poly_variant(fields, Type::empty_row())
1099 }
1100
1101 pub fn poly_variant(fields: Vec<Field<T::SpannedId, T>>, rest: T) -> T {
1102 T::from(Type::Variant(Type::extend_row(fields, rest)))
1103 }
1104
1105 pub fn effect(fields: Vec<Field<T::SpannedId, T>>) -> T {
1106 Type::poly_effect(fields, Type::empty_row())
1107 }
1108
1109 pub fn poly_effect(fields: Vec<Field<T::SpannedId, T>>, rest: T) -> T {
1110 T::from(Type::Effect(Type::extend_row(fields, rest)))
1111 }
1112
1113 pub fn tuple<S, I>(symbols: &mut S, elems: I) -> T
1114 where
1115 S: ?Sized + IdentEnv<Ident = Id>,
1116 T::SpannedId: From<(Id, Span<BytePos>)>,
1117 I: IntoIterator<Item = T>,
1118 T: From<(Type<Id, T>, Flags)> + HasSpan,
1119 {
1120 T::from(Type::tuple_(symbols, elems))
1121 }
1122
1123 pub fn tuple_<S, I>(symbols: &mut S, elems: I) -> Type<Id, T>
1124 where
1125 S: ?Sized + IdentEnv<Ident = Id>,
1126 T::SpannedId: From<(Id, Span<BytePos>)>,
1127 I: IntoIterator<Item = T>,
1128 T: From<(Type<Id, T>, Flags)> + HasSpan,
1129 {
1130 NullInterner.tuple_(symbols, elems)
1131 }
1132
1133 pub fn record(
1134 types: Vec<Field<T::SpannedId, Alias<Id, T>>>,
1135 fields: Vec<Field<T::SpannedId, T>>,
1136 ) -> T {
1137 Type::poly_record(types, fields, Type::empty_row())
1138 }
1139
1140 pub fn poly_record(
1141 types: Vec<Field<T::SpannedId, Alias<Id, T>>>,
1142 fields: Vec<Field<T::SpannedId, T>>,
1143 rest: T,
1144 ) -> T {
1145 T::from(Type::Record(Type::extend_full_row(types, fields, rest)))
1146 }
1147
1148 pub fn extend_full_row(
1149 types: Vec<Field<T::SpannedId, Alias<Id, T>>>,
1150 fields: Vec<Field<T::SpannedId, T>>,
1151 rest: T,
1152 ) -> T {
1153 Self::extend_type_row(types, Self::extend_row(fields, rest))
1154 }
1155
1156 pub fn extend_row(fields: Vec<Field<T::SpannedId, T>>, rest: T) -> T {
1157 if fields.is_empty() {
1158 rest
1159 } else {
1160 T::from(Type::ExtendRow { fields, rest })
1161 }
1162 }
1163
1164 pub fn extend_type_row(types: Vec<Field<T::SpannedId, Alias<Id, T>>>, rest: T) -> T {
1165 if types.is_empty() {
1166 rest
1167 } else {
1168 T::from(Type::ExtendTypeRow { types, rest })
1169 }
1170 }
1171
1172 pub fn empty_row() -> T {
1173 T::from(Type::EmptyRow)
1174 }
1175
1176 pub fn function<I>(args: I, ret: T) -> T
1177 where
1178 I: IntoIterator<Item = T>,
1179 I::IntoIter: DoubleEndedIterator<Item = T>,
1180 {
1181 Self::function_type(ArgType::Explicit, args, ret)
1182 }
1183
1184 pub fn function_implicit<I>(args: I, ret: T) -> T
1185 where
1186 I: IntoIterator<Item = T>,
1187 I::IntoIter: DoubleEndedIterator<Item = T>,
1188 {
1189 Self::function_type(ArgType::Implicit, args, ret)
1190 }
1191
1192 pub fn function_type<I>(arg_type: ArgType, args: I, ret: T) -> T
1193 where
1194 I: IntoIterator<Item = T>,
1195 I::IntoIter: DoubleEndedIterator<Item = T>,
1196 {
1197 args.into_iter().rev().fold(ret, |body, arg| {
1198 T::from(Type::Function(arg_type, arg, body))
1199 })
1200 }
1201
1202 pub fn generic(typ: Generic<Id>) -> T {
1203 T::from(Type::Generic(typ))
1204 }
1205
1206 pub fn skolem(typ: Skolem<Id>) -> T {
1207 T::from(Type::Skolem(typ))
1208 }
1209
1210 pub fn variable(typ: TypeVariable) -> T {
1211 T::from(Type::Variable(typ))
1212 }
1213
1214 pub fn alias(name: Id, args: Vec<Generic<Id>>, typ: T) -> T {
1215 Self::alias_implicit(name, args, typ, false)
1216 }
1217
1218 pub fn alias_implicit(name: Id, args: Vec<Generic<Id>>, typ: T, is_implicit: bool) -> T {
1219 T::from(Type::Alias(AliasRef {
1220 index: 0,
1221 group: Arc::from(vec![AliasData {
1222 name,
1223 args,
1224 typ,
1225 is_implicit,
1226 }]),
1227 }))
1228 }
1229
1230 pub fn ident(id: KindedIdent<Id>) -> T {
1231 T::from(Type::Ident(id))
1232 }
1233
1234 pub fn projection(id: AppVec<Id>) -> T {
1235 T::from(Type::Projection(id))
1236 }
1237
1238 pub fn function_builtin() -> T {
1239 Type::builtin(BuiltinType::Function)
1240 }
1241
1242 pub fn string() -> T {
1243 Type::builtin(BuiltinType::String)
1244 }
1245
1246 pub fn char() -> T {
1247 Type::builtin(BuiltinType::Char)
1248 }
1249
1250 pub fn byte() -> T {
1251 Type::builtin(BuiltinType::Byte)
1252 }
1253
1254 pub fn int() -> T {
1255 Type::builtin(BuiltinType::Int)
1256 }
1257
1258 pub fn float() -> T {
1259 Type::builtin(BuiltinType::Float)
1260 }
1261
1262 pub fn unit() -> T {
1263 Type::record(vec![], vec![])
1264 }
1265}
1266
1267impl<Id, T> Type<Id, T>
1268where
1269 T: TypePtr<Id = Id>,
1270{
1271 pub fn is_array(&self) -> bool {
1272 match self {
1273 Type::App(typ, _) => match &**typ {
1274 Type::Builtin(BuiltinType::Array) => true,
1275 _ => false,
1276 },
1277 _ => false,
1278 }
1279 }
1280
1281 fn is_simple_constructor(&self) -> bool {
1282 let mut typ = self;
1283 while let Some((_, ret)) = typ.as_function() {
1284 typ = ret;
1285 }
1286 match typ {
1287 Type::Opaque => true,
1288 _ => false,
1289 }
1290 }
1291
1292 pub fn as_function(&self) -> Option<(&T, &T)> {
1293 self.as_function_with_type().map(|t| (t.1, t.2))
1294 }
1295
1296 pub fn as_explicit_function(&self) -> Option<(&T, &T)> {
1297 self.as_function_with_type().and_then(|t| {
1298 if t.0 == ArgType::Explicit {
1299 Some((t.1, t.2))
1300 } else {
1301 None
1302 }
1303 })
1304 }
1305
1306 pub fn as_function_with_type(&self) -> Option<(ArgType, &T, &T)> {
1307 match *self {
1308 Type::Function(arg_type, ref arg, ref ret) => return Some((arg_type, arg, ret)),
1309 Type::App(ref app, ref args) => {
1310 if args.len() == 2 {
1311 if let Type::Builtin(BuiltinType::Function) = **app {
1312 return Some((ArgType::Explicit, &args[0], &args[1]));
1313 }
1314 } else if args.len() == 1 {
1315 if let Type::App(ref app, ref args2) = **app {
1316 if let Type::Builtin(BuiltinType::Function) = **app {
1317 return Some((ArgType::Explicit, &args2[0], &args[0]));
1318 }
1319 }
1320 }
1321 }
1322 _ => (),
1323 }
1324 None
1325 }
1326
1327 pub fn unapplied_args(&self) -> Cow<[T]>
1328 where
1329 T: Clone,
1330 {
1331 match *self {
1332 Type::App(ref f, ref args) => {
1333 let mut f = f;
1334 let mut extra_args = Vec::new();
1335 while let Type::App(ref f2, ref args2) = **f {
1336 f = f2;
1337 extra_args.extend(args2.iter().rev().cloned());
1338 }
1339 if extra_args.is_empty() {
1340 Cow::Borrowed(args)
1341 } else {
1342 extra_args.reverse();
1343 extra_args.extend(args.iter().cloned());
1344 Cow::Owned(extra_args)
1345 }
1346 }
1347 _ => Cow::Borrowed(&[]),
1348 }
1349 }
1350
1351 pub fn alias_ident(&self) -> Option<&Id> {
1352 match self {
1353 Type::App(id, _) => id.alias_ident(),
1354 Type::Ident(id) => Some(&id.name),
1355 Type::Alias(alias) => Some(&alias.name),
1356 _ => None,
1357 }
1358 }
1359
1360 pub fn applied_alias(&self) -> Option<&AliasRef<Id, T>> {
1361 match *self {
1362 Type::Alias(ref alias) => Some(alias),
1363 Type::App(ref alias, _) => alias.applied_alias(),
1364 _ => None,
1365 }
1366 }
1367
1368 pub fn is_non_polymorphic_record(&self) -> bool {
1369 match *self {
1370 Type::Record(ref row)
1371 | Type::ExtendRow { rest: ref row, .. }
1372 | Type::ExtendTypeRow { rest: ref row, .. } => row.is_non_polymorphic_record(),
1373 Type::EmptyRow => true,
1374 _ => false,
1375 }
1376 }
1377
1378 pub fn params(&self) -> &[Generic<Id>] {
1379 match *self {
1380 Type::Alias(ref alias) => alias.typ.params(),
1381 _ => &[],
1382 }
1383 }
1384
1385 pub fn kind<'k>(&'k self, cache: &'k KindCache) -> Cow<'k, ArcKind> {
1386 self.kind_(cache, 0)
1387 }
1388
1389 fn kind_<'k>(&'k self, cache: &'k KindCache, applied_args: usize) -> Cow<'k, ArcKind> {
1390 let mut immediate_kind = match *self {
1391 Type::Function(_, _, _) => Cow::Borrowed(&cache.typ),
1392 Type::App(ref t, ref args) => t.kind_(cache, args.len()),
1393 Type::Error => Cow::Borrowed(&cache.error),
1394 Type::Hole => Cow::Borrowed(&cache.hole),
1395 Type::Opaque | Type::Builtin(_) | Type::Record(_) | Type::Variant(_) => {
1396 Cow::Owned(Kind::typ())
1397 }
1398 Type::EmptyRow | Type::ExtendRow { .. } | Type::ExtendTypeRow { .. } => {
1399 Cow::Owned(Kind::row())
1400 }
1401 Type::Effect(_) => {
1402 let t = Kind::typ();
1403 Cow::Owned(Kind::function(t.clone(), t))
1404 }
1405 Type::Forall(_, ref typ) => typ.kind_(cache, applied_args),
1406 Type::Variable(ref var) => Cow::Borrowed(&var.kind),
1407 Type::Skolem(ref skolem) => Cow::Borrowed(&skolem.kind),
1408 Type::Generic(ref gen) => Cow::Borrowed(&gen.kind),
1409 Type::Ident(_) | Type::Projection(_) => Cow::Owned(cache.typ()),
1411 Type::Alias(ref alias) => {
1412 return if alias.params().len() < applied_args {
1413 alias.typ.kind_(cache, applied_args - alias.params().len())
1414 } else {
1415 let mut kind = alias.typ.kind_(cache, 0).into_owned();
1416 for arg in &alias.params()[applied_args..] {
1417 kind = Kind::function(arg.kind.clone(), kind)
1418 }
1419 Cow::Owned(kind)
1420 };
1421 }
1422 };
1423 for _ in 0..applied_args {
1424 immediate_kind = match immediate_kind {
1425 Cow::Borrowed(k) => match **k {
1426 Kind::Function(_, ref ret) => Cow::Borrowed(ret),
1427 _ => return Cow::Borrowed(k),
1428 },
1429 Cow::Owned(k) => match *k {
1430 Kind::Function(_, ref ret) => Cow::Owned(ret.clone()),
1431 _ => return Cow::Owned(k.clone()),
1432 },
1433 };
1434 }
1435 immediate_kind
1436 }
1437}
1438
1439impl<T> Type<Symbol, T>
1440where
1441 T: TypePtr<Id = Symbol>,
1442{
1443 pub fn name(&self) -> Option<&SymbolRef> {
1448 if let Some(id) = self.alias_ident() {
1449 return Some(&**id);
1450 }
1451
1452 match *self {
1453 Type::Function(..) => Some(BuiltinType::Function.symbol()),
1454 Type::App(ref id, _) => match **id {
1455 Type::Builtin(b) => Some(b.symbol()),
1456 _ => None,
1457 },
1458 Type::Builtin(b) => Some(b.symbol()),
1459 Type::Effect(_) => Some(SymbolRef::new("Effect")),
1460 _ => None,
1461 }
1462 }
1463
1464 pub fn owned_name(&self) -> Option<SymbolKey> {
1465 if let Some(id) = self.alias_ident() {
1466 return Some(SymbolKey::Owned(id.clone()));
1467 }
1468
1469 match *self {
1470 Type::Function(..) => Some(SymbolKey::Ref(BuiltinType::Function.symbol())),
1471 Type::App(ref id, _) => match **id {
1472 Type::Builtin(b) => Some(SymbolKey::Ref(b.symbol())),
1473 _ => None,
1474 },
1475 Type::Builtin(b) => Some(SymbolKey::Ref(b.symbol())),
1476 Type::Effect(_) => Some(SymbolKey::Ref(SymbolRef::new("Effect"))),
1477 _ => None,
1478 }
1479 }
1480}
1481
1482#[derive(Eq, Clone)]
1483pub enum SymbolKey {
1484 Owned(Symbol),
1485 Ref(&'static SymbolRef),
1486}
1487
1488impl fmt::Debug for SymbolKey {
1489 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1490 write!(f, "{:?}", Borrow::<SymbolRef>::borrow(self))
1491 }
1492}
1493
1494impl fmt::Display for SymbolKey {
1495 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1496 write!(f, "{}", Borrow::<SymbolRef>::borrow(self))
1497 }
1498}
1499
1500impl Hash for SymbolKey {
1501 fn hash<H>(&self, state: &mut H)
1502 where
1503 H: Hasher,
1504 {
1505 Borrow::<SymbolRef>::borrow(self).hash(state)
1506 }
1507}
1508
1509impl PartialEq for SymbolKey {
1510 fn eq(&self, other: &Self) -> bool {
1511 Borrow::<SymbolRef>::borrow(self) == Borrow::<SymbolRef>::borrow(other)
1512 }
1513}
1514
1515impl PartialOrd for SymbolKey {
1516 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1517 Borrow::<SymbolRef>::borrow(self).partial_cmp(Borrow::<SymbolRef>::borrow(other))
1518 }
1519}
1520
1521impl Ord for SymbolKey {
1522 fn cmp(&self, other: &Self) -> Ordering {
1523 Borrow::<SymbolRef>::borrow(self).cmp(Borrow::<SymbolRef>::borrow(other))
1524 }
1525}
1526
1527impl Deref for SymbolKey {
1528 type Target = SymbolRef;
1529
1530 fn deref(&self) -> &Self::Target {
1531 match *self {
1532 SymbolKey::Owned(ref s) => s,
1533 SymbolKey::Ref(s) => s,
1534 }
1535 }
1536}
1537
1538impl Borrow<SymbolRef> for SymbolKey {
1539 fn borrow(&self) -> &SymbolRef {
1540 self
1541 }
1542}
1543
1544#[derive(Clone)]
1545struct ArcTypeInner<Id = Symbol> {
1546 typ: Type<Id, ArcType<Id>>,
1547 flags: Flags,
1548}
1549
1550forward_eq_hash! { <Id> for ArcTypeInner<Id> { typ } }
1551
1552#[derive(Eq, PartialEq, Hash)]
1554pub struct ArcType<Id = Symbol> {
1555 typ: Arc<ArcTypeInner<Id>>,
1556}
1557
1558impl<Id> Default for ArcType<Id>
1559where
1560 Id: PartialEq,
1561{
1562 fn default() -> Self {
1563 Type::hole()
1564 }
1565}
1566
1567#[cfg(feature = "serde")]
1568impl<'de, Id> DeserializeState<'de, Seed<Id, ArcType<Id>>> for ArcType<Id>
1569where
1570 Id: DeserializeState<'de, Seed<Id, ArcType<Id>>> + Clone + ::std::any::Any + PartialEq,
1571{
1572 fn deserialize_state<D>(
1573 seed: &mut Seed<Id, ArcType<Id>>,
1574 deserializer: D,
1575 ) -> Result<Self, D::Error>
1576 where
1577 D: crate::serde::de::Deserializer<'de>,
1578 {
1579 use crate::serialization::SharedSeed;
1580 let seed = SharedSeed::new(seed);
1581 crate::serde::de::DeserializeSeed::deserialize(seed, deserializer).map(ArcType::new)
1582 }
1583}
1584
1585impl<Id> Clone for ArcType<Id> {
1586 fn clone(&self) -> ArcType<Id> {
1587 ArcType {
1588 typ: self.typ.clone(),
1589 }
1590 }
1591}
1592
1593impl<Id: fmt::Debug> fmt::Debug for ArcType<Id> {
1594 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1595 (**self).fmt(f)
1596 }
1597}
1598
1599impl<Id: AsRef<str> + AsId<Id>> fmt::Display for ArcType<Id> {
1600 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1601 write!(f, "{}", TypeFormatter::new(self))
1602 }
1603}
1604
1605impl<Id> fmt::Pointer for ArcType<Id> {
1606 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1607 write!(f, "{:p}", &**self)
1608 }
1609}
1610
1611impl<Id> Borrow<Type<Id, ArcType<Id>>> for ArcType<Id> {
1612 fn borrow(&self) -> &Type<Id, ArcType<Id>> {
1613 self
1614 }
1615}
1616
1617impl<Id> Deref for ArcType<Id> {
1618 type Target = Type<Id, ArcType<Id>>;
1619
1620 fn deref(&self) -> &Type<Id, ArcType<Id>> {
1621 &self.typ.typ
1622 }
1623}
1624
1625impl<Id> HasSpan for ArcType<Id> {
1626 fn span(&self) -> Span<BytePos> {
1627 Span::new(0.into(), 0.into())
1628 }
1629}
1630
1631impl<Id> HasMetadata for ArcType<Id> {
1632 fn metadata(&self) -> Option<&Metadata> {
1633 None
1634 }
1635}
1636
1637pub fn row_iter<T>(typ: &T) -> RowIterator<T> {
1638 RowIterator { typ, current: 0 }
1639}
1640
1641pub fn row_iter_mut<Id, T>(typ: &mut T) -> RowIteratorMut<Id, T> {
1642 RowIteratorMut {
1643 fields: [].iter_mut(),
1644 rest: Some(typ),
1645 }
1646}
1647
1648pub fn type_field_iter<T>(typ: &T) -> TypeFieldIterator<T> {
1649 TypeFieldIterator { typ, current: 0 }
1650}
1651
1652pub fn remove_forall<'a, Id, T>(typ: &'a T) -> &'a T
1653where
1654 T: TypePtr<Id = Id>,
1655 Id: 'a,
1656{
1657 match **typ {
1658 Type::Forall(_, ref typ) => remove_forall(typ),
1659 _ => typ,
1660 }
1661}
1662
1663pub fn remove_forall_mut<'a, Id, T>(typ: &'a mut T) -> &'a mut T
1664where
1665 T: TypePtr<Id = Id> + DerefMut<Target = Type<Id, T>>,
1666 Id: 'a,
1667{
1668 if let Type::Forall(_, _) = **typ {
1669 match **typ {
1670 Type::Forall(_, ref mut typ) => remove_forall_mut(typ),
1671 _ => unreachable!(),
1672 }
1673 } else {
1674 typ
1675 }
1676}
1677
1678pub trait TypeAlloc<T: TypePtr>: Sized {
1679 type Elem;
1680
1681 fn alloc_extend(
1682 iter: impl IntoIterator<Item = Self::Elem>,
1683 context: &mut (impl ?Sized + TypeContext<T::Id, T>),
1684 ) -> Self;
1685}
1686
1687macro_rules! type_alloc_impl {
1688 (T [$($where_: tt)*] $ty: ty, $elem: ty => $method: ident) => {
1689 impl<$($where_)*> TypeAlloc<T> for $ty
1690 where
1691 T: TypePtr,
1692 {
1693 type Elem = $elem;
1694
1695 fn alloc_extend(
1696 iter: impl IntoIterator<Item = Self::Elem>,
1697 context: &mut (impl ?Sized + TypeContext<T::Id, T>),
1698 ) -> Self {
1699 context.$method(iter)
1700 }
1701 }
1702 }
1703}
1704
1705type_alloc_impl! { T [T: TypePtr<Generics = Self>] Vec<Generic<<T as TypePtr>::Id>>, Generic<<T as TypePtr>::Id> => intern_generics }
1706type_alloc_impl! { T ['ast, T: TypePtr<Generics = Self>] &'ast mut [Generic<<T as TypePtr>::Id>], Generic<<T as TypePtr>::Id> => intern_generics }
1707
1708type_alloc_impl! { T [T: TypePtr<Types = Self>] AppVec<T>, T => intern_types }
1709type_alloc_impl! { T ['ast, T: TypePtr<Types = Self>] &'ast mut [T], T => intern_types }
1710
1711type_alloc_impl! { T [T: TypePtr<Fields = Self>] Vec<Field<<T as TypePtr>::SpannedId, T>>, Field<<T as TypePtr>::SpannedId, T> => intern_fields }
1712type_alloc_impl! { T ['ast, T: TypePtr<Fields = Self>] &'ast mut [Field<<T as TypePtr>::SpannedId, T>], Field<<T as TypePtr>::SpannedId, T> => intern_fields }
1713
1714type_alloc_impl! { T [T: TypePtr<TypeFields = Self>] Vec<Field<<T as TypePtr>::SpannedId, Alias<<T as TypePtr>::Id, T>>>, Field<<T as TypePtr>::SpannedId, Alias<<T as TypePtr>::Id, T>> => intern_type_fields }
1715type_alloc_impl! { T ['ast, T: TypePtr<TypeFields = Self>] &'ast mut [Field<<T as TypePtr>::SpannedId, Alias<<T as TypePtr>::Id, T>>], Field<<T as TypePtr>::SpannedId, Alias<<T as TypePtr>::Id, T>> => intern_type_fields }
1716
1717pub trait TypePtr: Deref<Target = Type<<Self as TypePtr>::Id, Self>> + Sized {
1718 type Id;
1719 type SpannedId;
1720 type Types: TypeAlloc<Self> + Deref<Target = [Self]> + Default;
1721 type Generics: TypeAlloc<Self> + Deref<Target = [Generic<Self::Id>]> + Default;
1722 type Fields: TypeAlloc<Self> + Deref<Target = [Field<Self::SpannedId, Self>]> + Default;
1723 type TypeFields: TypeAlloc<Self>
1724 + Deref<Target = [Field<Self::SpannedId, Alias<Self::Id, Self>>]>
1725 + Default;
1726
1727 fn flags(&self) -> Flags {
1728 Flags::all()
1729 }
1730
1731 fn spine(&self) -> &Self {
1732 match &**self {
1733 Type::App(ref id, _) => id.spine(),
1734 _ => self,
1735 }
1736 }
1737
1738 fn display<A>(&self, width: usize) -> TypeFormatter<Self::Id, Self, A>
1739 where
1740 Self::Id: AsRef<str>,
1741 Self::SpannedId: AsRef<str>,
1742 {
1743 TypeFormatter::new(self).width(width)
1744 }
1745}
1746
1747pub trait TypeExt:
1748 TypePtr<
1749 Types = AppVec<Self>,
1750 Generics = Vec<Generic<<Self as TypePtr>::Id>>,
1751 Fields = Vec<Field<<Self as TypePtr>::SpannedId, Self>>,
1752 TypeFields = Vec<Field<<Self as TypePtr>::SpannedId, Alias<<Self as TypePtr>::Id, Self>>>,
1753 > + Clone
1754 + Sized
1755{
1756 fn strong_count(typ: &Self) -> usize;
1757
1758 fn type_field_iter(&self) -> TypeFieldIterator<Self> {
1761 type_field_iter(self)
1762 }
1763
1764 fn arg_iter(&self) -> ArgIterator<Self> {
1765 arg_iter(self)
1766 }
1767
1768 fn implicit_arg_iter(&self) -> ImplicitArgIterator<Self> {
1769 implicit_arg_iter(self)
1770 }
1771
1772 fn row_iter(&self) -> RowIterator<Self> {
1775 row_iter(self)
1776 }
1777
1778 fn remove_implicit_args<'a>(&'a self) -> &'a Self {
1779 match **self {
1780 Type::Function(ArgType::Implicit, _, ref typ) => typ.remove_implicit_args(),
1781 _ => self,
1782 }
1783 }
1784
1785 fn remove_forall<'a>(&'a self) -> &'a Self {
1786 remove_forall(self)
1787 }
1788
1789 fn remove_forall_and_implicit_args<'a>(&'a self) -> &'a Self {
1790 match **self {
1791 Type::Function(ArgType::Implicit, _, ref typ) => typ.remove_forall_and_implicit_args(),
1792 Type::Forall(_, ref typ) => typ.remove_forall_and_implicit_args(),
1793 _ => self,
1794 }
1795 }
1796
1797 fn replace_generics(
1798 &self,
1799 interner: &mut impl TypeContext<Self::Id, Self>,
1800 named_variables: &mut FnvMap<Self::Id, Self>,
1801 ) -> Option<Self>
1802 where
1803 Self::Id: Clone + Eq + Hash,
1804 Self::SpannedId: Clone,
1805 Self: Clone,
1806 Self::Types: Clone,
1807 Self::Generics: Clone,
1808 Self::Fields: Clone,
1809 {
1810 if named_variables.is_empty() {
1811 None
1812 } else {
1813 self.replace_generics_(interner, named_variables)
1814 }
1815 }
1816
1817 fn replace_generics_(
1818 &self,
1819 interner: &mut impl TypeContext<Self::Id, Self>,
1820 named_variables: &mut FnvMap<Self::Id, Self>,
1821 ) -> Option<Self>
1822 where
1823 Self::Id: Clone + Eq + Hash,
1824 Self::SpannedId: Clone,
1825 Self: Clone,
1826 Self::Types: Clone,
1827 Self::Generics: Clone,
1828 Self::Fields: Clone,
1829 {
1830 if !self.flags().intersects(Flags::HAS_GENERICS) {
1831 return None;
1832 }
1833
1834 match &**self {
1835 Type::Generic(generic) => named_variables.get(&generic.id).cloned(),
1836 Type::Forall(params, typ) => {
1837 let removed: AppVec<_> = params
1838 .iter()
1839 .flat_map(|param| named_variables.remove_entry(¶m.id))
1840 .collect();
1841
1842 let new_typ = typ.replace_generics(interner, named_variables);
1843 let new_typ = new_typ.map(|typ| interner.intern(Type::Forall(params.clone(), typ)));
1844
1845 named_variables.extend(removed);
1846
1847 new_typ
1848 }
1849 _ => walk_move_type_opt(
1850 self,
1851 &mut InternerVisitor::control(interner, |interner, typ: &Self| {
1852 typ.replace_generics_(interner, named_variables)
1853 }),
1854 ),
1855 }
1856 }
1857
1858 fn forall_scope_iter(&self) -> ForallScopeIter<Self> {
1859 ForallScopeIter {
1860 typ: self,
1861 offset: 0,
1862 }
1863 }
1864
1865 fn pretty<'a, A>(&'a self, arena: &'a Arena<'a, A>) -> DocBuilder<'a, Arena<'a, A>, A>
1866 where
1867 Self::Id: AsRef<str> + 'a,
1868 Self::SpannedId: AsRef<str> + AsId<Self::Id> + 'a,
1869 A: Clone,
1870 Self: HasMetadata + HasSpan,
1871 {
1872 top(self).pretty(&Printer::new(arena, &()))
1873 }
1874
1875 fn apply_args<'a>(
1886 &self,
1887 params: &[Generic<Self::Id>],
1888 args: &'a [Self],
1889 interner: &mut impl TypeContext<Self::Id, Self>,
1890 named_variables: &mut FnvMap<Self::Id, Self>,
1891 ) -> Option<Self>
1892 where
1893 Self::Id: Clone + Eq + Hash,
1894 Self::SpannedId: Clone,
1895 Self: fmt::Display,
1896 Self::Id: fmt::Display,
1897 Self::Types: Clone + FromIterator<Self>,
1898 Self::Generics: Clone,
1899 Self::Fields: Clone,
1900 {
1901 let (non_replaced_type, unapplied_args) =
1902 self.arg_application(params, args, interner, named_variables)?;
1903
1904 let non_replaced_type = non_replaced_type
1905 .replace_generics(interner, named_variables)
1906 .unwrap_or_else(|| non_replaced_type.clone());
1907 Some(interner.app(non_replaced_type, unapplied_args.iter().cloned().collect()))
1908 }
1909
1910 fn arg_application<'a>(
1911 &self,
1912 params: &[Generic<Self::Id>],
1913 args: &'a [Self],
1914 interner: &mut impl TypeContext<Self::Id, Self>,
1915 named_variables: &mut FnvMap<Self::Id, Self>,
1916 ) -> Option<(Self, &'a [Self])>
1917 where
1918 Self::Id: Clone + Eq + Hash,
1919 Self: fmt::Display,
1920 Self::Id: fmt::Display,
1921 Self::Types: FromIterator<Self>,
1922 Self::Generics: Clone,
1923 Self::Fields: Clone,
1924 {
1925 if let Type::Error = &**self {
1928 return Some((self.clone(), &[]));
1929 }
1930
1931 let typ = if params.len() == args.len() {
1932 Cow::Borrowed(self)
1933 } else {
1934 let (d, arg_types) = split_app(self);
1943 let allowed_missing_args = arg_types
1944 .iter()
1945 .rev()
1946 .zip(params.iter().rev())
1947 .take_while(|&(l, r)| match **l {
1948 Type::Generic(ref g) => g == r,
1949 _ => false,
1950 })
1951 .count();
1952
1953 if params.len() > allowed_missing_args + args.len() {
1954 return None;
1955 }
1956 let arg_types = arg_types
1958 .iter()
1959 .take(arg_types.len() + args.len() - params.len())
1960 .cloned()
1961 .collect();
1962
1963 let d = d.cloned().unwrap_or_else(|| interner.function_builtin());
1964 Cow::Owned(interner.app(d, arg_types))
1965 };
1966
1967 named_variables.extend(
1968 params
1969 .iter()
1970 .map(|g| g.id.clone())
1971 .zip(args.iter().cloned()),
1972 );
1973
1974 Some((typ.into_owned(), &args[params.len().min(args.len())..]))
1975 }
1976
1977 fn instantiate_generics(
1978 &self,
1979 interner: &mut impl Substitution<Self::Id, Self>,
1980 named_variables: &mut FnvMap<Self::Id, Self>,
1981 ) -> Self
1982 where
1983 Self::Id: Clone + Eq + Hash,
1984 Self::SpannedId: Clone,
1985 Self::Types: Clone,
1986 Self::Generics: Clone,
1987 Self::Fields: Clone,
1988 {
1989 let mut typ = self;
1990 while let Type::Forall(params, inner_type) = &**typ {
1991 named_variables.extend(
1992 params
1993 .iter()
1994 .map(|param| (param.id.clone(), interner.new_var())),
1995 );
1996 typ = inner_type;
1997 }
1998 if named_variables.is_empty() {
1999 typ.clone()
2000 } else {
2001 typ.replace_generics(interner, named_variables)
2002 .unwrap_or_else(|| typ.clone())
2003 }
2004 }
2005
2006 fn skolemize(
2007 &self,
2008 interner: &mut impl Substitution<Self::Id, Self>,
2009 named_variables: &mut FnvMap<Self::Id, Self>,
2010 ) -> Self
2011 where
2012 Self::Id: Clone + Eq + Hash,
2013 Self::SpannedId: Clone,
2014 Self::Types: Clone,
2015 Self::Generics: Clone,
2016 Self::Fields: Clone,
2017 {
2018 let mut typ = self;
2019 while let Type::Forall(ref params, ref inner_type) = **typ {
2020 let iter = params.iter().map(|param| {
2021 (
2022 param.id.clone(),
2023 interner.new_skolem(param.id.clone(), param.kind.clone()),
2024 )
2025 });
2026 named_variables.extend(iter);
2027 typ = inner_type;
2028 }
2029 if named_variables.is_empty() {
2030 typ.clone()
2031 } else {
2032 typ.replace_generics(interner, named_variables)
2033 .unwrap_or_else(|| typ.clone())
2034 }
2035 }
2036
2037 fn skolemize_in(
2038 &self,
2039 interner: &mut impl Substitution<Self::Id, Self>,
2040 named_variables: &mut FnvMap<Self::Id, Self>,
2041 f: impl FnOnce(Self) -> Self,
2042 ) -> Self
2043 where
2044 Self::Id: Clone + Eq + Hash,
2045 Self::SpannedId: Clone,
2046 Self::Types: Clone,
2047 Self::Generics: FromIterator<Generic<Self::Id>> + Clone,
2048 Self::Fields: Clone,
2049 {
2050 let skolemized = self.skolemize(interner, named_variables);
2051 let new_type = f(skolemized);
2052 interner.with_forall(new_type, self)
2053 }
2054}
2055
2056pub fn forall_params<'a, T, Id>(mut typ: &'a T) -> impl Iterator<Item = &'a Generic<Id>>
2057where
2058 Id: 'a,
2059 T: TypePtr<Id = Id>,
2060{
2061 let mut i = 0;
2062 iter::repeat(()).scan((), move |_, _| {
2063 while let Type::Forall(ref params, ref inner_type) = **typ {
2064 if i < params.len() {
2065 i += 1;
2066 return Some(¶ms[i - 1]);
2067 } else {
2068 i = 0;
2069 typ = inner_type;
2070 }
2071 }
2072 None
2073 })
2074}
2075
2076impl<Id> ArcType<Id>
2077where
2078 Id: PartialEq,
2079{
2080 pub fn new(typ: Type<Id, ArcType<Id>>) -> ArcType<Id> {
2081 let flags = Flags::from_type(&typ);
2082 Self::with_flags(typ, flags)
2083 }
2084}
2085
2086impl<Id> TypePtr for ArcType<Id> {
2087 type Id = Id;
2088 type SpannedId = Id;
2089 type Types = AppVec<Self>;
2090 type Generics = Vec<Generic<Id>>;
2091 type Fields = Vec<Field<Id, Self>>;
2092 type TypeFields = Vec<Field<Id, Alias<Id, Self>>>;
2093
2094 fn flags(&self) -> Flags {
2095 self.typ.flags
2096 }
2097}
2098
2099impl<Id> TypeExt for ArcType<Id> {
2100 fn strong_count(typ: &ArcType<Id>) -> usize {
2101 Arc::strong_count(&typ.typ)
2102 }
2103}
2104
2105pub struct ForallScopeIter<'a, T: 'a> {
2106 pub typ: &'a T,
2107 offset: usize,
2108}
2109
2110impl<'a, T, Id: 'a> Iterator for ForallScopeIter<'a, T>
2111where
2112 T: TypePtr<Id = Id>,
2113{
2114 type Item = &'a Generic<Id>;
2115
2116 fn next(&mut self) -> Option<Self::Item> {
2117 match **self.typ {
2118 Type::Forall(ref params, ref typ) => {
2119 let offset = self.offset;
2120 let item = params.get(offset).map(|param| {
2121 self.offset += 1;
2122 param
2123 });
2124 match item {
2125 Some(_) => item,
2126 None => {
2127 self.typ = typ;
2128 self.next()
2129 }
2130 }
2131 }
2132 _ => None,
2133 }
2134 }
2135}
2136
2137impl<Id> From<Type<Id, ArcType<Id>>> for ArcType<Id>
2138where
2139 Id: PartialEq,
2140{
2141 fn from(typ: Type<Id, ArcType<Id>>) -> ArcType<Id> {
2142 ArcType::new(typ)
2143 }
2144}
2145
2146impl<Id> From<(Type<Id, ArcType<Id>>, Flags)> for ArcType<Id> {
2147 fn from((typ, flags): (Type<Id, ArcType<Id>>, Flags)) -> ArcType<Id> {
2148 ArcType::with_flags(typ, flags)
2149 }
2150}
2151
2152#[derive(Clone)]
2153pub struct TypeFieldIterator<'a, T: 'a> {
2154 typ: &'a T,
2155 current: usize,
2156}
2157
2158impl<'a, Id: 'a, T> Iterator for TypeFieldIterator<'a, T>
2159where
2160 T: TypePtr<Id = Id>,
2161{
2162 type Item = &'a Field<T::SpannedId, Alias<Id, T>>;
2163
2164 fn next(&mut self) -> Option<&'a Field<T::SpannedId, Alias<Id, T>>> {
2165 match **self.typ {
2166 Type::ExtendRow { ref rest, .. } | Type::Record(ref rest) => {
2167 self.typ = rest;
2168 self.next()
2169 }
2170 Type::ExtendTypeRow {
2171 ref types,
2172 ref rest,
2173 } => {
2174 let current = self.current;
2175 self.current += 1;
2176 types.get(current).or_else(|| {
2177 self.current = 0;
2178 self.typ = rest;
2179 self.next()
2180 })
2181 }
2182 _ => None,
2183 }
2184 }
2185}
2186
2187#[derive(Clone)]
2188pub struct RowIterator<'a, T: 'a> {
2189 typ: &'a T,
2190 current: usize,
2191}
2192
2193impl<'a, T> RowIterator<'a, T> {
2194 pub fn current_type(&self) -> &'a T {
2195 self.typ
2196 }
2197}
2198
2199impl<'a, Id: 'a, T> Iterator for RowIterator<'a, T>
2200where
2201 T: TypePtr<Id = Id>,
2202{
2203 type Item = &'a Field<T::SpannedId, T>;
2204
2205 fn next(&mut self) -> Option<&'a Field<T::SpannedId, T>> {
2206 match **self.typ {
2207 Type::Record(ref row) | Type::Variant(ref row) => {
2208 self.typ = row;
2209 self.next()
2210 }
2211 Type::ExtendRow {
2212 ref fields,
2213 ref rest,
2214 ..
2215 } => {
2216 let current = self.current;
2217 self.current += 1;
2218 fields.get(current).or_else(|| {
2219 self.current = 0;
2220 self.typ = rest;
2221 self.next()
2222 })
2223 }
2224 Type::ExtendTypeRow { ref rest, .. } => {
2225 self.typ = rest;
2226 self.next()
2227 }
2228 _ => None,
2229 }
2230 }
2231
2232 fn size_hint(&self) -> (usize, Option<usize>) {
2233 let len = self.len();
2234 (len, Some(len))
2235 }
2236}
2237
2238impl<'a, Id: 'a, T> ExactSizeIterator for RowIterator<'a, T>
2239where
2240 T: TypePtr<Id = Id>,
2241{
2242 fn len(&self) -> usize {
2243 let mut typ = self.typ;
2244 let mut size = 0;
2245 loop {
2246 typ = match **typ {
2247 Type::Record(ref row) | Type::Variant(ref row) => row,
2248 Type::ExtendRow {
2249 ref fields,
2250 ref rest,
2251 ..
2252 } => {
2253 size += fields.len();
2254 rest
2255 }
2256 Type::ExtendTypeRow { ref rest, .. } => rest,
2257 _ => break,
2258 };
2259 }
2260 size
2261 }
2262}
2263
2264pub struct RowIteratorMut<'a, SpId: 'a, T: 'a> {
2265 fields: ::std::slice::IterMut<'a, Field<SpId, T>>,
2266 rest: Option<&'a mut T>,
2267}
2268
2269impl<'a, SpId, T> RowIteratorMut<'a, SpId, T> {
2270 pub fn current_type(&mut self) -> &mut T {
2271 self.rest.as_mut().unwrap()
2272 }
2273}
2274
2275impl<'a, SpId: 'a, Id: 'a, T: 'a> Iterator for RowIteratorMut<'a, SpId, T>
2276where
2277 T: DerefMut<Target = Type<Id, T>> + TypePtr<Id = Id, SpannedId = SpId>,
2278 T::Fields: DerefMut<Target = [Field<SpId, T>]>,
2279{
2280 type Item = &'a mut Field<SpId, T>;
2281
2282 fn next(&mut self) -> Option<Self::Item> {
2283 loop {
2284 if let Some(x) = self.fields.next() {
2285 return Some(x);
2286 }
2287 match ***self.rest.as_ref()? {
2288 Type::Record(_)
2289 | Type::Variant(_)
2290 | Type::ExtendRow { .. }
2291 | Type::ExtendTypeRow { .. } => (),
2292 _ => return None,
2293 };
2294
2295 let rest = mem::replace(&mut self.rest, None)?;
2296 self.rest = match **rest {
2297 Type::Record(ref mut row) | Type::Variant(ref mut row) => Some(row),
2298 Type::ExtendRow {
2299 ref mut fields,
2300 ref mut rest,
2301 ..
2302 } => {
2303 self.fields = fields.iter_mut();
2304 Some(rest)
2305 }
2306 Type::ExtendTypeRow { ref mut rest, .. } => Some(rest),
2307 _ => unreachable!(),
2308 };
2309 }
2310 }
2311}
2312
2313fn split_top<'a, Id, T>(self_: &'a T) -> Option<(Option<&'a T>, Cow<[T]>)>
2314where
2315 T: TypePtr<Id = Id> + Clone,
2316 Id: 'a,
2317{
2318 Some(match **self_ {
2319 Type::App(ref f, ref args) => (Some(f), Cow::Borrowed(args)),
2320 Type::Function(_, ref a, ref r) => (None, Cow::Owned(vec![a.clone(), r.clone()])),
2321 _ => return None,
2322 })
2323}
2324
2325fn clone_cow<'a, T>(cow: Cow<'a, [T]>) -> impl DoubleEndedIterator<Item = T> + 'a
2326where
2327 T: ToOwned + Clone,
2328{
2329 use itertools::Either;
2330
2331 match cow {
2332 Cow::Borrowed(ts) => Either::Left(ts.iter().cloned()),
2333 Cow::Owned(ts) => Either::Right(ts.into_iter()),
2334 }
2335}
2336
2337pub fn split_app<'a, Id, T>(self_: &'a T) -> (Option<&'a T>, Cow<[T]>)
2338where
2339 T: TypePtr<Id = Id> + Clone,
2340 Id: 'a,
2341{
2342 match split_top(self_) {
2343 Some((f, args)) => {
2344 let mut f = f;
2345 let mut extra_args = Vec::new();
2346 while let Some((f2, args2)) = f.and_then(split_top) {
2347 f = f2;
2348 extra_args.extend(clone_cow(args2).rev());
2349 }
2350 if extra_args.is_empty() {
2351 (f, args)
2352 } else {
2353 extra_args.reverse();
2354 extra_args.extend(clone_cow(args));
2355 (f, Cow::Owned(extra_args))
2356 }
2357 }
2358 None => (Some(self_), Cow::Borrowed(&[][..])),
2359 }
2360}
2361
2362pub fn ctor_args<Id, T>(typ: &T) -> ArgIterator<T>
2363where
2364 T: TypePtr<Id = Id>,
2365{
2366 ArgIterator { typ }
2367}
2368
2369pub struct ArgIterator<'a, T: 'a> {
2370 pub typ: &'a T,
2373}
2374
2375pub fn arg_iter<Id, T>(typ: &T) -> ArgIterator<T>
2377where
2378 T: TypePtr<Id = Id>,
2379{
2380 ArgIterator { typ }
2381}
2382
2383impl<'a, Id, T> Iterator for ArgIterator<'a, T>
2384where
2385 Id: 'a,
2386 T: TypePtr<Id = Id>,
2387{
2388 type Item = &'a T;
2389 fn next(&mut self) -> Option<&'a T> {
2390 self.typ.as_function().map(|(arg, ret)| {
2391 self.typ = ret;
2392 arg
2393 })
2394 }
2395}
2396
2397pub struct ImplicitArgIterator<'a, T: 'a> {
2398 pub typ: &'a T,
2401}
2402
2403pub fn implicit_arg_iter<Id, T>(typ: &T) -> ImplicitArgIterator<T>
2405where
2406 T: TypePtr<Id = Id>,
2407{
2408 ImplicitArgIterator { typ }
2409}
2410
2411impl<'a, Id, T> Iterator for ImplicitArgIterator<'a, T>
2412where
2413 Id: 'a,
2414 T: TypePtr<Id = Id>,
2415{
2416 type Item = &'a T;
2417 fn next(&mut self) -> Option<&'a T> {
2418 self.typ
2419 .as_function_with_type()
2420 .and_then(|(arg_type, arg, ret)| {
2421 if arg_type == ArgType::Implicit {
2422 self.typ = ret;
2423 Some(arg)
2424 } else {
2425 None
2426 }
2427 })
2428 }
2429}
2430
2431impl<Id> ArcType<Id> {
2432 fn with_flags(typ: Type<Id, ArcType<Id>>, flags: Flags) -> ArcType<Id> {
2433 let typ = Arc::new(ArcTypeInner { typ, flags });
2434 ArcType { typ }
2435 }
2436
2437 pub fn set(into: &mut Self, typ: Type<Id, Self>)
2438 where
2439 Id: Clone + PartialEq,
2440 {
2441 let into = Arc::make_mut(&mut into.typ);
2442 into.flags = Flags::from_type(&typ);
2443 into.typ = typ;
2444 }
2445
2446 pub fn level(&self) -> u32 {
2449 use std::cmp::min;
2450 fold_type(
2451 self,
2452 |typ, level| match **typ {
2453 Type::Variable(ref var) => min(var.id, level),
2454 _ => level,
2455 },
2456 u32::max_value(),
2457 )
2458 }
2459
2460 pub fn needs_generalize(&self) -> bool
2461 where
2462 Id: PartialEq,
2463 {
2464 self.flags().intersects(Flags::NEEDS_GENERALIZE)
2465 }
2466
2467 pub fn forall_params(&self) -> impl Iterator<Item = &Generic<Id>> {
2468 forall_params(self)
2469 }
2470}
2471
2472impl TypeVariable {
2473 pub fn new(var: u32) -> TypeVariable {
2474 TypeVariable::with_kind(Kind::Type, var)
2475 }
2476
2477 pub fn with_kind(kind: Kind, var: u32) -> TypeVariable {
2478 TypeVariable {
2479 kind: ArcKind::new(kind),
2480 id: var,
2481 }
2482 }
2483}
2484
2485impl fmt::Display for TypeVariable {
2486 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2487 self.id.fmt(f)
2488 }
2489}
2490
2491impl<Id: fmt::Display> fmt::Display for Generic<Id> {
2492 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2493 self.id.fmt(f)
2494 }
2495}
2496
2497impl fmt::Display for BuiltinType {
2498 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2499 self.to_str().fmt(f)
2500 }
2501}
2502
2503#[derive(PartialEq, Copy, Clone, PartialOrd)]
2504pub enum Prec {
2505 Top,
2507 Function,
2510 Constructor,
2514}
2515
2516impl Prec {
2517 pub fn enclose<'a, A>(
2518 &self,
2519 limit: Prec,
2520 arena: &'a Arena<'a, A>,
2521 doc: DocBuilder<'a, Arena<'a, A>, A>,
2522 ) -> DocBuilder<'a, Arena<'a, A>, A> {
2523 if *self >= limit {
2524 chain![arena, "(", doc, ")"]
2525 } else {
2526 doc
2527 }
2528 }
2529}
2530
2531#[doc(hidden)]
2532pub fn dt<T>(prec: Prec, typ: &T) -> DisplayType<T> {
2533 DisplayType { prec, typ }
2534}
2535
2536fn top<T>(typ: &T) -> DisplayType<T> {
2537 dt(Prec::Top, typ)
2538}
2539
2540pub struct DisplayType<'a, T: 'a> {
2541 prec: Prec,
2542 typ: &'a T,
2543}
2544
2545pub trait ToDoc<'a, A, B, E> {
2546 fn to_doc(&'a self, allocator: &'a A, env: E) -> DocBuilder<'a, A, B>
2547 where
2548 A: DocAllocator<'a, B>;
2549}
2550
2551impl<'a, I, A> ToDoc<'a, Arena<'a, A>, A, ()> for ArcType<I>
2552where
2553 I: AsRef<str> + AsId<I>,
2554 A: Clone,
2555{
2556 fn to_doc(&'a self, arena: &'a Arena<'a, A>, _: ()) -> DocBuilder<'a, Arena<'a, A>, A> {
2557 self.to_doc(arena, &() as &dyn Source)
2558 }
2559}
2560
2561impl<'a, I, A> ToDoc<'a, Arena<'a, A>, A, &'a dyn Source> for ArcType<I>
2562where
2563 I: AsRef<str> + AsId<I>,
2564 A: Clone,
2565{
2566 fn to_doc(
2567 &'a self,
2568 arena: &'a Arena<'a, A>,
2569 source: &'a dyn Source,
2570 ) -> DocBuilder<'a, Arena<'a, A>, A> {
2571 let printer = Printer::new(arena, source);
2572 dt(Prec::Top, self).pretty(&printer)
2573 }
2574}
2575
2576fn is_tuple<T>(typ: &T) -> bool
2577where
2578 T: TypePtr,
2579 T::SpannedId: AsRef<str>,
2580{
2581 match **typ {
2582 Type::Record(_) => {
2583 type_field_iter(typ).next().is_none()
2584 && row_iter(typ).enumerate().all(|(i, field)| {
2585 let name = field.name.as_ref();
2586 name.starts_with('_') && name[1..].parse() == Ok(i)
2587 })
2588 }
2589 _ => false,
2590 }
2591}
2592
2593const INDENT: isize = 4;
2594
2595impl<'a, I, T> DisplayType<'a, T>
2596where
2597 T: TypePtr<Id = I> + HasSpan + HasMetadata + 'a,
2598 I: AsRef<str> + 'a,
2599 T::SpannedId: AsRef<str> + AsId<I> + 'a,
2600{
2601 pub fn pretty<A>(&self, printer: &Printer<'a, I, A>) -> DocBuilder<'a, Arena<'a, A>, A>
2602 where
2603 A: Clone,
2604 {
2605 let typ = self.typ;
2606
2607 let doc = self.pretty_(printer);
2608 match **typ {
2609 Type::ExtendRow { .. } | Type::Variant(..) => doc,
2610 _ => {
2611 let comment = printer.comments_before(typ.span().start());
2612 comment.append(doc)
2613 }
2614 }
2615 }
2616
2617 fn pretty_<A>(&self, printer: &Printer<'a, I, A>) -> DocBuilder<'a, Arena<'a, A>, A>
2618 where
2619 A: Clone,
2620 {
2621 let arena = printer.arena;
2622
2623 let p = self.prec;
2624 let typ = self.typ;
2625
2626 match **typ {
2627 Type::Hole => arena.text("_"),
2628 Type::Error => arena.text("!"),
2629 Type::Opaque => arena.text("<opaque>"),
2630 Type::Forall(ref args, ref typ) => {
2631 let doc = chain![
2632 arena,
2633 chain![
2634 arena,
2635 "forall ",
2636 arena.concat(
2637 args.iter()
2638 .map(|arg| { arena.text(arg.id.as_ref()).append(arena.line()) })
2639 ),
2640 "."
2641 ]
2642 .group(),
2643 chain![
2644 arena,
2645 printer.space_before(typ.span().start()),
2646 top(typ).pretty_(printer)
2647 ]
2648 .nest(INDENT)
2649 ];
2650 p.enclose(Prec::Function, arena, doc).group()
2651 }
2652 Type::Variable(ref var) => arena.text(format!("{}", var.id)),
2653 Type::Skolem(ref skolem) => {
2654 chain![arena, skolem.name.as_ref(), "@", skolem.id.to_string()]
2655 }
2656 Type::Generic(ref gen) => arena.text(gen.id.as_ref()),
2657 Type::Function(..) => self.pretty_function(printer).nest(INDENT),
2658 Type::App(ref t, ref args) => match self.typ.as_function() {
2659 Some(_) => self.pretty_function(printer).nest(INDENT),
2660 None => {
2661 let doc = dt(Prec::Top, t).pretty_(printer);
2662 let arg_doc = arena.concat(args.iter().map(|arg| {
2663 printer
2664 .space_before(arg.span().start())
2665 .append(dt(Prec::Constructor, arg).pretty_(printer))
2666 }));
2667 let doc = doc.append(arg_doc.nest(INDENT));
2668 p.enclose(Prec::Constructor, arena, doc).group()
2669 }
2670 },
2671 Type::Variant(ref row) => {
2672 let mut first = true;
2673
2674 let mut doc = arena.nil();
2675 let mut row = row;
2676 loop {
2677 row = match **row {
2678 Type::EmptyRow => break,
2679 Type::ExtendRow {
2680 ref fields,
2681 ref rest,
2682 ..
2683 } => {
2684 doc = doc.append(arena.concat(fields.iter().map(|field| {
2685 chain![
2686 arena,
2687 if first {
2688 first = false;
2689 arena.nil()
2690 } else {
2691 arena.hardline()
2692 },
2693 chain![
2694 arena,
2695 "| ",
2696 field.name.as_ref() as &str,
2697 if field.typ.is_simple_constructor() {
2698 arena.concat(arg_iter(&field.typ).map(|arg| {
2699 chain![
2700 arena,
2701 " ",
2702 dt(Prec::Constructor, arg).pretty(printer)
2703 ]
2704 }))
2705 } else {
2706 chain![
2707 arena,
2708 " :",
2709 arena.line(),
2710 top(&field.typ).pretty(printer),
2711 ]
2712 .nest(INDENT)
2713 }
2714 ]
2715 .group()
2716 ]
2717 })));
2718 rest
2719 }
2720 _ => {
2721 doc = chain![
2722 arena,
2723 doc,
2724 if first { arena.nil() } else { arena.hardline() },
2725 ".. ",
2726 top(row).pretty(printer)
2727 ];
2728 break;
2729 }
2730 };
2731 }
2732
2733 p.enclose(Prec::Constructor, arena, doc).group()
2734 }
2735
2736 Type::Effect(ref row) => Self::pretty_record_like(
2737 row,
2738 printer,
2739 "[|",
2740 &mut |field: &'a Field<T::SpannedId, T>| {
2741 chain![
2742 arena,
2743 pretty_print::doc_comment(arena, field.typ.comment()),
2744 pretty_print::ident(arena, field.name.as_ref() as &str),
2745 " : "
2746 ]
2747 },
2748 "|]",
2749 ),
2750
2751 Type::Builtin(ref t) => match *t {
2752 BuiltinType::Function => chain![arena, "(", t.to_str(), ")"],
2753 _ => arena.text(t.to_str()),
2754 },
2755 Type::Record(ref row) => {
2756 if is_tuple(typ) {
2757 Self::pretty_record_like(row, printer, "(", &mut |_| arena.nil(), ")")
2758 } else {
2759 let mut pretty_record_field = |field: &'a Field<T::SpannedId, T>| {
2760 chain![
2761 arena,
2762 pretty_print::doc_comment(arena, field.typ.comment()),
2763 pretty_print::ident(arena, field.name.as_ref() as &str),
2764 " : "
2765 ]
2766 };
2767 Self::pretty_record_like(row, printer, "{", &mut pretty_record_field, "}")
2768 }
2769 }
2770 Type::ExtendRow { .. } | Type::ExtendTypeRow { .. } => {
2771 self.pretty_row("{", printer, &mut |field| {
2772 chain![
2773 arena,
2774 pretty_print::doc_comment(arena, field.typ.comment()),
2775 pretty_print::ident(arena, field.name.as_ref() as &str),
2776 " : "
2777 ]
2778 })
2779 }
2780 Type::EmptyRow => arena.text("EmptyRow"),
2783 Type::Ident(ref id) => {
2784 printer.symbol_with(&id.name, Name::new(id.as_ref()).name().as_str())
2785 }
2786 Type::Projection(ref ids) => arena.concat(Itertools::intersperse(
2787 ids.iter().map(|id| printer.symbol(id)),
2788 arena.text("."),
2789 )),
2790 Type::Alias(ref alias) => printer.symbol(&alias.name),
2791 }
2792 }
2793
2794 fn pretty_record_like<A>(
2795 row: &'a T,
2796 printer: &Printer<'a, I, A>,
2797 open: &'static str,
2798 pretty_field: &mut dyn FnMut(&'a Field<T::SpannedId, T>) -> DocBuilder<'a, Arena<'a, A>, A>,
2799 close: &'static str,
2800 ) -> DocBuilder<'a, Arena<'a, A>, A>
2801 where
2802 A: Clone,
2803 {
2804 let arena = printer.arena;
2805
2806 let forced_hardline = row_iter(row).any(|field| field.typ.comment().is_some());
2807
2808 let hardline = if forced_hardline {
2809 arena.hardline()
2810 } else {
2811 arena.line()
2812 };
2813
2814 let mut doc = arena.text(open);
2815 doc = match **row {
2816 Type::EmptyRow => doc,
2817 Type::ExtendRow { .. } | Type::ExtendTypeRow { .. } => doc
2818 .append(top(row).pretty_row(open, printer, pretty_field))
2819 .nest(INDENT),
2820 _ => doc
2821 .append(arena.line())
2822 .append("| ")
2823 .append(top(row).pretty(printer))
2824 .nest(INDENT),
2825 };
2826 if open != "(" {
2827 doc = doc.append(hardline);
2828 }
2829
2830 doc.append(close).group()
2831 }
2832
2833 fn pretty_row<A>(
2834 &self,
2835 open: &str,
2836 printer: &Printer<'a, I, A>,
2837 pretty_field: &mut dyn FnMut(&'a Field<T::SpannedId, T>) -> DocBuilder<'a, Arena<'a, A>, A>,
2838 ) -> DocBuilder<'a, Arena<'a, A>, A>
2839 where
2840 A: Clone,
2841 {
2842 let arena = printer.arena;
2843
2844 let mut doc = arena.nil();
2845 let mut typ = self.typ;
2846
2847 let fields = {
2848 let mut typ = typ;
2849 loop {
2850 match **typ {
2851 Type::ExtendRow { ref fields, .. } => break &fields[..],
2852 Type::ExtendTypeRow { ref rest, .. } => typ = rest,
2853 _ => break &[][..],
2854 }
2855 }
2856 };
2857 let forced_hardline = fields.iter().any(|field| field.typ.comment().is_some());
2858
2859 let hardline = if forced_hardline {
2860 arena.hardline()
2861 } else {
2862 arena.line()
2863 };
2864
2865 let print_any_field = fields
2866 .iter()
2867 .any(|field| printer.filter(field.name.as_id()) != Filter::Drop);
2868
2869 let mut filtered = false;
2870
2871 let types_len = type_field_iter(typ).count();
2872 for (i, field) in type_field_iter(typ).enumerate() {
2873 let filter = printer.filter(field.name.as_id());
2874 if filter == Filter::Drop {
2875 filtered = true;
2876 continue;
2877 }
2878
2879 let f =
2880 chain![
2881 arena,
2882 chain![
2883 arena,
2884 field.name.as_ref() as &str,
2885 arena.line(),
2886 arena.concat(
2887 field.typ.params().iter().map(|param| {
2888 arena.text(param.id.as_ref()).append(arena.line())
2889 })
2890 )
2891 ]
2892 .group(),
2893 arena.text("= "),
2894 if filter == Filter::RetainKey {
2895 arena.text("...")
2896 } else {
2897 top(&field.typ.typ).pretty(printer)
2898 },
2899 if i + 1 != types_len || print_any_field {
2900 arena.text(",")
2901 } else {
2902 arena.nil()
2903 }
2904 ]
2905 .group();
2906 doc = doc.append(hardline.clone()).append(f);
2907 }
2908
2909 let mut row_iter = row_iter(typ);
2910 for (i, field) in row_iter.by_ref().enumerate() {
2911 let filter = printer.filter(field.name.as_id());
2912 if filter == Filter::Drop {
2913 filtered = true;
2914 continue;
2915 }
2916
2917 let mut rhs = if filter == Filter::RetainKey {
2918 arena.text("...")
2919 } else {
2920 top(&field.typ).pretty(printer)
2921 };
2922 match *field.typ {
2923 Type::Record(_) => (),
2925 _ => rhs = rhs.nest(INDENT),
2926 }
2927 let f = chain![
2928 arena,
2929 pretty_field(field),
2930 rhs.group(),
2931 if i + 1 != fields.len() {
2932 arena.text(",")
2933 } else {
2934 arena.nil()
2935 }
2936 ]
2937 .group();
2938 let space_before = if i == 0 && open == "(" {
2939 arena.nil()
2940 } else {
2941 hardline.clone()
2942 };
2943 doc = doc.append(space_before).append(f);
2944 }
2945 typ = row_iter.typ;
2946
2947 let doc = if filtered {
2948 if let Doc::Nil = *doc.1 {
2949 chain![arena, hardline.clone(), "..."]
2950 } else {
2951 chain![
2952 arena,
2953 hardline.clone(),
2954 "...,",
2955 doc,
2956 if forced_hardline {
2957 arena.nil()
2958 } else {
2959 arena.text(",")
2960 },
2961 hardline.clone(),
2962 "..."
2963 ]
2964 }
2965 } else {
2966 doc
2967 };
2968 match **typ {
2969 Type::EmptyRow => doc,
2970 _ => doc
2971 .append(arena.line())
2972 .append("| ")
2973 .append(top(typ).pretty(printer)),
2974 }
2975 }
2976
2977 fn pretty_function<A>(&self, printer: &Printer<'a, I, A>) -> DocBuilder<'a, Arena<'a, A>, A>
2978 where
2979 I: AsRef<str>,
2980 A: Clone,
2981 {
2982 let arena = printer.arena;
2983 let doc = self.pretty_function_(printer);
2984 self.prec.enclose(Prec::Function, arena, doc).group()
2985 }
2986
2987 fn pretty_function_<A>(&self, printer: &Printer<'a, I, A>) -> DocBuilder<'a, Arena<'a, A>, A>
2988 where
2989 I: AsRef<str>,
2990 A: Clone,
2991 {
2992 let arena = printer.arena;
2993 match self.typ.as_function_with_type() {
2994 Some((arg_type, arg, ret)) => chain![
2995 arena,
2996 chain![
2997 arena,
2998 if arg_type == ArgType::Implicit {
2999 arena.text("[")
3000 } else {
3001 arena.nil()
3002 },
3003 dt(Prec::Function, arg).pretty_(printer),
3004 if arg_type == ArgType::Implicit {
3005 arena.text("]")
3006 } else {
3007 arena.nil()
3008 },
3009 ]
3010 .group(),
3011 printer.space_after(arg.span().end()),
3012 "-> ",
3013 top(ret).pretty_function_(printer)
3014 ],
3015 None => self.pretty(printer),
3016 }
3017 }
3018}
3019
3020pub fn pretty_print<'a, I, T, A>(
3021 printer: &Printer<'a, I, A>,
3022 typ: &'a T,
3023) -> DocBuilder<'a, Arena<'a, A>, A>
3024where
3025 I: AsRef<str> + 'a,
3026 T: TypePtr<Id = I> + HasSpan + HasMetadata,
3027 T::SpannedId: AsRef<str> + AsId<I> + 'a,
3028 A: Clone,
3029{
3030 dt(Prec::Top, typ).pretty(printer)
3031}
3032
3033pub fn walk_type<'a, I, T, F>(typ: &'a T, mut f: F)
3034where
3035 F: Walker<'a, T>,
3036 T: TypePtr<Id = I> + 'a,
3037 I: 'a,
3038{
3039 f.walk(typ)
3040}
3041
3042pub fn walk_type_<'a, I, T, F: ?Sized>(typ: &'a T, f: &mut F)
3043where
3044 F: Walker<'a, T>,
3045 T: TypePtr<Id = I> + 'a,
3046 I: 'a,
3047{
3048 match **typ {
3049 Type::Function(_, ref arg, ref ret) => {
3050 f.walk(arg);
3051 f.walk(ret);
3052 }
3053 Type::App(ref t, ref args) => {
3054 f.walk(t);
3055 for a in &**args {
3056 f.walk(a);
3057 }
3058 }
3059 Type::Forall(_, ref typ)
3060 | Type::Record(ref typ)
3061 | Type::Variant(ref typ)
3062 | Type::Effect(ref typ) => f.walk(typ),
3063 Type::ExtendRow {
3064 ref fields,
3065 ref rest,
3066 } => {
3067 for field in fields.iter() {
3068 f.walk(&field.typ);
3069 }
3070 f.walk(rest);
3071 }
3072 Type::ExtendTypeRow {
3073 ref types,
3074 ref rest,
3075 } => {
3076 for field in &**types {
3077 f.walk(&field.typ.typ);
3078 }
3079 f.walk(rest);
3080 }
3081 Type::Hole
3082 | Type::Opaque
3083 | Type::Error
3084 | Type::Builtin(_)
3085 | Type::Variable(_)
3086 | Type::Generic(_)
3087 | Type::Skolem(_)
3088 | Type::Ident(_)
3089 | Type::Projection(_)
3090 | Type::Alias(_)
3091 | Type::EmptyRow => (),
3092 }
3093}
3094
3095pub fn walk_type_mut<Id, T, F: ?Sized>(typ: &mut T, f: &mut F)
3096where
3097 F: WalkerMut<T>,
3098 T: TypePtr<Id = Id> + DerefMut<Target = Type<Id, T>>,
3099 T::Types: DerefMut<Target = [T]>,
3100 T::Fields: DerefMut<Target = [Field<T::SpannedId, T>]>,
3101 T::TypeFields: DerefMut<Target = [Field<T::SpannedId, Alias<Id, T>>]>,
3102{
3103 match **typ {
3104 Type::Forall(_, ref mut typ) => f.walk_mut(typ),
3105 Type::Function(_, ref mut arg, ref mut ret) => {
3106 f.walk_mut(arg);
3107 f.walk_mut(ret);
3108 }
3109 Type::App(ref mut t, ref mut args) => {
3110 f.walk_mut(t);
3111 for a in args.iter_mut() {
3112 f.walk_mut(a);
3113 }
3114 }
3115 Type::Record(ref mut row) | Type::Variant(ref mut row) | Type::Effect(ref mut row) => {
3116 f.walk_mut(row)
3117 }
3118 Type::ExtendRow {
3119 ref mut fields,
3120 ref mut rest,
3121 } => {
3122 for field in &mut **fields {
3123 f.walk_mut(&mut field.typ);
3124 }
3125 f.walk_mut(rest);
3126 }
3127 Type::ExtendTypeRow {
3128 ref mut types,
3129 ref mut rest,
3130 } => {
3131 for field in &mut **types {
3132 if let Some(alias) = field.typ.try_get_alias_mut() {
3133 let field_type = alias.unresolved_type_mut();
3134 f.walk_mut(field_type);
3135 }
3136 }
3137 f.walk_mut(rest);
3138 }
3139 Type::Hole
3140 | Type::Opaque
3141 | Type::Error
3142 | Type::Builtin(_)
3143 | Type::Variable(_)
3144 | Type::Generic(_)
3145 | Type::Skolem(_)
3146 | Type::Ident(_)
3147 | Type::Projection(_)
3148 | Type::Alias(_)
3149 | Type::EmptyRow => (),
3150 }
3151}
3152
3153pub fn fold_type<Id, T, F, A>(typ: &T, mut f: F, a: A) -> A
3154where
3155 F: FnMut(&T, A) -> A,
3156 T: TypePtr<Id = Id>,
3157{
3158 let mut a = Some(a);
3159 walk_type(typ, |t| {
3160 a = Some(f(t, a.take().expect("None in fold_type")));
3161 });
3162 a.expect("fold_type")
3163}
3164
3165pub trait TypeVisitor<Id, T>
3166where
3167 T: TypePtr<Id = Id>,
3168 T::Types: Clone,
3169 T::Generics: Clone,
3170 T::Fields: Clone,
3171 T::TypeFields: Clone,
3172{
3173 type Context: TypeContext<Id, T>;
3174
3175 fn context(&mut self) -> &mut Self::Context;
3176
3177 fn make(&mut self, typ: Type<Id, T>) -> T {
3178 self.context().intern(typ)
3179 }
3180
3181 fn make_types(&mut self, typ: impl IntoIterator<Item = T>) -> T::Types {
3182 self.context().intern_types(typ)
3183 }
3184
3185 fn visit(&mut self, typ: &T) -> Option<T>
3186 where
3187 T: TypePtr<Id = Id> + Clone,
3188 Id: Clone,
3189 T::SpannedId: Clone,
3190 {
3191 walk_move_type_opt(typ, self)
3192 }
3193
3194 fn forall(&mut self, params: T::Generics, typ: T) -> T {
3195 if params.is_empty() {
3196 typ
3197 } else {
3198 self.make(Type::Forall(params, typ))
3199 }
3200 }
3201
3202 fn app(&mut self, id: T, args: T::Types) -> T {
3203 if args.is_empty() {
3204 id
3205 } else {
3206 self.make(Type::App(id, args))
3207 }
3208 }
3209}
3210
3211pub trait Walker<'a, T> {
3212 fn walk(&mut self, typ: &'a T);
3213}
3214
3215impl<Id, T, F> TypeVisitor<Id, T> for F
3216where
3217 F: ?Sized + FnMut(&T) -> Option<T>,
3218 Id: Clone,
3219 T::SpannedId: Clone,
3220 T: TypeExt<Id = Id> + From<(Type<Id, T>, Flags)> + From<Type<Id, T>>,
3221 T::Types: FromIterator<T> + Clone,
3222 T::Generics: FromIterator<Generic<Id>> + Clone,
3223 T::Fields: FromIterator<Field<T::SpannedId, T>> + Clone,
3224{
3225 type Context = NullInterner;
3226
3227 fn context(&mut self) -> &mut Self::Context {
3228 NullInterner::new()
3229 }
3230
3231 fn visit(&mut self, typ: &T) -> Option<T>
3232 where
3233 T: TypePtr<Id = Id> + From<Type<Id, T>> + Clone,
3234 Id: Clone,
3235 {
3236 let new_type = walk_move_type_opt(typ, self);
3237 let new_type2 = self(new_type.as_ref().map_or(typ, |t| t));
3238 new_type2.or(new_type)
3239 }
3240}
3241
3242#[macro_export(local_inner_macros)]
3243macro_rules! expr {
3244 ($self: ident, $id: ident, $expr: expr) => {{
3245 let $id = $self;
3246 $expr
3247 }};
3248}
3249
3250#[macro_export(local_inner_macros)]
3251macro_rules! forward_type_interner_methods_no_arg {
3252 ($typ: ty, [$($tokens: tt)+] $id: ident $($rest : ident)* ) => {
3253 fn $id(&mut self) -> $typ {
3254 $crate::expr!(self, $($tokens)+).$id()
3255 }
3256 $crate::forward_type_interner_methods_no_arg!($typ, [$($tokens)+] $($rest)*);
3257 };
3258
3259 ($typ: ty, [$($tokens: tt)+]) => {
3260 }
3261}
3262
3263#[macro_export]
3264macro_rules! forward_type_interner_methods {
3265 ($id: ty, $typ: ty, $($tokens: tt)+ ) => {
3266 fn intern(&mut self, typ: $crate::types::Type<$id, $typ>) -> $typ {
3267 $crate::expr!(self, $($tokens)+).intern(typ)
3268 }
3269
3270 fn intern_types(&mut self, types: impl IntoIterator<Item = $typ>) -> <$typ as $crate::types::TypePtr>::Types {
3271 $crate::expr!(self, $($tokens)+).intern_types(types)
3272 }
3273
3274 fn intern_generics(&mut self, types: impl IntoIterator<Item = $crate::types::Generic<$id>>) -> <$typ as $crate::types::TypePtr>::Generics {
3275 $crate::expr!(self, $($tokens)+).intern_generics(types)
3276 }
3277
3278 fn intern_fields(&mut self, types: impl IntoIterator<Item = $crate::types::Field<<$typ as $crate::types::TypePtr>::SpannedId, $typ>>) -> <$typ as $crate::types::TypePtr>::Fields {
3279 $crate::expr!(self, $($tokens)+).intern_fields(types)
3280 }
3281
3282 fn intern_type_fields(&mut self, types: impl IntoIterator<Item = $crate::types::Field<<$typ as $crate::types::TypePtr>::SpannedId, $crate::types::Alias<$id, $typ>>>) -> <$typ as $crate::types::TypePtr>::TypeFields {
3283 $crate::expr!(self, $($tokens)+).intern_type_fields(types)
3284 }
3285
3286 fn intern_flags(&mut self, typ: $crate::types::Type<$id, $typ>, flags: $crate::types::Flags) -> $typ {
3287 $crate::expr!(self, $($tokens)+).intern_flags(typ, flags)
3288 }
3289
3290 fn builtin(&mut self, typ: $crate::types::BuiltinType) -> $typ {
3291 $crate::expr!(self, $($tokens)+).builtin(typ)
3292 }
3293
3294 fn forall(&mut self, params: <$typ as $crate::types::TypePtr>::Generics, typ: $typ) -> $typ {
3295 $crate::expr!(self, $($tokens)+).forall(params, typ)
3296 }
3297
3298 fn with_forall(&mut self, typ: $typ, from: &$typ) -> $typ
3299 where
3300 $id: Clone + Eq + std::hash::Hash,
3301 $typ: $crate::types::TypeExt<Id = $id> + Clone,
3302 <$typ as $crate::types::TypePtr>::Generics: std::iter::FromIterator<$crate::types::Generic<$id>> + Clone,
3303 {
3304 $crate::expr!(self, $($tokens)+).with_forall(typ, from)
3305 }
3306
3307 fn array(&mut self, typ: $typ) -> $typ {
3308 $crate::expr!(self, $($tokens)+).array(typ)
3309 }
3310
3311 fn app(&mut self, id: $typ, args: <$typ as $crate::types::TypePtr>::Types) -> $typ {
3312 $crate::expr!(self, $($tokens)+).app(id, args)
3313 }
3314
3315 fn variant(&mut self, fields: <$typ as $crate::types::TypePtr>::Fields) -> $typ {
3316 $crate::expr!(self, $($tokens)+).variant(fields)
3317 }
3318
3319 fn poly_variant(&mut self, fields: <$typ as $crate::types::TypePtr>::Fields, rest: $typ) -> $typ {
3320 $crate::expr!(self, $($tokens)+).poly_variant(fields, rest)
3321 }
3322
3323 fn effect(&mut self, fields: <$typ as $crate::types::TypePtr>::Fields) -> $typ {
3324 $crate::expr!(self, $($tokens)+).effect(fields)
3325 }
3326
3327 fn poly_effect(&mut self, fields: <$typ as $crate::types::TypePtr>::Fields, rest: $typ) -> $typ {
3328 $crate::expr!(self, $($tokens)+).poly_effect(fields, rest)
3329 }
3330
3331 fn record(
3332 &mut self,
3333 types: <$typ as $crate::types::TypePtr>::TypeFields,
3334 fields: <$typ as $crate::types::TypePtr>::Fields,
3335 ) -> $typ {
3336 $crate::expr!(self, $($tokens)+).record(types, fields)
3337 }
3338
3339 fn poly_record(
3340 &mut self,
3341 types: <$typ as $crate::types::TypePtr>::TypeFields,
3342 fields: <$typ as $crate::types::TypePtr>::Fields,
3343 rest: $typ,
3344 ) -> $typ {
3345 $crate::expr!(self, $($tokens)+).poly_record(types, fields, rest)
3346 }
3347
3348 fn extend_full_row(
3349 &mut self,
3350 types: <$typ as $crate::types::TypePtr>::TypeFields,
3351 fields: <$typ as $crate::types::TypePtr>::Fields,
3352 rest: $typ,
3353 ) -> $typ {
3354 $crate::expr!(self, $($tokens)+).extend_full_row(types, fields, rest)
3355 }
3356
3357 fn extend_row(
3358 &mut self,
3359 fields: <$typ as $crate::types::TypePtr>::Fields,
3360 rest: $typ,
3361 ) -> $typ {
3362 $crate::expr!(self, $($tokens)+).extend_row(fields, rest)
3363 }
3364
3365 fn extend_type_row(
3366 &mut self,
3367 types: <$typ as $crate::types::TypePtr>::TypeFields,
3368 rest: $typ,
3369 ) -> $typ {
3370 $crate::expr!(self, $($tokens)+).extend_type_row(types, rest)
3371 }
3372
3373 fn generic(&mut self, typ: $crate::types::Generic<$id>) -> $typ {
3374 $crate::expr!(self, $($tokens)+).generic(typ)
3375 }
3376
3377 fn skolem(&mut self, typ: $crate::types::Skolem<$id>) -> $typ {
3378 $crate::expr!(self, $($tokens)+).skolem(typ)
3379 }
3380
3381 fn variable(&mut self, typ: $crate::types::TypeVariable) -> $typ {
3382 $crate::expr!(self, $($tokens)+).variable(typ)
3383 }
3384
3385 fn alias(
3386 &mut self,
3387 name: $id,
3388 args: <$typ as $crate::types::TypePtr>::Generics,
3389 typ: $typ,
3390 ) -> $typ
3391 {
3392 $crate::expr!(self, $($tokens)+).alias(name, args, typ)
3393 }
3394
3395 fn ident(&mut self, id: $crate::ast::KindedIdent<$id>) -> $typ {
3396 $crate::expr!(self, $($tokens)+).ident(id)
3397 }
3398
3399 fn projection(&mut self, id: $crate::types::AppVec<$id>) -> $typ {
3400 $crate::expr!(self, $($tokens)+).projection(id)
3401 }
3402
3403 fn builtin_type(&mut self, typ: $crate::types::BuiltinType) -> $typ {
3404 $crate::expr!(self, $($tokens)+).builtin_type(typ)
3405 }
3406
3407 fn new_alias(&mut self, name: $id, args: <$typ as $crate::types::TypePtr>::Generics, typ: $typ) -> $crate::types::Alias<$id, $typ> {
3408 $crate::expr!(self, $($tokens)+).new_alias(name, args, typ)
3409 }
3410
3411 fn new_data_alias(&mut self, data: $crate::types::AliasData<$id, $typ>) -> $crate::types::Alias<$id, $typ> {
3412 $crate::expr!(self, $($tokens)+).new_data_alias(data)
3413 }
3414
3415 fn alias_group(
3416 &mut self,
3417 group: Vec<$crate::types::AliasData<$id, $typ>>,
3418 ) -> Vec<$crate::types::Alias<$id, $typ>>
3419 where
3420 $typ: $crate::types::TypeExt<Id = $id>,
3421 $id: PartialEq,
3422 {
3423 $crate::expr!(self, $($tokens)+).alias_group(group)
3424 }
3425
3426 $crate::forward_type_interner_methods_no_arg!(
3472 $typ,
3473 [$($tokens)+]
3474 hole opaque error array_builtin empty_row function_builtin string char byte int float unit
3475 );
3476 }
3477}
3478
3479pub struct InternerVisitor<'i, F, T> {
3480 interner: &'i mut T,
3481 visitor: F,
3482}
3483
3484pub trait TypeContext<Id, T>
3485where
3486 T: TypePtr<Id = Id>,
3487{
3488 fn intern_flags(&mut self, typ: Type<Id, T>, flags: Flags) -> T;
3489
3490 fn intern(&mut self, typ: Type<Id, T>) -> T;
3491
3492 fn intern_types(&mut self, types: impl IntoIterator<Item = T>) -> T::Types;
3493
3494 fn intern_generics(&mut self, types: impl IntoIterator<Item = Generic<Id>>) -> T::Generics;
3495
3496 fn intern_fields(
3497 &mut self,
3498 types: impl IntoIterator<Item = Field<T::SpannedId, T>>,
3499 ) -> T::Fields;
3500
3501 fn intern_type_fields(
3502 &mut self,
3503 types: impl IntoIterator<Item = Field<T::SpannedId, Alias<Id, T>>>,
3504 ) -> T::TypeFields;
3505
3506 fn hole(&mut self) -> T {
3507 self.intern(Type::Hole)
3508 }
3509
3510 fn opaque(&mut self) -> T {
3511 self.intern(Type::Opaque)
3512 }
3513
3514 fn error(&mut self) -> T {
3515 self.intern(Type::Error)
3516 }
3517
3518 fn builtin(&mut self, typ: BuiltinType) -> T {
3519 self.intern(Type::Builtin(typ))
3520 }
3521
3522 fn forall(&mut self, params: T::Generics, typ: T) -> T {
3523 if params.is_empty() {
3524 typ
3525 } else {
3526 self.intern(Type::Forall(params, typ))
3527 }
3528 }
3529
3530 fn with_forall(&mut self, typ: T, from: &T) -> T
3531 where
3532 Id: Clone + Eq + Hash,
3533 T: TypeExt<Id = Id> + Clone,
3534 T::Generics: FromIterator<Generic<Id>> + Clone,
3535 {
3536 let params = forall_params(from).cloned().collect();
3537 self.forall(params, typ)
3538 }
3539
3540 fn array(&mut self, typ: T) -> T {
3541 let a = self.array_builtin();
3542 let typ = self.intern_types(Some(typ));
3543 self.app(a, typ)
3544 }
3545
3546 fn array_builtin(&mut self) -> T {
3547 self.builtin(BuiltinType::Array)
3548 }
3549
3550 fn app(&mut self, id: T, args: T::Types) -> T {
3551 if args.is_empty() {
3552 id
3553 } else {
3554 self.intern(Type::App(id, args))
3555 }
3556 }
3557
3558 fn variant(&mut self, fields: T::Fields) -> T {
3559 let empty_row = self.empty_row();
3560 self.poly_variant(fields, empty_row)
3561 }
3562
3563 fn poly_variant(&mut self, fields: T::Fields, rest: T) -> T {
3564 let row = self.extend_row(fields, rest);
3565 self.intern(Type::Variant(row))
3566 }
3567
3568 fn effect(&mut self, fields: T::Fields) -> T {
3569 let empty_row = self.empty_row();
3570 self.poly_effect(fields, empty_row)
3571 }
3572
3573 fn poly_effect(&mut self, fields: T::Fields, rest: T) -> T {
3574 let extend_row = self.extend_row(fields, rest);
3575 self.intern(Type::Effect(extend_row))
3576 }
3577
3578 fn tuple<S, I>(&mut self, symbols: &mut S, elems: I) -> T
3579 where
3580 S: ?Sized + IdentEnv<Ident = Id>,
3581 T::SpannedId: From<(Id, Span<BytePos>)>,
3582 I: IntoIterator<Item = T>,
3583 T: HasSpan,
3584 {
3585 let t = self.tuple_(symbols, elems);
3586 self.intern(t)
3587 }
3588
3589 fn tuple_<S, I>(&mut self, symbols: &mut S, elems: I) -> Type<Id, T>
3590 where
3591 S: ?Sized + IdentEnv<Ident = Id>,
3592 T::SpannedId: From<(Id, Span<BytePos>)>,
3593 T: HasSpan,
3594 I: IntoIterator<Item = T>,
3595 {
3596 let empty_row = self.empty_row();
3597 let elems = self.intern_fields(elems.into_iter().enumerate().map(|(i, typ)| Field {
3598 name: (symbols.from_str(&format!("_{}", i)), typ.span()).into(),
3599 typ,
3600 }));
3601 Type::Record(self.extend_row(elems, empty_row))
3602 }
3603
3604 fn record(&mut self, types: T::TypeFields, fields: T::Fields) -> T {
3605 let empty_row = self.empty_row();
3606 self.poly_record(types, fields, empty_row)
3607 }
3608
3609 fn poly_record(&mut self, types: T::TypeFields, fields: T::Fields, rest: T) -> T {
3610 let row = self.extend_full_row(types, fields, rest);
3611 self.intern(Type::Record(row))
3612 }
3613
3614 fn extend_full_row(&mut self, types: T::TypeFields, fields: T::Fields, rest: T) -> T {
3615 let rest = self.extend_row(fields, rest);
3616 self.extend_type_row(types, rest)
3617 }
3618
3619 fn extend_row(&mut self, fields: T::Fields, rest: T) -> T {
3620 if fields.is_empty() {
3621 rest
3622 } else {
3623 self.intern(Type::ExtendRow { fields, rest })
3624 }
3625 }
3626
3627 fn extend_type_row(&mut self, types: T::TypeFields, rest: T) -> T {
3628 if types.is_empty() {
3629 rest
3630 } else {
3631 self.intern(Type::ExtendTypeRow { types, rest })
3632 }
3633 }
3634
3635 fn empty_row(&mut self) -> T {
3636 self.intern(Type::EmptyRow)
3637 }
3638
3639 fn function<I>(&mut self, args: I, ret: T) -> T
3640 where
3641 I: IntoIterator<Item = T>,
3642 I::IntoIter: DoubleEndedIterator<Item = T>,
3643 {
3644 self.function_type(ArgType::Explicit, args, ret)
3645 }
3646
3647 fn function_implicit<I>(&mut self, args: I, ret: T) -> T
3648 where
3649 I: IntoIterator<Item = T>,
3650 I::IntoIter: DoubleEndedIterator<Item = T>,
3651 {
3652 self.function_type(ArgType::Implicit, args, ret)
3653 }
3654
3655 fn function_type<I>(&mut self, arg_type: ArgType, args: I, ret: T) -> T
3656 where
3657 I: IntoIterator<Item = T>,
3658 I::IntoIter: DoubleEndedIterator<Item = T>,
3659 {
3660 args.into_iter().rev().fold(ret, |body, arg| {
3661 self.intern(Type::Function(arg_type, arg, body))
3662 })
3663 }
3664
3665 fn generic(&mut self, typ: Generic<Id>) -> T {
3666 self.intern(Type::Generic(typ))
3667 }
3668
3669 fn skolem(&mut self, typ: Skolem<Id>) -> T {
3670 self.intern(Type::Skolem(typ))
3671 }
3672
3673 fn variable(&mut self, typ: TypeVariable) -> T {
3674 self.intern(Type::Variable(typ))
3675 }
3676
3677 fn alias(&mut self, name: Id, args: T::Generics, typ: T) -> T {
3678 self.intern(Type::Alias(AliasRef {
3679 index: 0,
3680 group: Arc::from(vec![AliasData {
3681 name,
3682 args,
3683 typ,
3684 is_implicit: false,
3685 }]),
3686 }))
3687 }
3688
3689 fn ident(&mut self, id: KindedIdent<Id>) -> T {
3690 self.intern(Type::Ident(id))
3691 }
3692
3693 fn projection(&mut self, id: AppVec<Id>) -> T {
3694 self.intern(Type::Projection(id))
3695 }
3696
3697 fn function_builtin(&mut self) -> T {
3698 self.builtin(BuiltinType::Function)
3699 }
3700
3701 fn string(&mut self) -> T {
3702 self.builtin(BuiltinType::String)
3703 }
3704
3705 fn char(&mut self) -> T {
3706 self.builtin(BuiltinType::Char)
3707 }
3708
3709 fn byte(&mut self) -> T {
3710 self.builtin(BuiltinType::Byte)
3711 }
3712
3713 fn int(&mut self) -> T {
3714 self.builtin(BuiltinType::Int)
3715 }
3716
3717 fn float(&mut self) -> T {
3718 self.builtin(BuiltinType::Float)
3719 }
3720
3721 fn unit(&mut self) -> T {
3722 self.record(Default::default(), Default::default())
3723 }
3724
3725 fn builtin_type(&mut self, typ: BuiltinType) -> T {
3726 match typ {
3727 BuiltinType::String => self.string(),
3728 BuiltinType::Byte => self.byte(),
3729 BuiltinType::Char => self.char(),
3730 BuiltinType::Int => self.int(),
3731 BuiltinType::Float => self.float(),
3732 BuiltinType::Array => self.array_builtin(),
3733 BuiltinType::Function => self.function_builtin(),
3734 }
3735 }
3736
3737 fn new_alias(&mut self, name: Id, args: T::Generics, typ: T) -> Alias<Id, T> {
3738 Alias {
3739 _typ: self.alias(name, args, typ),
3740 _marker: PhantomData,
3741 }
3742 }
3743
3744 fn new_data_alias(&mut self, data: AliasData<Id, T>) -> Alias<Id, T> {
3745 Alias {
3746 _typ: self.intern(Type::Alias(AliasRef {
3747 index: 0,
3748 group: Arc::from(vec![data]),
3749 })),
3750 _marker: PhantomData,
3751 }
3752 }
3753
3754 fn alias_group(&mut self, group: Vec<AliasData<Id, T>>) -> Vec<Alias<Id, T>>
3755 where
3756 T: TypeExt<Id = Id>,
3757 Id: PartialEq,
3758 {
3759 let group = Arc::<[_]>::from(group);
3760 (0..group.len())
3761 .map(|index| {
3762 let typ = Type::Alias(AliasRef {
3763 index,
3764 group: group.clone(),
3765 });
3766 let flags = Flags::from_type(&typ)
3767 | (if group[index].is_implicit {
3768 Flags::HAS_IMPLICIT
3769 } else {
3770 Flags::empty()
3771 });
3772
3773 Alias {
3774 _typ: self.intern_flags(typ, flags),
3775 _marker: PhantomData,
3776 }
3777 })
3778 .collect()
3779 }
3780}
3781
3782pub trait Substitution<Id, T>: TypeContext<Id, T>
3783where
3784 T: TypePtr<Id = Id>,
3785{
3786 fn new_var(&mut self) -> T;
3787 fn new_skolem(&mut self, name: Id, kind: ArcKind) -> T;
3788}
3789
3790impl<'b, Id, T, V> TypeContext<Id, T> for &'b Rc<V>
3791where
3792 for<'a> &'a V: TypeContext<Id, T>,
3793 T: TypePtr<Id = Id>,
3794{
3795 forward_type_interner_methods!(Id, T, self_, &***self_);
3796}
3797
3798impl<Id, T, V> TypeContext<Id, T> for Rc<V>
3799where
3800 for<'a> &'a V: TypeContext<Id, T>,
3801 T: TypePtr<Id = Id>,
3802{
3803 forward_type_interner_methods!(Id, T, self_, &**self_);
3804}
3805
3806impl<'a, Id, T, V> TypeContext<Id, T> for &'a RefCell<V>
3807where
3808 V: TypeContext<Id, T>,
3809 T: TypePtr<Id = Id>,
3810{
3811 forward_type_interner_methods!(Id, T, self_, self_.borrow_mut());
3812}
3813
3814pub type SharedInterner<Id, T> = TypeCache<Id, T>;
3815
3816#[derive(Default)]
3817pub struct NullInterner;
3818
3819impl NullInterner {
3820 pub fn new() -> &'static mut NullInterner {
3821 unsafe { &mut *(&mut NullInterner as *mut _) }
3823 }
3824}
3825
3826impl<Id, T> TypeContext<Id, T> for NullInterner
3827where
3828 T: TypePtr<Id = Id> + From<(Type<Id, T>, Flags)> + From<Type<Id, T>>,
3829 T::Types: FromIterator<T>,
3830 T::Generics: FromIterator<Generic<Id>>,
3831 T::Fields: FromIterator<Field<T::SpannedId, T>>,
3832 T::TypeFields: FromIterator<Field<T::SpannedId, Alias<Id, T>>>,
3833{
3834 fn intern(&mut self, typ: Type<Id, T>) -> T {
3835 T::from(typ)
3836 }
3837
3838 fn intern_types(&mut self, types: impl IntoIterator<Item = T>) -> T::Types {
3839 types.into_iter().collect()
3840 }
3841
3842 fn intern_generics(&mut self, types: impl IntoIterator<Item = Generic<Id>>) -> T::Generics {
3843 types.into_iter().collect()
3844 }
3845
3846 fn intern_fields(
3847 &mut self,
3848 types: impl IntoIterator<Item = Field<T::SpannedId, T>>,
3849 ) -> T::Fields {
3850 types.into_iter().collect()
3851 }
3852
3853 fn intern_type_fields(
3854 &mut self,
3855 types: impl IntoIterator<Item = Field<T::SpannedId, Alias<Id, T>>>,
3856 ) -> T::TypeFields {
3857 types.into_iter().collect()
3858 }
3859
3860 fn intern_flags(&mut self, typ: Type<Id, T>, flags: Flags) -> T {
3861 T::from((typ, flags))
3862 }
3863}
3864
3865macro_rules! forward_to_cache {
3866 ($($id: ident)*) => {
3867 $(
3868 fn $id(&mut self) -> T {
3869 TypeCache::$id(self)
3870 }
3871 )*
3872 }
3873}
3874
3875impl<Id, T> TypeContext<Id, T> for TypeCache<Id, T>
3876where
3877 T: TypeExt<Id = Id> + From<(Type<Id, T>, Flags)> + From<Type<Id, T>> + Clone,
3878 T::Types: Default + Extend<T> + FromIterator<T>,
3879 T::Generics: FromIterator<Generic<Id>>,
3880 T::Fields: FromIterator<Field<T::SpannedId, T>>,
3881 T::TypeFields: FromIterator<Field<T::SpannedId, Alias<Id, T>>>,
3882{
3883 fn intern(&mut self, typ: Type<Id, T>) -> T {
3884 T::from(typ)
3885 }
3886
3887 fn intern_types(&mut self, types: impl IntoIterator<Item = T>) -> T::Types {
3888 types.into_iter().collect()
3889 }
3890
3891 fn intern_generics(&mut self, types: impl IntoIterator<Item = Generic<Id>>) -> T::Generics {
3892 types.into_iter().collect()
3893 }
3894
3895 fn intern_fields(
3896 &mut self,
3897 types: impl IntoIterator<Item = Field<T::SpannedId, T>>,
3898 ) -> T::Fields {
3899 types.into_iter().collect()
3900 }
3901
3902 fn intern_type_fields(
3903 &mut self,
3904 types: impl IntoIterator<Item = Field<T::SpannedId, Alias<Id, T>>>,
3905 ) -> T::TypeFields {
3906 types.into_iter().collect()
3907 }
3908
3909 fn intern_flags(&mut self, typ: Type<Id, T>, flags: Flags) -> T {
3910 T::from((typ, flags))
3911 }
3912
3913 forward_to_cache! {
3914 hole opaque error int byte float string char
3915 function_builtin array_builtin unit empty_row
3916 }
3917}
3918
3919impl<'a, Id, T> TypeContext<Id, T> for &'a TypeCache<Id, T>
3920where
3921 T: TypeExt<Id = Id> + From<(Type<Id, T>, Flags)> + From<Type<Id, T>> + Clone,
3922 T::Types: Default + Extend<T> + FromIterator<T>,
3923 T::Generics: FromIterator<Generic<Id>>,
3924 T::Fields: FromIterator<Field<T::SpannedId, T>>,
3925 T::TypeFields: FromIterator<Field<T::SpannedId, Alias<Id, T>>>,
3926{
3927 fn intern(&mut self, typ: Type<Id, T>) -> T {
3928 T::from(typ)
3929 }
3930
3931 fn intern_types(&mut self, types: impl IntoIterator<Item = T>) -> T::Types {
3932 types.into_iter().collect()
3933 }
3934
3935 fn intern_generics(&mut self, types: impl IntoIterator<Item = Generic<Id>>) -> T::Generics {
3936 types.into_iter().collect()
3937 }
3938
3939 fn intern_fields(
3940 &mut self,
3941 types: impl IntoIterator<Item = Field<T::SpannedId, T>>,
3942 ) -> T::Fields {
3943 types.into_iter().collect()
3944 }
3945
3946 fn intern_type_fields(
3947 &mut self,
3948 types: impl IntoIterator<Item = Field<T::SpannedId, Alias<Id, T>>>,
3949 ) -> T::TypeFields {
3950 types.into_iter().collect()
3951 }
3952
3953 fn intern_flags(&mut self, typ: Type<Id, T>, flags: Flags) -> T {
3954 T::from((typ, flags))
3955 }
3956
3957 forward_to_cache! {
3958 hole opaque error int byte float string char
3959 function_builtin array_builtin unit empty_row
3960 }
3961}
3962
3963use crate::ast::{ArenaRef, AstType};
3964impl<'ast, Id> TypeContext<Id, AstType<'ast, Id>> for ArenaRef<'_, 'ast, Id> {
3965 fn intern(&mut self, typ: Type<Id, AstType<'ast, Id>>) -> AstType<'ast, Id> {
3966 AstType::new_no_loc(*self, typ)
3967 }
3968
3969 fn intern_types(
3970 &mut self,
3971 types: impl IntoIterator<Item = AstType<'ast, Id>>,
3972 ) -> &'ast mut [AstType<'ast, Id>] {
3973 self.alloc_extend(types)
3974 }
3975
3976 fn intern_generics(
3977 &mut self,
3978 types: impl IntoIterator<Item = Generic<Id>>,
3979 ) -> &'ast mut [Generic<Id>] {
3980 self.alloc_extend(types)
3981 }
3982
3983 fn intern_fields(
3984 &mut self,
3985 types: impl IntoIterator<Item = Field<Spanned<Id, BytePos>, AstType<'ast, Id>>>,
3986 ) -> &'ast mut [Field<Spanned<Id, BytePos>, AstType<'ast, Id>>] {
3987 self.alloc_extend(types)
3988 }
3989
3990 fn intern_type_fields(
3991 &mut self,
3992 types: impl IntoIterator<Item = Field<Spanned<Id, BytePos>, Alias<Id, AstType<'ast, Id>>>>,
3993 ) -> &'ast mut [Field<Spanned<Id, BytePos>, Alias<Id, AstType<'ast, Id>>>] {
3994 self.alloc_extend(types)
3995 }
3996
3997 fn intern_flags(
3998 &mut self,
3999 typ: Type<Id, AstType<'ast, Id>>,
4000 _flags: Flags,
4001 ) -> AstType<'ast, Id> {
4002 self.intern(typ)
4003 }
4004}
4005
4006#[derive(Clone, Default)]
4007struct Interned<T>(T);
4008
4009impl<T> Eq for Interned<T>
4010where
4011 T: Deref,
4012 T::Target: Eq,
4013{
4014}
4015
4016impl<T> PartialEq for Interned<T>
4017where
4018 T: Deref,
4019 T::Target: PartialEq,
4020{
4021 #[inline(always)]
4022 fn eq(&self, other: &Self) -> bool {
4023 *self.0 == *other.0
4024 }
4025}
4026
4027impl<T> std::hash::Hash for Interned<T>
4028where
4029 T: Deref,
4030 T::Target: std::hash::Hash,
4031{
4032 #[inline(always)]
4033 fn hash<H>(&self, state: &mut H)
4034 where
4035 H: std::hash::Hasher,
4036 {
4037 (*self.0).hash(state)
4038 }
4039}
4040
4041impl<Id, T> Borrow<Type<Id, T>> for Interned<T>
4042where
4043 T: TypePtr<Id = Id>,
4044{
4045 fn borrow(&self) -> &Type<Id, T> {
4046 &self.0
4047 }
4048}
4049
4050pub trait TypeContextAlloc: TypePtr + Sized {
4051 fn alloc(into: &mut Self, typ: Type<Self::Id, Self>, flags: Flags);
4052}
4053
4054impl TypeContextAlloc for ArcType {
4055 fn alloc(into: &mut Self, typ: Type<Symbol, Self>, flags: Flags) {
4056 match Arc::get_mut(&mut into.typ) {
4057 Some(into) => {
4058 into.flags = flags;
4059 into.typ = typ;
4060 }
4061 None => {
4062 *into = Self::with_flags(typ, flags);
4063 }
4064 }
4065 }
4066}
4067
4068pub struct Interner<Id, T>
4069where
4070 T: TypeExt<Id = Id>,
4071 T::Types: Default + Extend<T> + FromIterator<T>,
4072{
4073 set: FnvMap<Interned<T>, ()>,
4074 scratch: Interned<T>,
4075 type_cache: TypeCache<Id, T>,
4076}
4077
4078impl<Id, T> Default for Interner<Id, T>
4079where
4080 T: Default + TypeExt<Id = Id> + From<Type<Id, T>> + Clone,
4081 T::Target: Eq + Hash,
4082 T::Types: Default + Extend<T> + FromIterator<T>,
4083{
4084 fn default() -> Self {
4085 let mut interner = Interner {
4086 set: Default::default(),
4087 scratch: Default::default(),
4088 type_cache: Default::default(),
4089 };
4090
4091 macro_rules! populate_builtins {
4092 ($($id: ident)*) => {
4093 $(
4094 let x = interner.type_cache.$id();
4095 interner.set.insert(Interned(x), ());
4096 )*
4097 }
4098 }
4099
4100 populate_builtins! {
4101 hole opaque error int byte float string char
4102 function_builtin array_builtin unit empty_row
4103 }
4104
4105 interner
4106 }
4107}
4108
4109macro_rules! forward_to_intern_cache {
4110 ($($id: ident)*) => {
4111 $(
4112 fn $id(&mut self) -> T {
4113 self.type_cache.$id()
4114 }
4115 )*
4116 }
4117}
4118
4119impl<Id, T> TypeContext<Id, T> for Interner<Id, T>
4120where
4121 T: TypeContextAlloc<Id = Id> + TypeExt<Id = Id> + Eq + Hash + Clone,
4122 T::Types: FromIterator<T>,
4123 T::Generics: FromIterator<Generic<Id>>,
4124 T::TypeFields: FromIterator<Field<T::SpannedId, Alias<Id, T>>>,
4125 T::SpannedId: Eq + Hash,
4126 Id: Eq + Hash,
4127{
4128 fn intern(&mut self, typ: Type<Id, T>) -> T {
4129 let flags = Flags::from_type(&typ);
4130 self.intern_flags(typ, flags)
4131 }
4132
4133 fn intern_types(&mut self, types: impl IntoIterator<Item = T>) -> T::Types {
4134 types.into_iter().collect()
4135 }
4136
4137 fn intern_generics(&mut self, types: impl IntoIterator<Item = Generic<Id>>) -> T::Generics {
4138 types.into_iter().collect()
4139 }
4140
4141 fn intern_fields(
4142 &mut self,
4143 types: impl IntoIterator<Item = Field<T::SpannedId, T>>,
4144 ) -> T::Fields {
4145 types.into_iter().collect()
4146 }
4147
4148 fn intern_type_fields(
4149 &mut self,
4150 types: impl IntoIterator<Item = Field<T::SpannedId, Alias<Id, T>>>,
4151 ) -> T::TypeFields {
4152 types.into_iter().collect()
4153 }
4154
4155 fn intern_flags(&mut self, typ: Type<Id, T>, flags: Flags) -> T {
4156 use std::collections::hash_map::Entry;
4157
4158 T::alloc(&mut self.scratch.0, typ, flags);
4159 match self.set.entry(self.scratch.clone()) {
4160 Entry::Occupied(entry) => return entry.key().0.clone(),
4161 Entry::Vacant(entry) => {
4162 entry.insert(());
4163 self.scratch.0.clone()
4164 }
4165 }
4166 }
4167
4168 forward_to_intern_cache! {
4169 hole opaque error int byte float string char
4170 function_builtin array_builtin unit empty_row
4171 }
4172}
4173
4174impl<'i, F, V> InternerVisitor<'i, F, V> {
4175 pub fn new<Id, T>(interner: &'i mut V, visitor: F) -> Self
4176 where
4177 F: FnMut(&mut V, &T) -> Option<T>,
4178 T: TypeExt<Id = Id>,
4179 V: TypeContext<Id, T>,
4180 {
4181 InternerVisitor { interner, visitor }
4182 }
4183
4184 pub fn control<Id, T>(
4185 interner: &'i mut V,
4186 visitor: F,
4187 ) -> InternerVisitor<'i, ControlVisitation<F>, V>
4188 where
4189 F: FnMut(&mut V, &T) -> Option<T>,
4190 T: TypeExt<Id = Id>,
4191 V: TypeContext<Id, T>,
4192 {
4193 InternerVisitor {
4194 interner,
4195 visitor: ControlVisitation(visitor),
4196 }
4197 }
4198}
4199
4200impl<'i, F, V, Id, T> TypeVisitor<Id, T> for InternerVisitor<'i, F, V>
4201where
4202 F: FnMut(&mut V, &T) -> Option<T>,
4203 Id: Clone,
4204 T::SpannedId: Clone,
4205 T: TypeExt<Id = Id, Types = AppVec<T>>,
4206 V: TypeContext<Id, T>,
4207 T::Generics: FromIterator<Generic<Id>> + Clone,
4208 T::Fields: FromIterator<Field<T::SpannedId, T>> + Clone,
4209{
4210 type Context = V;
4211
4212 fn context(&mut self) -> &mut Self::Context {
4213 &mut self.interner
4214 }
4215
4216 fn visit(&mut self, typ: &T) -> Option<T>
4217 where
4218 T: TypePtr<Id = Id> + Clone,
4219 Id: Clone,
4220 {
4221 let new_type = walk_move_type_opt(typ, self);
4222 let new_type2 = (self.visitor)(self.interner, new_type.as_ref().map_or(typ, |t| t));
4223 new_type2.or(new_type)
4224 }
4225}
4226
4227impl<'i, F, V, Id, T> TypeVisitor<Id, T> for InternerVisitor<'i, ControlVisitation<F>, V>
4228where
4229 F: FnMut(&mut V, &T) -> Option<T>,
4230 Id: Clone,
4231 T::SpannedId: Clone,
4232 T: TypeExt<Id = Id>,
4233 V: TypeContext<Id, T>,
4234 T::Types: Clone,
4235 T::Generics: Clone,
4236 T::Fields: Clone,
4237{
4238 type Context = V;
4239
4240 fn context(&mut self) -> &mut Self::Context {
4241 &mut self.interner
4242 }
4243
4244 fn visit(&mut self, typ: &T) -> Option<T>
4245 where
4246 T: TypePtr<Id = Id> + Clone,
4247 Id: Clone,
4248 {
4249 (self.visitor.0)(self.interner, typ)
4250 }
4251}
4252
4253pub struct ControlVisitation<F: ?Sized>(pub F);
4255
4256impl<F, Id, T> TypeVisitor<Id, T> for ControlVisitation<F>
4257where
4258 F: FnMut(&T) -> Option<T>,
4259 Id: Clone,
4260 T::SpannedId: Clone,
4261 T: TypeExt<Id = Id> + From<(Type<Id, T>, Flags)> + From<Type<Id, T>>,
4262 T::Types: FromIterator<T> + Clone,
4263 T::Generics: FromIterator<Generic<Id>> + Clone,
4264 T::Fields: FromIterator<Field<T::SpannedId, T>> + Clone,
4265{
4266 type Context = NullInterner;
4267
4268 fn context(&mut self) -> &mut Self::Context {
4269 NullInterner::new()
4270 }
4271
4272 fn visit(&mut self, typ: &T) -> Option<T>
4273 where
4274 T: TypePtr<Id = Id> + From<Type<Id, T>> + Clone,
4275 Id: Clone,
4276 {
4277 (self.0)(typ)
4278 }
4279}
4280
4281impl<'a, F, T> Walker<'a, T> for ControlVisitation<F>
4282where
4283 F: ?Sized + FnMut(&'a T),
4284 T: 'a,
4285{
4286 fn walk(&mut self, typ: &'a T) {
4287 (self.0)(typ)
4288 }
4289}
4290
4291pub struct FlagsVisitor<F: ?Sized>(pub Flags, pub F);
4292
4293impl<F, Id, T> TypeVisitor<Id, T> for FlagsVisitor<F>
4294where
4295 F: FnMut(&T) -> Option<T>,
4296 Id: Clone,
4297 T::SpannedId: Clone,
4298 T: TypeExt<Id = Id> + From<(Type<Id, T>, Flags)> + From<Type<Id, T>>,
4299 T::Types: FromIterator<T> + Clone,
4300 T::Generics: FromIterator<Generic<Id>> + Clone,
4301 T::Fields: FromIterator<Field<T::SpannedId, T>> + Clone,
4302{
4303 type Context = NullInterner;
4304
4305 fn context(&mut self) -> &mut Self::Context {
4306 NullInterner::new()
4307 }
4308
4309 fn visit(&mut self, typ: &T) -> Option<T>
4310 where
4311 T: TypePtr<Id = Id> + From<Type<Id, T>> + Clone,
4312 Id: Clone,
4313 {
4314 if self.0.intersects(typ.flags()) {
4315 let new_type = walk_move_type_opt(typ, self);
4316 let new_type2 = (self.1)(new_type.as_ref().map_or(typ, |t| t));
4317 new_type2.or(new_type)
4318 } else {
4319 None
4320 }
4321 }
4322}
4323
4324impl<'a, T, F> Walker<'a, T> for FlagsVisitor<F>
4325where
4326 F: ?Sized + FnMut(&'a T),
4327 T: TypeExt + 'a,
4328{
4329 fn walk(&mut self, typ: &'a T) {
4330 if self.0.intersects(typ.flags()) {
4331 (self.1)(typ);
4332 walk_type_(typ, self);
4333 }
4334 }
4335}
4336
4337impl<'a, I, T, F> Walker<'a, T> for F
4338where
4339 F: ?Sized + FnMut(&'a T),
4340 T: TypePtr<Id = I> + 'a,
4341 I: 'a,
4342{
4343 fn walk(&mut self, typ: &'a T) {
4344 self(typ);
4345 walk_type_(typ, self)
4346 }
4347}
4348
4349pub trait WalkerMut<T> {
4350 fn walk_mut(&mut self, typ: &mut T);
4351}
4352
4353impl<Id, T, F: ?Sized> WalkerMut<T> for F
4354where
4355 F: FnMut(&mut T),
4356 T: TypePtr<Id = Id> + DerefMut<Target = Type<Id, T>>,
4357 T::Types: DerefMut<Target = [T]>,
4358 T::Fields: DerefMut<Target = [Field<T::SpannedId, T>]>,
4359 T::TypeFields: DerefMut<Target = [Field<T::SpannedId, Alias<Id, T>>]>,
4360{
4361 fn walk_mut(&mut self, typ: &mut T) {
4362 self(typ);
4363 walk_type_mut(typ, self)
4364 }
4365}
4366
4367pub fn walk_move_type<F: ?Sized, I, T>(typ: T, f: &mut F) -> T
4369where
4370 F: TypeVisitor<I, T>,
4371 T: TypePtr<Id = I> + Clone,
4372 T::Types: Clone,
4373 T::Generics: Clone,
4374 T::Fields: Clone,
4375 T::TypeFields: Clone,
4376 T::SpannedId: Clone,
4377 I: Clone,
4378{
4379 f.visit(&typ).unwrap_or(typ)
4380}
4381
4382pub fn visit_type_opt<F: ?Sized, I, T>(typ: &T, f: &mut F) -> Option<T>
4383where
4384 F: TypeVisitor<I, T>,
4385 T: TypePtr<Id = I> + Clone,
4386 T::Types: Clone,
4387 T::Generics: Clone,
4388 T::Fields: Clone,
4389 T::TypeFields: Clone,
4390 T::SpannedId: Clone,
4391 I: Clone,
4392{
4393 f.visit(typ)
4394}
4395
4396pub fn walk_move_type_opt<F: ?Sized, I, T>(typ: &Type<I, T>, f: &mut F) -> Option<T>
4397where
4398 F: TypeVisitor<I, T>,
4399 T: TypePtr<Id = I> + Clone,
4400 T::Types: Clone,
4401 T::Generics: Clone,
4402 T::Fields: Clone,
4403 T::TypeFields: Clone,
4404 T::SpannedId: Clone,
4405 I: Clone,
4406{
4407 match *typ {
4408 Type::Forall(ref args, ref typ) => f.visit(typ).map(|typ| f.forall(args.clone(), typ)),
4409
4410 Type::Function(arg_type, ref arg, ref ret) => {
4411 let new_arg = f.visit(arg);
4412 let new_ret = f.visit(ret);
4413 merge(arg, new_arg, ret, new_ret, |arg, ret| {
4414 f.make(Type::Function(arg_type, arg, ret))
4415 })
4416 }
4417 Type::App(ref id, ref args) => {
4418 let new_args = walk_move_types(f, args.iter(), |f, t| f.visit(t))
4420 .map(|args: Vec<_>| f.make_types(args));
4421 merge(id, f.visit(id), args, new_args, |x, y| f.app(x, y))
4422 }
4423 Type::Record(ref row) => f.visit(row).map(|row| f.make(Type::Record(row))),
4424 Type::Variant(ref row) => f.visit(row).map(|row| f.make(Type::Variant(row))),
4425 Type::Effect(ref row) => f.visit(row).map(|row| f.make(Type::Effect(row))),
4426 Type::ExtendRow {
4427 ref fields,
4428 ref rest,
4429 } => {
4430 let new_fields = walk_move_types(f, fields.iter(), |f, field| {
4431 f.visit(&field.typ)
4432 .map(|typ| Field::new(field.name.clone(), typ))
4433 })
4434 .map(|args: Vec<_>| f.context().intern_fields(args));
4435 let new_rest = f.visit(rest);
4436 merge(fields, new_fields, rest, new_rest, |fields, rest| {
4437 f.make(Type::ExtendRow { fields, rest })
4438 })
4439 }
4440 Type::ExtendTypeRow {
4441 ref types,
4442 ref rest,
4443 } => {
4444 let new_rest = f.visit(rest);
4445 new_rest.map(|rest| {
4446 f.make(Type::ExtendTypeRow {
4447 types: types.clone(),
4448 rest,
4449 })
4450 })
4451 }
4452 Type::Hole
4453 | Type::Opaque
4454 | Type::Error
4455 | Type::Builtin(_)
4456 | Type::Variable(_)
4457 | Type::Skolem(_)
4458 | Type::Generic(_)
4459 | Type::Ident(_)
4460 | Type::Projection(_)
4461 | Type::Alias(_)
4462 | Type::EmptyRow => None,
4463 }
4464}
4465
4466pub fn walk_move_types<'a, I, F, T, S, R>(state: &mut S, types: I, f: F) -> Option<R>
4467where
4468 S: ?Sized,
4469 I: IntoIterator<Item = &'a T>,
4470 I::IntoIter: FusedIterator + Clone,
4471 F: FnMut(&mut S, &'a T) -> Option<T>,
4472 T: Clone + 'a,
4473 R: FromIterator<T>,
4474{
4475 merge_collect(state, types, f, |_, e| e.clone())
4476}
4477
4478pub fn translate_alias<Id, T, U, F, I>(
4479 interner: &mut I,
4480 alias: &AliasData<Id, T>,
4481 mut translate: F,
4482) -> AliasData<Id, U>
4483where
4484 T: TypePtr<Id = Id>,
4485 U: TypePtr<Id = Id>,
4486 Id: Clone,
4487 T::SpannedId: Clone,
4488 F: FnMut(&mut I, &T) -> U,
4489 I: TypeContext<Id, U>,
4490{
4491 AliasData {
4492 name: alias.name.clone(),
4493 args: interner.intern_generics(alias.args.iter().cloned()),
4494 typ: translate(interner, &alias.typ),
4495 is_implicit: alias.is_implicit,
4496 }
4497}
4498
4499pub fn translate_type<Id, T, U>(interner: &mut impl TypeContext<Id, U>, arc_type: &T) -> U
4500where
4501 T: TypePtr<Id = Id>,
4502 U: TypePtr<Id = Id>,
4503 Id: Clone,
4504 T::SpannedId: Into<U::SpannedId>,
4505 T::SpannedId: Clone,
4506{
4507 translate_type_with(interner, arc_type, |interner, typ| {
4508 translate_type(interner, typ)
4509 })
4510}
4511
4512pub fn translate_type_with<Id, T, U, I, F>(
4513 interner: &mut I,
4514 typ: &Type<Id, T>,
4515 mut translate: F,
4516) -> U
4517where
4518 T: TypePtr<Id = Id>,
4519 U: TypePtr<Id = Id>,
4520 Id: Clone,
4521 T::SpannedId: Into<U::SpannedId>,
4522 T::SpannedId: Clone,
4523 F: FnMut(&mut I, &T) -> U,
4524 I: TypeContext<Id, U>,
4525{
4526 macro_rules! intern {
4527 ($e: expr) => {{
4528 let t = $e;
4529 interner.intern(t)
4530 }};
4531 }
4532 match *typ {
4533 Type::Function(arg_type, ref arg, ref ret) => {
4534 let t = Type::Function(arg_type, translate(interner, arg), translate(interner, ret));
4535 interner.intern(t)
4536 }
4537 Type::App(ref f, ref args) => {
4538 let f = translate(interner, f);
4539 let args = args
4540 .iter()
4541 .map(|typ| translate(interner, typ))
4542 .collect::<SmallVec<[_; 5]>>();
4543 let t = Type::App(f, interner.intern_types(args));
4544 interner.intern(t)
4545 }
4546 Type::Record(ref row) => intern!(Type::Record(translate(interner, row))),
4547 Type::Variant(ref row) => intern!(Type::Variant(translate(interner, row))),
4548 Type::Effect(ref row) => intern!(Type::Effect(translate(interner, row))),
4549 Type::Forall(ref params, ref typ) => {
4550 let t = Type::Forall(
4551 interner.intern_generics(params.iter().cloned()),
4552 translate(interner, typ),
4553 );
4554 interner.intern(t)
4555 }
4556 Type::Skolem(ref skolem) => interner.intern(Type::Skolem(Skolem {
4557 name: skolem.name.clone(),
4558 id: skolem.id.clone(),
4559 kind: skolem.kind.clone(),
4560 })),
4561 Type::ExtendRow {
4562 ref fields,
4563 ref rest,
4564 } => {
4565 let fields = fields
4566 .iter()
4567 .map(|field| Field {
4568 name: field.name.clone().into(),
4569 typ: translate(interner, &field.typ),
4570 })
4571 .collect::<SmallVec<[_; 10]>>();
4572 let fields = interner.intern_fields(fields);
4573
4574 let rest = translate(interner, rest);
4575
4576 interner.extend_row(fields, rest)
4577 }
4578 Type::ExtendTypeRow {
4579 ref types,
4580 ref rest,
4581 } => {
4582 let types = types
4583 .iter()
4584 .map(|field| Field {
4585 name: field.name.clone().into(),
4586 typ: Alias {
4587 _typ: translate(interner, &field.typ.as_type()),
4588 _marker: PhantomData,
4589 },
4590 })
4591 .collect::<SmallVec<[_; 10]>>();
4592 let types = interner.intern_type_fields(types);
4593 let rest = translate(interner, rest);
4594
4595 interner.extend_type_row(types, rest)
4596 }
4597 Type::Hole => interner.hole(),
4598 Type::Opaque => interner.opaque(),
4599 Type::Error => interner.error(),
4600 Type::Builtin(ref builtin) => interner.builtin_type(builtin.clone()),
4601 Type::Variable(ref var) => interner.variable(var.clone()),
4602 Type::Generic(ref gen) => interner.generic(gen.clone()),
4603 Type::Ident(ref id) => interner.ident(id.clone()),
4604 Type::Projection(ref ids) => interner.projection(ids.clone()),
4605 Type::Alias(ref alias) => {
4606 let group: Vec<_> = alias
4607 .group
4608 .iter()
4609 .map(|alias_data| {
4610 translate_alias(interner, alias_data, |interner, a| translate(interner, a))
4611 })
4612 .collect();
4613
4614 interner.intern(Type::Alias(AliasRef {
4615 index: alias.index,
4616 group: Arc::from(group),
4617 }))
4618 }
4619 Type::EmptyRow => interner.empty_row(),
4620 }
4621}
4622
4623#[cfg(test)]
4624mod tests {
4625 use super::*;
4626
4627 #[cfg(target_pointer_width = "64")]
4628 const _: [(); 8 * 5] = [(); std::mem::size_of::<Type<Symbol, ArcType>>()];
4630
4631 #[test]
4632 fn walk_move_types_test() {
4633 assert_eq!(
4634 walk_move_types(&mut (), [1, 2, 3].iter(), |_, i| if *i == 2 {
4635 Some(4)
4636 } else {
4637 None
4638 }),
4639 Some(vec![1, 4, 3])
4640 );
4641 }
4642}