rue_compiler/compile/expr/
guard.rs1use std::collections::HashMap;
2
3use log::debug;
4use rue_ast::{AstGuardExpr, AstNode};
5use rue_hir::{Value, generate_check_hir};
6
7use crate::{Compiler, compile_expr, compile_type};
8
9pub fn compile_guard_expr(ctx: &mut Compiler, guard: &AstGuardExpr) -> Value {
10 let ty = if let Some(ty) = guard.ty() {
11 compile_type(ctx, &ty)
12 } else {
13 debug!("Unresolved guard type");
14 ctx.builtins().unresolved.ty
15 };
16
17 let expr = if let Some(expr) = guard.expr() {
18 compile_expr(ctx, &expr, Some(ty))
19 } else {
20 debug!("Unresolved guard expr");
21 ctx.builtins().unresolved.clone()
22 };
23
24 let constraint = ctx.guard_type(guard.syntax(), expr.ty, ty);
25 let builtins = ctx.builtins().clone();
26 let check_hir = generate_check_hir(ctx, &builtins, constraint.check.simplify(), expr.hir);
27
28 let mut value = Value::new(check_hir, ctx.builtins().types.bool);
29
30 if let Some(reference) = expr.reference {
31 let mut then_map = HashMap::new();
32 let mut symbol_map = HashMap::new();
33 symbol_map.insert(reference.path.clone(), ty);
34 then_map.insert(reference.symbol, symbol_map);
35
36 let mut else_map = HashMap::new();
37 if let Some(else_id) = constraint.else_id {
38 let mut symbol_map = HashMap::new();
39 symbol_map.insert(reference.path.clone(), else_id);
40 else_map.insert(reference.symbol, symbol_map);
41 }
42
43 value = value.with_mappings(then_map, else_map);
44 }
45
46 value
47}