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 name = ctx.local_name(&generic_parameter);
21
22        let ty = ctx.alloc_type(Type::Generic(Generic { name: Some(name) }));
23
24        ctx.declaration_span(Declaration::Type(ty), generic_parameter.text_range());
25
26        ctx.push_declaration(Declaration::Type(ty));
27
28        if ctx.scope(scope).ty(generic_parameter.text()).is_some() {
29            ctx.diagnostic(
30                &generic_parameter,
31                DiagnosticKind::DuplicateType(generic_parameter.text().to_string()),
32            );
33        }
34
35        ctx.scope_mut(scope)
36            .insert_type(generic_parameter.text().to_string(), ty, false);
37
38        vars.push(ty);
39
40        ctx.pop_declaration();
41    }
42
43    if is_empty {
44        ctx.diagnostic(
45            generic_parameters.syntax(),
46            DiagnosticKind::EmptyGenericParameters,
47        );
48    }
49
50    vars
51}
52
53pub fn compile_generic_arguments(
54    ctx: &mut Compiler,
55    generic_arguments: &AstGenericArguments,
56) -> Vec<TypeId> {
57    let mut args = Vec::new();
58
59    let mut is_empty = true;
60
61    for generic_argument in generic_arguments.types() {
62        is_empty = false;
63        args.push(compile_type(ctx, &generic_argument));
64    }
65
66    if is_empty {
67        ctx.diagnostic(
68            generic_arguments.syntax(),
69            DiagnosticKind::EmptyGenericArguments,
70        );
71    }
72
73    args
74}