1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use std::collections::HashMap;

use crate::ty;
use crate::ty::purity;
use crate::ty::purity::Purity;

/// Type arguments to a polymorphic function or substitution
#[derive(PartialEq, Clone, Debug)]
pub struct TyArgs<M: ty::Pm> {
    pvar_purities: HashMap<purity::PVarId, purity::Ref>,
    tvar_types: HashMap<ty::TVarId, ty::Ref<M>>,
}

impl<M: ty::Pm> TyArgs<M> {
    pub fn new(
        pvar_purities: HashMap<purity::PVarId, purity::Ref>,
        tvar_types: HashMap<ty::TVarId, ty::Ref<M>>,
    ) -> Self {
        Self {
            pvar_purities,
            tvar_types,
        }
    }

    pub fn empty() -> Self {
        Self {
            pvar_purities: HashMap::new(),
            tvar_types: HashMap::new(),
        }
    }

    pub fn pvar_purities(&self) -> &HashMap<purity::PVarId, purity::Ref> {
        &self.pvar_purities
    }

    pub fn tvar_types(&self) -> &HashMap<ty::TVarId, ty::Ref<M>> {
        &self.tvar_types
    }
}

impl TyArgs<ty::Poly> {
    /// Returns the args for the passed pvars/tvars where all args are set to their upper bound
    pub fn from_upper_bound(pvars: &[purity::PVarId], tvars: &[ty::TVarId]) -> Self {
        let pvar_purities = pvars
            .iter()
            .map(|pvar| (pvar.clone(), Purity::Impure.into()))
            .collect();

        let tvar_types = tvars
            .iter()
            .map(|tvar| (tvar.clone(), tvar.bound.clone()))
            .collect();

        Self {
            pvar_purities,
            tvar_types,
        }
    }
}