rue_compiler/compile/expr/
if_expr.rs1use log::debug;
2use rue_ast::{AstIfExpr, AstNode};
3use rue_hir::{Hir, Value};
4use rue_types::{Type, TypeId, Union};
5
6use crate::{Compiler, compile_expr};
7
8pub fn compile_if_expr(
9 ctx: &mut Compiler,
10 expr: &AstIfExpr,
11 expected_type: Option<TypeId>,
12) -> Value {
13 let condition = if let Some(condition) = expr.condition() {
14 let value = compile_expr(ctx, &condition, None);
15 ctx.check_condition(condition.syntax(), value.ty);
16 value
17 } else {
18 debug!("Unresolved if condition");
19 ctx.builtins().unresolved.clone()
20 };
21
22 let then_expr = if let Some(then_expr) = expr.then_expr() {
23 if expr.inline().is_some() {
24 compile_expr(ctx, &then_expr, expected_type)
26 } else {
27 let index = ctx.push_mappings(condition.then_map.clone());
28 let value = compile_expr(ctx, &then_expr, expected_type);
29 ctx.revert_mappings(index);
30 value
31 }
32 } else {
33 debug!("Unresolved if then expr");
34 ctx.builtins().unresolved.clone()
35 };
36
37 let else_expr = if let Some(else_expr) = expr.else_expr() {
38 if expr.inline().is_some() {
39 compile_expr(ctx, &else_expr, expected_type)
41 } else {
42 let index = ctx.push_mappings(condition.else_map.clone());
43 let value = compile_expr(ctx, &else_expr, expected_type);
44 ctx.revert_mappings(index);
45 value
46 }
47 } else {
48 debug!("Unresolved if else expr");
49 ctx.builtins().unresolved.clone()
50 };
51
52 let ty = ctx.alloc_type(Type::Union(Union::new(vec![then_expr.ty, else_expr.ty])));
53 let hir = ctx.alloc_hir(Hir::If(
54 condition.hir,
55 then_expr.hir,
56 else_expr.hir,
57 expr.inline().is_some(),
58 ));
59
60 Value::new(hir, ty)
61}