rue_compiler/compile/expr/
pair.rs

1use log::debug;
2use rue_ast::AstPairExpr;
3use rue_hir::{Hir, Value};
4use rue_types::{Pair, Type, TypeId, Union};
5
6use crate::{Compiler, compile_expr};
7
8pub fn compile_pair_expr(
9    ctx: &mut Compiler,
10    pair: &AstPairExpr,
11    expected_type: Option<TypeId>,
12) -> Value {
13    let (expected_first, expected_rest) = if let Some(ty) = expected_type
14        && let pairs = rue_types::extract_pairs(ctx.types_mut(), ty, false)
15        && !pairs.is_empty()
16    {
17        let first = if pairs.len() == 1 {
18            pairs[0].first
19        } else {
20            ctx.alloc_type(Type::Union(Union::new(
21                pairs.iter().map(|pair| pair.first).collect(),
22            )))
23        };
24
25        let rest = if pairs.len() == 1 {
26            pairs[0].rest
27        } else {
28            ctx.alloc_type(Type::Union(Union::new(
29                pairs.iter().map(|pair| pair.rest).collect(),
30            )))
31        };
32
33        (Some(first), Some(rest))
34    } else {
35        (None, None)
36    };
37
38    let first = if let Some(first) = pair.first() {
39        compile_expr(ctx, &first, expected_first)
40    } else {
41        debug!("Unresolved pair first");
42        ctx.builtins().unresolved.clone()
43    };
44
45    let rest = if let Some(rest) = pair.rest() {
46        compile_expr(ctx, &rest, expected_rest)
47    } else {
48        debug!("Unresolved pair rest");
49        ctx.builtins().unresolved.clone()
50    };
51
52    let hir = ctx.alloc_hir(Hir::Pair(first.hir, rest.hir));
53    let ty = ctx.alloc_type(Type::Pair(Pair::new(first.ty, rest.ty)));
54
55    Value::new(hir, ty)
56}