luaur_analysis/methods/
magic_clone_handle_old_solver.rs1use crate::functions::extend_type_pack::extend_type_pack;
2use crate::functions::follow_type::follow_type_id;
3use crate::functions::get_type_alt_j::get_type_id;
4use crate::functions::shallow_clone_clone_alt_b::shallow_clone;
5use crate::records::clone_state::CloneState;
6use crate::records::count_mismatch::CountMismatch;
7use crate::records::intersection_type::IntersectionType;
8use crate::records::module::Module;
9use crate::records::scope::Scope;
10use crate::records::table_type::TableType;
11use crate::records::type_checker::TypeChecker;
12use crate::records::type_pack::TypePack;
13use crate::records::with_predicate::WithPredicate;
14use crate::type_aliases::type_error_data::TypeErrorData;
15use crate::type_aliases::type_pack_id::TypePackId;
16use alloc::sync::Arc;
17use alloc::vec;
18use luaur_ast::records::ast_expr_call::AstExprCall;
19use luaur_common::records::dense_hash_map::DenseHashMap;
20
21pub fn magic_clone_handle_old_solver(
24 typechecker: &mut TypeChecker,
25 _scope: &Arc<Scope>,
26 expr: &AstExprCall,
27 with_predicate: WithPredicate<TypePackId>,
28) -> Option<WithPredicate<TypePackId>> {
29 let param_pack = with_predicate.r#type;
30
31 let builtin_types = typechecker.builtin_types;
32 let module = typechecker.current_module.as_ref()?;
33 let arena = unsafe { &mut (*(Arc::as_ptr(module) as *mut Module)).internal_types };
34
35 let extended = extend_type_pack(arena, builtin_types, param_pack, 1, alloc::vec::Vec::new());
38 let param_types = extended.head;
39 if param_types.is_empty() || expr.args.size == 0 {
40 typechecker.report_error_location_type_error_data(
41 &expr.arg_location,
42 TypeErrorData::CountMismatch(CountMismatch {
43 expected: 1,
44 actual: 0,
45 ..Default::default()
46 }),
47 );
48 return None;
49 }
50
51 let input_type = unsafe { follow_type_id(param_types[0]) };
52
53 let table_ty = unsafe { get_type_id::<TableType>(input_type) };
54 let intersection_ty = unsafe { get_type_id::<IntersectionType>(input_type) };
55 if table_ty.is_null() && intersection_ty.is_null() {
56 return None;
57 }
58
59 if !intersection_ty.is_null() {
60 for &ty in unsafe { (*intersection_ty).parts.iter() } {
61 if unsafe { get_type_id::<TableType>(ty) }.is_null() {
62 return None;
63 }
64 }
65 }
66
67 let mut clone_state = CloneState {
68 builtin_types,
69 seen_types: DenseHashMap::new(core::ptr::null()),
70 seen_type_packs: DenseHashMap::new(core::ptr::null()),
71 };
72 let result_type = shallow_clone(
73 input_type,
74 arena,
75 &mut clone_state,
76 false,
77 );
78
79 let cloned_type_pack = arena.add_type_pack_t(TypePack {
80 head: vec![result_type],
81 tail: None,
82 });
83 Some(WithPredicate::with_predicate_t(cloned_type_pack))
84}