Skip to main content

luaur_analysis/methods/
constraint_solver_try_dispatch_iterable_function.rs

1use 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}