fn instantiate(
    t: Type,
    ctx_level: usize,
    ids: &mut im::HashMap<usize, Type>,
    env: &mut Env,
) -> Type {
    match t {
        Type::App {
            public,
            name,
            module,
            args,
        } => {
            let args = args
                .into_iter()
                .map(|t| instantiate(t, ctx_level, ids, env))
                .collect();
            Type::App {
                public,
                name,
                module,
                args,
            }
        }

        Type::Var { typ } => {
            match &*typ.borrow() {
                TypeVar::Link { typ } => return instantiate(*typ.clone(), ctx_level, ids, env),

                TypeVar::Unbound { .. } => return Type::Var { typ: typ.clone() },

                TypeVar::Generic { id } => match ids.get(id) {
                    Some(t) => return t.clone(),
                    None => {
                        if !env.annotated_generic_types.contains(id) {
                            let v = env.new_unbound_var(ctx_level);
                            ids.insert(*id, v.clone());
                            return v;
                        }
                    }
                },
            }
            Type::Var { typ }
        }

        Type::Fn { args, retrn, .. } => {
            let args = args
                .into_iter()
                .map(|t| instantiate(t, ctx_level, ids, env))
                .collect();
            let retrn = Box::new(instantiate(*retrn, ctx_level, ids, env));
            Type::Fn { args, retrn }
        }

        Type::Tuple { elems } => Type::Tuple {
            elems: elems
                .into_iter()
                .map(|t| instantiate(t, ctx_level, ids, env))
                .collect(),
        },
    }
}
/// Instantiate converts generic variables into unbound ones.
///
Instantiate converts generic variables into unbound ones.
Instantiate converts generic variables into unbound ones .
fn instantiate(
    t: Type,
    ctx_level: usize,
    ids: &mut im::HashMap<usize, Type>,
    env: &mut Env,
) -> Type {
    match t {
        Type::App {
            public,
            name,
            module,
            args,
        } => {
            let args = args
                .into_iter()
                .map(|t| instantiate(t, ctx_level, ids, env))
                .collect();
            Type::App {
                public,
                name,
                module,
                args,
            }
        }
        Type::Var { typ } => {
            match &*typ.borrow() {
                TypeVar::Link { typ } => return instantiate(*typ.clone(), ctx_level, ids, env),
                TypeVar::Unbound { .. } => return Type::Var { typ: typ.clone() },
                TypeVar::Generic { id } => match ids.get(id) {
                    Some(t) => return t.clone(),
                    None => {
                        if !env.annotated_generic_types.contains(id) {
                            let v = env.new_unbound_var(ctx_level);
                            ids.insert(*id, v.clone());
                            return v;
                        }
                    }
                },
            }
            Type::Var { typ }
        }
        Type::Fn { args, retrn, .. } => {
            let args = args
                .into_iter()
                .map(|t| instantiate(t, ctx_level, ids, env))
                .collect();
            let retrn = Box::new(instantiate(*retrn, ctx_level, ids, env));
            Type::Fn { args, retrn }
        }
        Type::Tuple { elems } => Type::Tuple {
            elems: elems
                .into_iter()
                .map(|t| instantiate(t, ctx_level, ids, env))
                .collect(),
        },
    }
}
fn instantiate ( t : Type , ctx_level : usize , ids : & mut im :: HashMap < usize , Type > , env : & mut Env , ) -> Type { match t { Type :: App { public , name , module , args , } => { let args = args . into_iter ( ) . map ( | t | instantiate ( t , ctx_level , ids , env ) ) . collect ( ) ; Type :: App { public , name , module , args , } } Type :: Var { typ } => { match & * typ . borrow ( ) { TypeVar :: Link { typ } => return instantiate ( * typ . clone ( ) , ctx_level , ids , env ) , TypeVar :: Unbound { .. } => return Type :: Var { typ : typ . clone ( ) } , TypeVar :: Generic { id } => match ids . get ( id ) { Some ( t ) => return t . clone ( ) , None => { if ! env . annotated_generic_types . contains ( id ) { let v = env . new_unbound_var ( ctx_level ) ; ids . insert ( * id , v . clone ( ) ) ; return v ; } } } , } Type :: Var { typ } } Type :: Fn { args , retrn , .. } => { let args = args . into_iter ( ) . map ( | t | instantiate ( t , ctx_level , ids , env ) ) . collect ( ) ; let retrn = Box :: new ( instantiate ( * retrn , ctx_level , ids , env ) ) ; Type :: Fn { args , retrn } } Type :: Tuple { elems } => Type :: Tuple { elems : elems . into_iter ( ) . map ( | t | instantiate ( t , ctx_level , ids , env ) ) . collect ( ) , } , } }
Instantiate converts generic variables into unbound ones.
Instantiate converts generic variables into unbound ones .
t
Type
ctx_level
usize
ids
&mut im::HashMap<usize, Type>
env
&mut Env
t
Type
ctx_level
usize
ids
&mut im::HashMap<usize, Type>
env
&mut Env