Skip to main content

luaur_analysis/methods/
constraint_generator_resolve_generic_default_parameters.rs

1use crate::functions::as_mutable_type::as_mutable_type_id;
2use crate::functions::emplace_type_pack::emplace_type_pack;
3use crate::methods::unifiable_bound_type_id_emplace_type_bound_type::unifiable_bound_type_id_emplace_type_bound_type;
4use crate::records::constraint_generator::ConstraintGenerator;
5use crate::records::scope::Scope;
6use crate::records::type_fun::TypeFun;
7use crate::type_aliases::type_pack_variant::TypePackVariant;
8use luaur_ast::records::ast_stat_type_alias::AstStatTypeAlias;
9use luaur_common::macros::luau_assert::LUAU_ASSERT;
10
11impl ConstraintGenerator {
12    pub fn resolve_generic_default_parameters(
13        &mut self,
14        defn_scope: *mut Scope,
15        alias: *mut AstStatTypeAlias,
16        fun: &TypeFun,
17    ) {
18        let alias_ref = unsafe { &*alias };
19        LUAU_ASSERT!(alias_ref.generics.size == fun.type_params().len());
20
21        for i in 0..alias_ref.generics.size {
22            let ast_ty = unsafe { *alias_ref.generics.data.add(i) };
23            let param = &fun.type_params()[i];
24
25            if param.defaultValue.is_some() && !unsafe { (*ast_ty).default_value }.is_null() {
26                let resolves_to = unsafe { (*ast_ty).default_value };
27                let to_unblock = param.defaultValue.unwrap();
28                let resolved = self.resolve_type(
29                    defn_scope,
30                    resolves_to,
31                    /* in_type_arguments */ false,
32                    /* replace_error_with_fresh */ false,
33                    crate::enums::polarity::Polarity::Positive,
34                );
35                unsafe {
36                    let mut resolved = resolved;
37                    unifiable_bound_type_id_emplace_type_bound_type(
38                        &mut *as_mutable_type_id(to_unblock),
39                        &mut resolved,
40                    );
41                }
42            }
43
44            unsafe {
45                let name_key = core::ffi::CStr::from_ptr((*ast_ty).name.value)
46                    .to_string_lossy()
47                    .into_owned();
48                (*defn_scope)
49                    .private_type_bindings
50                    .insert(name_key, TypeFun::type_fun_type_id(param.ty));
51            }
52        }
53
54        LUAU_ASSERT!(alias_ref.generic_packs.size == fun.type_pack_params().len());
55
56        for i in 0..alias_ref.generic_packs.size {
57            let ast_pack = unsafe { *alias_ref.generic_packs.data.add(i) };
58            let param = &fun.type_pack_params()[i];
59
60            if param.defaultValue.is_some() && !unsafe { (*ast_pack).default_value }.is_null() {
61                let resolves_to = unsafe { (*ast_pack).default_value };
62                let to_unblock = param.defaultValue.unwrap();
63                let resolved = self.resolve_type_pack_scope_ptr_ast_type_pack_bool_bool_polarity(
64                    defn_scope,
65                    resolves_to,
66                    /* in_type_arguments */ false,
67                    /* replace_error_with_fresh */ false,
68                    crate::enums::polarity::Polarity::Positive,
69                );
70                unsafe {
71                    emplace_type_pack(
72                        crate::functions::as_mutable_type_pack::as_mutable_type_pack_id(to_unblock),
73                        TypePackVariant::Bound(resolved),
74                    );
75                }
76            }
77
78            unsafe {
79                let name_key = core::ffi::CStr::from_ptr((*ast_pack).name.value)
80                    .to_string_lossy()
81                    .into_owned();
82                (*defn_scope)
83                    .private_type_pack_bindings
84                    .insert(name_key, param.tp);
85            }
86        }
87    }
88}