gluon_base/types/
mod.rs

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
98/// Trait for values which contains typed values which can be refered by name
99pub trait TypeEnv: KindEnv {
100    type Type;
101    /// Returns the type of the value bound at `id`
102    fn find_type(&self, id: &SymbolRef) -> Option<Self::Type>;
103
104    /// Returns information about the type `id`
105    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
132/// Trait which is a `TypeEnv` which also provides access to the type representation of some
133/// primitive types
134pub 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/// All the builtin types of gluon
247#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
248#[cfg_attr(feature = "serde_derive", derive(Deserialize, Serialize))]
249pub enum BuiltinType {
250    /// Unicode string
251    String,
252    /// Unsigned byte
253    Byte,
254    /// Character
255    Char,
256    /// Integer number
257    Int,
258    /// Floating point number
259    Float,
260    /// Type constructor for arrays, `Array a : Type -> Type`
261    Array,
262    /// Type constructor for functions, `(->) a b : Type -> Type -> Type`
263    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/// FIXME Distinguish generic id's so we only need to compare them by `id` (currently they will get
341/// the wrong kind assigned to them otherwise)
342#[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/// An alias is wrapper around `Type::Alias`, allowing it to be cheaply converted to a type and
370/// dereferenced to `AliasRef`
371#[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    /// Returns the actual type of the alias
512    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(&params[..]);
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/// Data for a type alias. Probably you want to use `Alias` instead of this directly as Alias allows
549/// for cheap conversion back into a type as well.
550#[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    /// Name of the Alias
574    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    /// The other aliases defined in this group
584    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                // Replace `Ident` with the alias it resolves to so that a `TypeEnv` is not
673                // needed to resolve the type later on
674                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    /// The type that is being aliased
727    #[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    /// Returns the type aliased by `self` with out `Type::Ident` resolved to their actual
737    /// `Type::Alias` representation
738    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
850/// `SmallVec` used in the `Type::App` constructor to avoid allocating a `Vec` for every applied
851/// type. If `Type` is changed in a way that changes its size it is likely a good idea to change
852/// the number of elements in the `SmallVec` so that it fills out the entire `Type` enum while not
853/// increasing the size of `Type`.
854pub 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/// The representation of gluon's types.
909///
910/// For efficiency this enum is not stored directly but instead a pointer wrapper which derefs to
911/// `Type` is used to enable types to be shared. It is recommended to use the static functions on
912/// `Type` such as `Type::app` and `Type::record` when constructing types as those will construct
913/// the pointer wrapper directly.
914#[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    /// An unbound type `_`, awaiting ascription.
949    Hole,
950    /// An opaque type
951    Opaque,
952    /// A type used to mark type errors
953    Error,
954    /// A builtin type
955    Builtin(BuiltinType),
956    /// Universally quantified types
957    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    /// A type application with multiple arguments. For example,
966    /// `Map String Int` would be represented as `App(Map, [String, Int])`.
967    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 type which can have a explicit or implicit argument
976    Function(
977        ArgType,
978        #[cfg_attr(feature = "serde_derive", serde(state))] T,
979        #[cfg_attr(feature = "serde_derive", serde(state))] T,
980    ),
981    /// Record constructor, of kind `Row -> Type`
982    Record(#[cfg_attr(feature = "serde_derive", serde(state))] T),
983    /// Variant constructor, of kind `Row -> Type`
984    Variant(#[cfg_attr(feature = "serde_derive", serde(state))] T),
985    /// Effect constructor, of kind `Row -> Type -> Type`
986    Effect(#[cfg_attr(feature = "serde_derive", serde(state))] T),
987    /// The empty row, of kind `Row`
988    EmptyRow,
989    /// Row extension, of kind `... -> Row -> Row`
990    ExtendRow {
991        /// The fields of this record type
992        #[cfg_attr(feature = "serde_derive", serde(state))]
993        fields: T::Fields,
994        /// The rest of the row
995        #[cfg_attr(feature = "serde_derive", serde(state))]
996        rest: T,
997    },
998    /// Row extension, of kind `... -> Row -> Row`
999    ExtendTypeRow {
1000        /// The associated types of this record type
1001        #[cfg_attr(feature = "serde_derive", serde(state))]
1002        types: T::TypeFields,
1003        /// The rest of the row
1004        #[cfg_attr(feature = "serde_derive", serde(state))]
1005        rest: T,
1006    },
1007    /// An identifier type. These are created during parsing, but should all be
1008    /// resolved into `Type::Alias`es during type checking.
1009    ///
1010    /// Identifiers are also sometimes used inside aliased types to avoid cycles
1011    /// in reference counted pointers. This is a bit of a wart at the moment and
1012    /// _may_ cause spurious unification failures.
1013    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    /// An unbound type variable that may be unified with other types. These
1022    /// will eventually be converted into `Type::Generic`s during generalization.
1023    Variable(#[cfg_attr(feature = "serde_derive", serde(state))] TypeVariable),
1024    /// A variable that needs to be instantiated with a fresh type variable
1025    /// when the binding is referred to.
1026    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            // FIXME can be another kind
1410            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    /// Returns the name of `self`
1444    /// Example:
1445    /// Option a => Option
1446    /// Int => Int
1447    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/// A shared type which is atomically reference counted
1553#[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    /// Returns an iterator over all type fields in a record.
1759    /// `{ Test, Test2, x, y } => [Test, Test2]`
1760    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    /// Returns an iterator over all fields in a record.
1773    /// `{ Test, Test2, x, y } => [x, y]`
1774    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(&param.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    /// Applies a list of arguments to a parameterised type, returning `Some`
1876    /// if the substitution was successful.
1877    ///
1878    /// Example:
1879    ///
1880    /// ```text
1881    /// self = forall e t . | Err e | Ok t
1882    /// args = [Error, Option a]
1883    /// result = | Err Error | Ok (Option a)
1884    /// ```
1885    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 the alias was just hiding an error then any application is also an error as we have
1926        // no way of knowing how many arguments it should take
1927        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            // It is ok to take the type only if it is fully applied or if it
1935            // the missing argument only appears in order at the end, i.e:
1936            //
1937            // type Test a b c = Type (a Int) b c
1938            //
1939            // Test a b == Type (a Int) b
1940            // Test a == Type (a Int)
1941            // Test == ??? (Impossible to do a sane substitution)
1942            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            // Remove the args at the end of the aliased type
1957            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(&params[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    /// The current type being iterated over. After `None` has been returned this is the return
2371    /// type.
2372    pub typ: &'a T,
2373}
2374
2375/// Constructs an iterator over a functions arguments
2376pub 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    /// The current type being iterated over. After `None` has been returned this is the return
2399    /// type.
2400    pub typ: &'a T,
2401}
2402
2403/// Constructs an iterator over a functions arguments
2404pub 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    /// Returns the lowest level which this type contains. The level informs from where type
2447    /// variables where created.
2448    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    /// The type exists in the top context, no parentheses needed.
2506    Top,
2507    /// The type exists in a function argument `Type -> a`, parentheses are
2508    /// needed if the type is a function `(b -> c) -> a`.
2509    Function,
2510    /// The type exists in a constructor argument `Option Type`, parentheses
2511    /// are needed for functions or other constructors `Option (a -> b)`
2512    /// `Option (Result a b)`.
2513    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            // This should not be displayed normally as it should only exist in `ExtendRow`
2781            // which handles `EmptyRow` explicitly
2782            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                // Records handle nesting on their own
2924                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        /*
3427           Avoid forwarding methods that take an iterator as they can cause panics when using `RefCell`
3428
3429        fn tuple<S, I>(&mut self, symbols: &mut S, elems: I) -> $typ
3430        where
3431            S: ?Sized + $crate::ast::IdentEnv<Ident = $id>,
3432            I: IntoIterator<Item = $typ>,
3433        {
3434            $crate::expr!(self, $($tokens)+).tuple(symbols, elems)
3435        }
3436
3437        fn tuple_<S, I>(&mut self, symbols: &mut S, elems: I) -> $crate::types::Type<$id, $typ>
3438        where
3439            S: ?Sized + $crate::ast::IdentEnv<Ident = $id>,
3440            I: IntoIterator<Item = $typ>,
3441        {
3442            $crate::expr!(self, $($tokens)+).tuple_(symbols, elems)
3443        }
3444
3445        fn function<I>(&mut self, args: I, ret: $typ) -> $typ
3446        where
3447            $typ: Clone,
3448            I: IntoIterator<Item = $typ>,
3449            I::IntoIter: DoubleEndedIterator<Item = $typ>,
3450        {
3451            $crate::expr!(self, $($tokens)+).function( args, ret)
3452        }
3453
3454        fn function_implicit<I>(&mut self, args: I, ret: $typ) -> $typ
3455        where
3456            I: IntoIterator<Item = $typ>,
3457            I::IntoIter: DoubleEndedIterator<Item = $typ>,
3458        {
3459            $crate::expr!(self, $($tokens)+).function_implicit(args, ret)
3460        }
3461
3462        fn function_type<I>(&mut self, arg_type: $crate::types::ArgType, args: I, ret: $typ) -> $typ
3463        where
3464            I: IntoIterator<Item = $typ>,
3465            I::IntoIter: DoubleEndedIterator<Item = $typ>,
3466        {
3467            $crate::expr!(self, $($tokens)+).function_type(arg_type, args, ret)
3468        }
3469        */
3470
3471        $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        // SAFETY NullInterner is zero-sized
3822        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
4253/// Wrapper type which allows functions to control how to traverse the members of the type
4254pub 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
4367/// Walks through a type calling `f` on each inner type. If `f` return `Some` the type is replaced.
4368pub 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            // TODO Avoid Vec allocation
4419            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    // Safeguard against accidentally growing Type as it is a core type
4629    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}