rue_compiler/compile/
generics.rs

1use rue_ast::{AstGenericArguments, AstGenericParameters, AstNode};
2use rue_diagnostic::DiagnosticKind;
3use rue_hir::ScopeId;
4use rue_types::{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);
21
22        if ctx.scope(scope).ty(generic_parameter.text()).is_some() {
23            ctx.diagnostic(
24                &generic_parameter,
25                DiagnosticKind::DuplicateType(generic_parameter.text().to_string()),
26            );
27        }
28
29        ctx.scope_mut(scope)
30            .insert_type(generic_parameter.text().to_string(), ty, false);
31
32        vars.push(ty);
33    }
34
35    if is_empty {
36        ctx.diagnostic(
37            generic_parameters.syntax(),
38            DiagnosticKind::EmptyGenericParameters,
39        );
40    }
41
42    vars
43}
44
45pub fn compile_generic_arguments(
46    ctx: &mut Compiler,
47    generic_arguments: &AstGenericArguments,
48) -> Vec<TypeId> {
49    let mut args = Vec::new();
50
51    let mut is_empty = true;
52
53    for generic_argument in generic_arguments.types() {
54        is_empty = false;
55        args.push(compile_type(ctx, &generic_argument));
56    }
57
58    if is_empty {
59        ctx.diagnostic(
60            generic_arguments.syntax(),
61            DiagnosticKind::EmptyGenericArguments,
62        );
63    }
64
65    args
66}