rue_compiler/compile/ty/
lambda.rs

1use log::debug;
2use rue_ast::AstLambdaType;
3use rue_diagnostic::DiagnosticKind;
4use rue_hir::Scope;
5use rue_types::{FunctionType, Type, TypeId};
6
7use crate::{Compiler, compile_generic_parameters, compile_type};
8
9pub fn compile_lambda_type(ctx: &mut Compiler, lambda: &AstLambdaType) -> TypeId {
10    let scope = ctx.alloc_scope(Scope::new());
11
12    if let Some(generic_parameters) = lambda.generic_parameters() {
13        compile_generic_parameters(ctx, scope, &generic_parameters);
14    }
15
16    ctx.push_scope(scope);
17
18    let mut params = Vec::new();
19    let mut nil_terminated = true;
20
21    let len = lambda.parameters().count();
22
23    for (i, param) in lambda.parameters().enumerate() {
24        let is_spread = if let Some(spread) = param.spread() {
25            if i == len - 1 {
26                true
27            } else {
28                ctx.diagnostic(&spread, DiagnosticKind::NonFinalSpread);
29                false
30            }
31        } else {
32            false
33        };
34
35        if is_spread {
36            nil_terminated = false;
37        }
38
39        let ty = if let Some(ty) = param.ty() {
40            compile_type(ctx, &ty)
41        } else {
42            debug!("Unresolved lambda parameter type");
43            ctx.builtins().unresolved.ty
44        };
45
46        params.push(ty);
47    }
48
49    let ret = if let Some(ty) = lambda.return_type() {
50        compile_type(ctx, &ty)
51    } else {
52        debug!("Unresolved lambda return type");
53        ctx.builtins().unresolved.ty
54    };
55
56    ctx.pop_scope();
57
58    ctx.alloc_type(Type::Function(FunctionType {
59        params,
60        nil_terminated,
61        ret,
62    }))
63}