fn lower_expr(path: &Path, expr: &core::RcExpr) -> RcExpr {
    match *expr.inner {
        core::Expr::Ann(_, ref expr, ref ty) => {
            let lowered_expr = lower_expr(path, expr);
            let lowered_ty = lower_repr_ty(path, ty);

            Expr::Ann(lowered_expr, lowered_ty).into()
        }
        core::Expr::Const(_, c) => Expr::Const(c).into(),
        core::Expr::Var(_, ref var) => Expr::Var(var.clone()).into(),
        core::Expr::Lam(_, ref params, ref body_expr) => {
            let lowered_params = params
                .iter()
                .map(|param| Named::new(param.name.clone(), lower_repr_ty(path, &param.inner)))
                .collect();

            Expr::Lam(lowered_params, lower_expr(path, body_expr)).into()
        }
        core::Expr::App(_, ref fn_expr, ref arg_exprs) => {
            let lowered_arg_exprs = arg_exprs
                .iter()
                .map(|expr| lower_expr(path, expr))
                .collect();

            Expr::App(lower_expr(path, fn_expr), lowered_arg_exprs).into()
        }

        core::Expr::Intro(_, _, _) => unimplemented!(),
        core::Expr::Array(_, ref elems) => {
            Expr::Array(elems.iter().map(|elem| lower_expr(path, elem)).collect()).into()
        }

        core::Expr::Unop(_, op, ref expr) => Expr::Unop(op, lower_expr(path, expr)).into(),
        core::Expr::Binop(_, op, ref lhs, ref rhs) => {
            Expr::Binop(op, lower_expr(path, lhs), lower_expr(path, rhs)).into()
        }
        core::Expr::Struct(ref fields) => {
            let lowered_fields = lower_row(path, fields, |field_path, expr| {
                lower_expr(&field_path, expr)
            });

            Expr::Struct(path.clone(), lowered_fields).into()
        }
        core::Expr::Proj(_, ref expr, ref field_name) => {
            Expr::Proj(lower_expr(path, expr), field_name.clone()).into()
        }
        core::Expr::Subscript(_, _, _) => unimplemented!(),
        core::Expr::Cast(_, ref src_expr, ref dst_ty) => {
            Expr::Cast(lower_expr(path, src_expr), lower_repr_ty(path, dst_ty)).into()
        }
    }
}
/// Lower host expressions to the nominal format
///
/// # Arguments
///
/// * `path` - path to the parent struct or union
/// * `expr` - the expression to be lowered
Lower host expressions to the nominal format
Lower host expressions to the nominal format
fn lower_expr(path: &Path, expr: &core::RcExpr) -> RcExpr {
    match *expr.inner {
        core::Expr::Ann(_, ref expr, ref ty) => {
            let lowered_expr = lower_expr(path, expr);
            let lowered_ty = lower_repr_ty(path, ty);
            Expr::Ann(lowered_expr, lowered_ty).into()
        }
        core::Expr::Const(_, c) => Expr::Const(c).into(),
        core::Expr::Var(_, ref var) => Expr::Var(var.clone()).into(),
        core::Expr::Lam(_, ref params, ref body_expr) => {
            let lowered_params = params
                .iter()
                .map(|param| Named::new(param.name.clone(), lower_repr_ty(path, &param.inner)))
                .collect();
            Expr::Lam(lowered_params, lower_expr(path, body_expr)).into()
        }
        core::Expr::App(_, ref fn_expr, ref arg_exprs) => {
            let lowered_arg_exprs = arg_exprs
                .iter()
                .map(|expr| lower_expr(path, expr))
                .collect();
            Expr::App(lower_expr(path, fn_expr), lowered_arg_exprs).into()
        }
        core::Expr::Intro(_, _, _) => unimplemented!(),
        core::Expr::Array(_, ref elems) => {
            Expr::Array(elems.iter().map(|elem| lower_expr(path, elem)).collect()).into()
        }
        core::Expr::Unop(_, op, ref expr) => Expr::Unop(op, lower_expr(path, expr)).into(),
        core::Expr::Binop(_, op, ref lhs, ref rhs) => {
            Expr::Binop(op, lower_expr(path, lhs), lower_expr(path, rhs)).into()
        }
        core::Expr::Struct(ref fields) => {
            let lowered_fields = lower_row(path, fields, |field_path, expr| {
                lower_expr(&field_path, expr)
            });
            Expr::Struct(path.clone(), lowered_fields).into()
        }
        core::Expr::Proj(_, ref expr, ref field_name) => {
            Expr::Proj(lower_expr(path, expr), field_name.clone()).into()
        }
        core::Expr::Subscript(_, _, _) => unimplemented!(),
        core::Expr::Cast(_, ref src_expr, ref dst_ty) => {
            Expr::Cast(lower_expr(path, src_expr), lower_repr_ty(path, dst_ty)).into()
        }
    }
}
fn lower_expr ( path : & Path , expr : & core :: RcExpr ) -> RcExpr { match * expr . inner { core :: Expr :: Ann ( _ , ref expr , ref ty ) => { let lowered_expr = lower_expr ( path , expr ) ; let lowered_ty = lower_repr_ty ( path , ty ) ; Expr :: Ann ( lowered_expr , lowered_ty ) . into ( ) } core :: Expr :: Const ( _ , c ) => Expr :: Const ( c ) . into ( ) , core :: Expr :: Var ( _ , ref var ) => Expr :: Var ( var . clone ( ) ) . into ( ) , core :: Expr :: Lam ( _ , ref params , ref body_expr ) => { let lowered_params = params . iter ( ) . map ( | param | Named :: new ( param . name . clone ( ) , lower_repr_ty ( path , & param . inner ) ) ) . collect ( ) ; Expr :: Lam ( lowered_params , lower_expr ( path , body_expr ) ) . into ( ) } core :: Expr :: App ( _ , ref fn_expr , ref arg_exprs ) => { let lowered_arg_exprs = arg_exprs . iter ( ) . map ( | expr | lower_expr ( path , expr ) ) . collect ( ) ; Expr :: App ( lower_expr ( path , fn_expr ) , lowered_arg_exprs ) . into ( ) } core :: Expr :: Intro ( _ , _ , _ ) => unimplemented ! ( ) , core :: Expr :: Array ( _ , ref elems ) => { Expr :: Array ( elems . iter ( ) . map ( | elem | lower_expr ( path , elem ) ) . collect ( ) ) . into ( ) } core :: Expr :: Unop ( _ , op , ref expr ) => Expr :: Unop ( op , lower_expr ( path , expr ) ) . into ( ) , core :: Expr :: Binop ( _ , op , ref lhs , ref rhs ) => { Expr :: Binop ( op , lower_expr ( path , lhs ) , lower_expr ( path , rhs ) ) . into ( ) } core :: Expr :: Struct ( ref fields ) => { let lowered_fields = lower_row ( path , fields , | field_path , expr | { lower_expr ( & field_path , expr ) } ) ; Expr :: Struct ( path . clone ( ) , lowered_fields ) . into ( ) } core :: Expr :: Proj ( _ , ref expr , ref field_name ) => { Expr :: Proj ( lower_expr ( path , expr ) , field_name . clone ( ) ) . into ( ) } core :: Expr :: Subscript ( _ , _ , _ ) => unimplemented ! ( ) , core :: Expr :: Cast ( _ , ref src_expr , ref dst_ty ) => { Expr :: Cast ( lower_expr ( path , src_expr ) , lower_repr_ty ( path , dst_ty ) ) . into ( ) } } }
Lower host expressions to the nominal format
Lower host expressions to the nominal format
path
&Path
expr
&core::RcExpr
path
&Path
expr
&core::RcExpr