Skip to main content

luaur_analysis/methods/
replace_generics_clean_instantiation.rs

1use crate::enums::table_state::TableState;
2use crate::functions::get_mutable_type::get_mutable_type_id;
3use crate::records::free_type::FreeType;
4use crate::records::replace_generics::ReplaceGenerics;
5use crate::records::table_type::TableType;
6use crate::type_aliases::type_id::TypeId;
7use luaur_common::macros::luau_assert::LUAU_ASSERT;
8use luaur_common::FFlag;
9
10impl ReplaceGenerics {
11    pub fn clean_type_id(&mut self, ty: TypeId) -> TypeId {
12        LUAU_ASSERT!(self.is_dirty_type_id(ty));
13
14        let log = self.base.base.log;
15        let level = self.level;
16        let scope = self.scope;
17
18        if FFlag::LuauReplacerIsSolverAgnostic.get() {
19            let ttv = unsafe { (*log).txn_log_get_mutable::<TableType, TypeId>(ty) };
20            if !ttv.is_null() {
21                let ttv = unsafe { &*ttv };
22                let mut clone =
23                    TableType::table_type_props_optional_table_indexer_type_level_scope_table_state(
24                        &ttv.props,
25                        ttv.indexer.clone(),
26                        level,
27                        scope,
28                        TableState::Free,
29                    );
30                clone.definition_module_name = ttv.definition_module_name.clone();
31                clone.definition_location = ttv.definition_location;
32                self.base.add_type(clone)
33            } else {
34                // arena->freshType(builtinTypes, scope, level)
35                let builtins = unsafe { &*self.builtin_types };
36                let free_type = FreeType {
37                    scope,
38                    level,
39                    lower_bound: builtins.neverType,
40                    upper_bound: builtins.unknownType,
41                    ..FreeType::default()
42                };
43                self.base.add_type(free_type)
44            }
45        } else {
46            let ttv = unsafe { (*log).txn_log_get_mutable::<TableType, TypeId>(ty) };
47            if !ttv.is_null() {
48                let ttv = unsafe { &*ttv };
49                let mut clone =
50                    TableType::table_type_props_optional_table_indexer_type_level_scope_table_state(
51                        &ttv.props,
52                        ttv.indexer.clone(),
53                        level,
54                        scope,
55                        TableState::Free,
56                    );
57                clone.definition_module_name = ttv.definition_module_name.clone();
58                clone.definition_location = ttv.definition_location;
59                self.base.add_type(clone)
60            } else if FFlag::LuauSolverV2.get() {
61                let builtins = unsafe { &*self.builtin_types };
62                let free_type = FreeType {
63                    scope,
64                    lower_bound: builtins.neverType,
65                    upper_bound: builtins.unknownType,
66                    ..FreeType::default()
67                };
68                let res = self.base.add_type(free_type);
69                unsafe {
70                    (*get_mutable_type_id::<FreeType>(res)).level = level;
71                }
72                res
73            } else {
74                // arena->freshType(builtinTypes, scope, level)
75                let builtins = unsafe { &*self.builtin_types };
76                let free_type = FreeType {
77                    scope,
78                    level,
79                    lower_bound: builtins.neverType,
80                    upper_bound: builtins.unknownType,
81                    ..FreeType::default()
82                };
83                self.base.add_type(free_type)
84            }
85        }
86    }
87}