luaur_analysis/methods/
module_clone_public_interface.rs1use crate::enums::solver_mode::SolverMode;
2use crate::records::builtin_types::BuiltinTypes;
3use crate::records::clone_public_interface::ClonePublicInterface;
4use crate::records::clone_state::CloneState;
5use crate::records::internal_error::InternalError;
6use crate::records::internal_error_reporter::InternalErrorReporter;
7use crate::records::module::Module;
8use crate::records::scope::Scope;
9use crate::records::txn_log::TxnLog;
10use crate::records::type_error::TypeError;
11use crate::type_aliases::type_pack_id::TypePackId;
12use alloc::sync::Arc;
13use alloc::vec::Vec;
14use luaur_ast::records::location::Location;
15use luaur_common::records::dense_hash_map::DenseHashMap;
16
17impl Module {
18 pub fn clone_public_interface(
21 &mut self,
22 builtin_types: *mut BuiltinTypes,
23 _ice: &mut InternalErrorReporter,
24 mode: SolverMode,
25 ) {
26 let _clone_state = CloneState {
29 builtin_types,
30 seen_types: DenseHashMap::new(core::ptr::null()),
31 seen_type_packs: DenseHashMap::new(core::ptr::null()),
32 };
33
34 let module_scope = self.get_module_scope();
35 let module_scope_ptr = Arc::as_ptr(&module_scope) as *mut Scope;
38
39 let return_type: TypePackId = unsafe { (*module_scope_ptr).return_type };
40 let varargpack: Option<TypePackId> = if mode == SolverMode::New {
41 None
42 } else {
43 unsafe { (*module_scope_ptr).vararg_pack }
44 };
45
46 let log = TxnLog {
48 type_var_changes: DenseHashMap::new(core::ptr::null()),
49 type_pack_changes: DenseHashMap::new(core::ptr::null()),
50 parent: core::ptr::null_mut(),
51 owned_seen: Vec::new(),
52 shared_seen: core::ptr::null_mut(),
53 radioactive: false,
54 };
55 let mut clone_public_interface =
56 ClonePublicInterface::new(&log, builtin_types, self as *mut Module, mode);
57
58 let return_type = clone_public_interface.clone_type_pack(return_type);
59
60 unsafe { (*module_scope_ptr).return_type = return_type };
61 if let Some(vp) = varargpack {
62 let varargpack = clone_public_interface.clone_type_pack(vp);
63 unsafe { (*module_scope_ptr).vararg_pack = Some(varargpack) };
64 }
65
66 unsafe {
67 for (_name, tf) in (*module_scope_ptr).exported_type_bindings.iter_mut() {
68 let cloned = clone_public_interface.clone_type_fun(&*tf);
69 *tf = cloned;
70 }
71 }
72
73 for (_name, ty) in self.declared_globals.iter_mut() {
74 *ty = clone_public_interface.clone_type(*ty);
75 }
76
77 for tf in self.type_function_aliases.iter_mut() {
78 let cloned = clone_public_interface.clone_type_fun(&**tf);
79 **tf = cloned;
80 }
81
82 if clone_public_interface.internal_type_escaped {
83 self.errors
84 .push(TypeError::type_error_location_module_name_type_error_data(
85 Location::default(),
87 self.name.clone(),
88 InternalError::new(alloc::string::String::from(
89 "An internal type is escaping this module; please report this bug at \
90 https://github.com/luau-lang/luau/issues",
91 ))
92 .into(),
93 ));
94 }
95
96 self.return_type = unsafe { (*module_scope_ptr).return_type };
98 self.exported_type_bindings = unsafe { (*module_scope_ptr).exported_type_bindings.clone() };
99 }
100}