/// Given a `def_list` produced by the `chase_actor` function, infer which types are recursive
Given a `def_list` produced by the `chase_actor` function, infer which types are recursive
Given a ` def_list ` produced by the ` chase_actor ` function infer which types are recursive
pub fn infer_rec<'a>(env: &'a TypeEnv, def_list: &'a [&'a str]) -> Result<BTreeSet<&'a str>> {
    let mut seen = BTreeSet::new();
    let mut res = BTreeSet::new();
    fn go<'a>(
        seen: &mut BTreeSet<&'a str>,
        res: &mut BTreeSet<&'a str>,
        env: &'a TypeEnv,
        t: &'a Type,
    ) -> Result<()> {
        use Type::*;
        match t {
            Var(id) => {
                if seen.insert(id) {
                    res.insert(id);
                }
            }
            Opt(ty) | Vec(ty) => go(seen, res, env, ty)?,
            Record(fs) | Variant(fs) => {
                for f in fs.iter() {
                    go(seen, res, env, &f.ty)?;
                }
            }
            Func(f) => {
                for ty in f.args.iter().chain(f.rets.iter()) {
                    go(seen, res, env, ty)?;
                }
            }
            Service(ms) => {
                for (_, ty) in ms.iter() {
                    go(seen, res, env, ty)?;
                }
            }
            Class(args, t) => {
                for arg in args.iter() {
                    go(seen, res, env, arg)?;
                }
                go(seen, res, env, t)?;
            }
            _ => (),
        }
        Ok(())
    }
    for var in def_list.iter() {
        let t = env.0.get(*var).unwrap();
        go(&mut seen, &mut res, env, t)?;
        seen.insert(var);
    }
    Ok(res)
}
pub fn infer_rec < ' a > ( env : & ' a TypeEnv , def_list : & ' a [ & ' a str ] ) -> Result < BTreeSet < & ' a str > > { let mut seen = BTreeSet :: new ( ) ; let mut res = BTreeSet :: new ( ) ; fn go < ' a > ( seen : & mut BTreeSet < & ' a str > , res : & mut BTreeSet < & ' a str > , env : & ' a TypeEnv , t : & ' a Type , ) -> Result < ( ) > { use Type :: * ; match t { Var ( id ) => { if seen . insert ( id ) { res . insert ( id ) ; } } Opt ( ty ) | Vec ( ty ) => go ( seen , res , env , ty ) ? , Record ( fs ) | Variant ( fs ) => { for f in fs . iter ( ) { go ( seen , res , env , & f . ty ) ? ; } } Func ( f ) => { for ty in f . args . iter ( ) . chain ( f . rets . iter ( ) ) { go ( seen , res , env , ty ) ? ; } } Service ( ms ) => { for ( _ , ty ) in ms . iter ( ) { go ( seen , res , env , ty ) ? ; } } Class ( args , t ) => { for arg in args . iter ( ) { go ( seen , res , env , arg ) ? ; } go ( seen , res , env , t ) ? ; } _ => ( ) , } Ok ( ( ) ) } for var in def_list . iter ( ) { let t = env . 0 . get ( * var ) . unwrap ( ) ; go ( & mut seen , & mut res , env , t ) ? ; seen . insert ( var ) ; } Ok ( res ) }
Given a `def_list` produced by the `chase_actor` function, infer which types are recursive
Given a ` def_list ` produced by the ` chase_actor ` function infer which types are recursive
env
&'a TypeEnv
def_list
&'a [&'a str]