rue_compiler/compile/
generics.rs

1use rue_ast::{AstGenericArguments, AstGenericParameters, AstNode};
2use rue_diagnostic::DiagnosticKind;
3use rue_hir::{Declaration, ScopeId};
4use rue_types::{Generic, Type, TypeId};
5
6use crate::{Compiler, compile_type};
7
8pub fn compile_generic_parameters(
9    ctx: &mut Compiler,
10    scope: ScopeId,
11    generic_parameters: &AstGenericParameters,
12) -> Vec<TypeId> {
13    let mut vars = Vec::new();
14
15    let mut is_empty = true;
16
17    for generic_parameter in generic_parameters.names() {
18        is_empty = false;
19
20        let ty = ctx.alloc_type(Type::Generic(Generic {
21            name: Some(generic_parameter.clone()),
22        }));
23
24        ctx.push_declaration(Declaration::Type(ty));
25
26        if ctx.scope(scope).ty(generic_parameter.text()).is_some() {
27            ctx.diagnostic(
28                &generic_parameter,
29                DiagnosticKind::DuplicateType(generic_parameter.text().to_string()),
30            );
31        }
32
33        ctx.scope_mut(scope)
34            .insert_type(generic_parameter.text().to_string(), ty, false);
35
36        vars.push(ty);
37
38        ctx.pop_declaration();
39    }
40
41    if is_empty {
42        ctx.diagnostic(
43            generic_parameters.syntax(),
44            DiagnosticKind::EmptyGenericParameters,
45        );
46    }
47
48    vars
49}
50
51pub fn compile_generic_arguments(
52    ctx: &mut Compiler,
53    generic_arguments: &AstGenericArguments,
54) -> Vec<TypeId> {
55    let mut args = Vec::new();
56
57    let mut is_empty = true;
58
59    for generic_argument in generic_arguments.types() {
60        is_empty = false;
61        args.push(compile_type(ctx, &generic_argument));
62    }
63
64    if is_empty {
65        ctx.diagnostic(
66            generic_arguments.syntax(),
67            DiagnosticKind::EmptyGenericArguments,
68        );
69    }
70
71    args
72}