rue_compiler/compile/expr/
pair.rs1use 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}