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
use std::collections::HashMap;

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

fn resolve_ref_to_purity(
    pvar_purities: &HashMap<purity::PVarId, purity::Ref>,
    poly: &purity::Ref,
) -> Purity {
    match poly {
        purity::Ref::Fixed(purity) => *purity,
        purity::Ref::Var(pvar) => {
            let inner_ref = pvar_purities
                .get(pvar)
                .expect("Unable to find PVar determining fun apply purity");

            resolve_ref_to_purity(pvar_purities, inner_ref)
        }
    }
}

/// Returns the purity for a fun application
pub fn fun_app_purity(
    pvar_purities: &HashMap<purity::PVarId, purity::Ref>,
    fun_purity: &purity::Ref,
    fun_ret_ty: &ty::Ref<ty::Poly>,
) -> Purity {
    if fun_ret_ty.is_never() {
        // This is a hack for things like `panic`. Pure funs are allowed to panic but if they
        // return `(U)` they're likely only called to terminate the program. Without this `panic`
        // would be optimised away.
        return Purity::Impure;
    }

    resolve_ref_to_purity(pvar_purities, fun_purity)
}