fn lower_repr_ty(path: &Path, ty: &core::RcType) -> RcType {
    match *ty.inner {
        core::Type::HostVar(ref var) => lower_ty_var(var),
        core::Type::Const(ty_const) => Type::Const(ty_const).into(),
        core::Type::Arrow(ref arg_tys, ref ret_ty) => {
            let arg_repr_tys = arg_tys
                .iter()
                .map(|arg_ty| lower_repr_ty(path, arg_ty))
                .collect();
            let ret_repr_ty = lower_repr_ty(path, ret_ty);

            Type::Arrow(arg_repr_tys, ret_repr_ty).into()
        }
        core::Type::Lam(_, _, _) => {
            // Due to the way our surface syntax is defined, the only type
            // abstractions we should encounter are those that are defined on
            // top-level definitions. Thes should have already been handled in
            // the `From<&'a core::Module>` impl for `Module`.
            panic!("ICE: encountered unexpected type abstraction: {:?}", ty)
        }
        core::Type::App(_, ref ty, ref param_tys) => {
            let lowered_ty = lower_repr_ty(path, ty);

            // Replace empty parameter lists on paths with the supplied parameters
            // TODO: This feels rather hacky! I'm sure it will break in non-trivial cases.
            // surely there is a better way to handle this?
            if let Type::Path(ref path, ref params) = *lowered_ty.inner {
                assert!(params.is_empty(), "ICE: Params not empty: {:?}", params);

                let lowered_params = param_tys
                    .iter()
                    .enumerate()
                    .map(|(i, ty)| lower_repr_ty(&path.append_child(format!("Arg{}", i)), ty))
                    .collect::<Vec<_>>();

                return Type::Path(path.clone(), lowered_params).into();
            }

            lowered_ty
        }

        core::Type::HostArray(ref elem_ty) => {
            let elem_path = path.append_child("Elem");
            let elem_ty = lower_repr_ty(&elem_path, elem_ty);

            Type::Array(elem_ty).into()
        }
        core::Type::HostUnion(_) | core::Type::HostStruct(_) => {
            // We expect that the repr type has already had a corresponding type
            // generated for it, so instead we just return the current path.
            Type::Path(path.clone(), vec![]).into()
        }

        _ => unimplemented!(),
    }
}
/// Lower host types to the nominal format
///
/// # Arguments
///
/// * `path` - path to the parent struct or union
/// * `ty` - the type to be lowered
Lower host types to the nominal format
Lower host types to the nominal format
fn lower_repr_ty(path: &Path, ty: &core::RcType) -> RcType {
    match *ty.inner {
        core::Type::HostVar(ref var) => lower_ty_var(var),
        core::Type::Const(ty_const) => Type::Const(ty_const).into(),
        core::Type::Arrow(ref arg_tys, ref ret_ty) => {
            let arg_repr_tys = arg_tys
                .iter()
                .map(|arg_ty| lower_repr_ty(path, arg_ty))
                .collect();
            let ret_repr_ty = lower_repr_ty(path, ret_ty);
            Type::Arrow(arg_repr_tys, ret_repr_ty).into()
        }
        core::Type::Lam(_, _, _) => {
            // Due to the way our surface syntax is defined, the only type
            // abstractions we should encounter are those that are defined on
            // top-level definitions. Thes should have already been handled in
            // the `From<&'a core::Module>` impl for `Module`.
            panic!("ICE: encountered unexpected type abstraction: {:?}", ty)
        }
        core::Type::App(_, ref ty, ref param_tys) => {
            let lowered_ty = lower_repr_ty(path, ty);
            // Replace empty parameter lists on paths with the supplied parameters
            // TODO: This feels rather hacky! I'm sure it will break in non-trivial cases.
            // surely there is a better way to handle this?
            if let Type::Path(ref path, ref params) = *lowered_ty.inner {
                assert!(params.is_empty(), "ICE: Params not empty: {:?}", params);
                let lowered_params = param_tys
                    .iter()
                    .enumerate()
                    .map(|(i, ty)| lower_repr_ty(&path.append_child(format!("Arg{}", i)), ty))
                    .collect::<Vec<_>>();
                return Type::Path(path.clone(), lowered_params).into();
            }
            lowered_ty
        }
        core::Type::HostArray(ref elem_ty) => {
            let elem_path = path.append_child("Elem");
            let elem_ty = lower_repr_ty(&elem_path, elem_ty);
            Type::Array(elem_ty).into()
        }
        core::Type::HostUnion(_) | core::Type::HostStruct(_) => {
            // We expect that the repr type has already had a corresponding type
            // generated for it, so instead we just return the current path.
            Type::Path(path.clone(), vec![]).into()
        }
        _ => unimplemented!(),
    }
}
fn lower_repr_ty ( path : & Path , ty : & core :: RcType ) -> RcType { match * ty . inner { core :: Type :: HostVar ( ref var ) => lower_ty_var ( var ) , core :: Type :: Const ( ty_const ) => Type :: Const ( ty_const ) . into ( ) , core :: Type :: Arrow ( ref arg_tys , ref ret_ty ) => { let arg_repr_tys = arg_tys . iter ( ) . map ( | arg_ty | lower_repr_ty ( path , arg_ty ) ) . collect ( ) ; let ret_repr_ty = lower_repr_ty ( path , ret_ty ) ; Type :: Arrow ( arg_repr_tys , ret_repr_ty ) . into ( ) } core :: Type :: Lam ( _ , _ , _ ) => { // Due to the way our surface syntax is defined, the only type // abstractions we should encounter are those that are defined on // top-level definitions. Thes should have already been handled in // the `From<&'a core::Module>` impl for `Module`. panic ! ( " " ty ) } core :: Type :: App ( _ , ref ty , ref param_tys ) => { let lowered_ty = lower_repr_ty ( path , ty ) ; // Replace empty parameter lists on paths with the supplied parameters // TODO: This feels rather hacky! I'm sure it will break in non-trivial cases. // surely there is a better way to handle this? if let Type :: Path ( ref path , ref params ) = * lowered_ty . inner { assert ! ( params is_empty ( ) " " params ) ; let lowered_params = param_tys . iter ( ) . enumerate ( ) . map ( | ( i , ty ) | lower_repr_ty ( & path . append_child ( format ! ( " " i ) ) , ty ) ) . collect :: < Vec < _ > > ( ) ; return Type :: Path ( path . clone ( ) , lowered_params ) . into ( ) ; } lowered_ty } core :: Type :: HostArray ( ref elem_ty ) => { let elem_path = path . append_child ( " " ) ; let elem_ty = lower_repr_ty ( & elem_path , elem_ty ) ; Type :: Array ( elem_ty ) . into ( ) } core :: Type :: HostUnion ( _ ) | core :: Type :: HostStruct ( _ ) => { // We expect that the repr type has already had a corresponding type // generated for it, so instead we just return the current path. Type :: Path ( path . clone ( ) , vec ! [ ] ) . into ( ) } _ => unimplemented ! ( ) , } }
Lower host types to the nominal format
Lower host types to the nominal format
path
&Path
ty
&core::RcType
path
&Path
ty
&core::RcType