luaur_analysis/methods/
constraint_solver_try_dispatch_iterable_function.rs1use crate::functions::get_mutable_type_pack::get_mutable_type_pack_id;
2use crate::functions::get_type_id::get_type_id;
3use crate::records::blocked_type_pack::BlockedTypePack;
4use crate::records::constraint::Constraint;
5use crate::records::constraint_solver::ConstraintSolver;
6use crate::records::function_call_constraint::FunctionCallConstraint;
7use crate::records::function_type::FunctionType;
8use crate::records::iterable_constraint::IterableConstraint;
9use crate::records::unpack_constraint::UnpackConstraint;
10use crate::type_aliases::constraint_v::ConstraintV;
11use crate::type_aliases::type_id::TypeId;
12use core::ptr::NonNull;
13use luaur_common::macros::luau_assert::LUAU_ASSERT;
14
15impl ConstraintSolver {
16 pub fn try_dispatch_iterable_function(
17 &mut self,
18 next_ty: TypeId,
19 table_ty: TypeId,
20 c: &IterableConstraint,
21 constraint: *const Constraint,
22 ) -> bool {
23 let next_fn = unsafe { get_type_id::<FunctionType>(next_ty) };
24 LUAU_ASSERT!(!next_fn.is_null());
25
26 unsafe {
27 (*(*c.ast_for_in_next_types)
28 .get_or_insert(c.next_ast_fragment as *const crate::records::ast_node::AstNode)) =
29 next_ty
30 };
31
32 let table_ty_pack =
33 unsafe { (*self.arena).add_type_pack_initializer_list_type_id(&[table_ty]) };
34
35 let variables_pack = unsafe {
36 let mut btp = BlockedTypePack {
37 index: 0,
38 owner: core::ptr::null_mut(),
39 };
40 btp.blocked_type_pack_blocked_type_pack();
41 (*self.arena).add_type_pack_t(btp)
42 };
43
44 let call_constraint = self.push_constraint(
45 NonNull::new(unsafe { (*constraint).scope }).unwrap(),
46 unsafe { (*constraint).location },
47 ConstraintV::FunctionCall(FunctionCallConstraint {
48 fn_type: next_ty,
49 args_pack: table_ty_pack,
50 result: variables_pack,
51 call_site: core::ptr::null_mut(),
52 discriminant_types: alloc::vec::Vec::new(),
53 type_arguments: alloc::vec::Vec::new(),
54 type_pack_arguments: alloc::vec::Vec::new(),
55 ast_overload_resolved_types: core::ptr::null_mut(),
56 }),
57 );
58
59 unsafe {
60 (*get_mutable_type_pack_id::<BlockedTypePack>(variables_pack)).owner =
61 call_constraint.as_ptr()
62 };
63
64 let unpack_constraint = self.unpack_and_assign(
65 c.variables.clone(),
66 variables_pack,
67 NonNull::new(constraint as *mut Constraint).unwrap(),
68 );
69
70 self.inherit_blocks(constraint, call_constraint.as_ptr());
71 self.inherit_blocks(unpack_constraint.as_ptr(), call_constraint.as_ptr());
72
73 true
74 }
75}