luaur_analysis/methods/
constraint_solver_try_dispatch_constraint_solver_alt_e.rs1use crate::enums::polarity::Polarity;
2use crate::enums::table_state::TableState;
3use crate::functions::extend_type_pack::extend_type_pack;
4use crate::functions::follow_type::follow_type_id;
5use crate::functions::fresh_type::fresh_type;
6use crate::functions::get_type_alt_j::get_type_id;
7use crate::functions::track_interior_free_type::track_interior_free_type;
8use crate::records::constraint::Constraint;
9use crate::records::constraint_solver::ConstraintSolver;
10use crate::records::free_type::FreeType;
11use crate::records::function_type::FunctionType;
12use crate::records::iterable_constraint::IterableConstraint;
13use crate::records::table_indexer::TableIndexer;
14use crate::records::table_type::TableType;
15use crate::records::type_level::TypeLevel;
16use crate::type_aliases::props_type::Props;
17
18impl ConstraintSolver {
19 pub fn try_dispatch_iterable_constraint_not_null_constraint_bool(
20 &mut self,
21 c: &IterableConstraint,
22 constraint: *const Constraint,
23 force: bool,
24 ) -> bool {
25 let iterator = unsafe {
26 extend_type_pack(
27 &mut *self.arena,
28 self.builtin_types,
29 c.iterator,
30 3,
31 alloc::vec::Vec::new(),
32 )
33 };
34
35 if iterator.head.len() < 3 {
36 if let Some(tail) = iterator.tail {
37 if self.is_blocked_type_pack_id(tail) {
38 return if force {
39 true
40 } else {
41 self.block_type_pack_id_not_null_constraint(tail, constraint)
42 };
43 }
44 }
45 }
46
47 let mut blocked = false;
48 for ty in &iterator.head {
49 if self.is_blocked_type_id(*ty) {
50 self.block_type_id_not_null_constraint(*ty, constraint);
51 blocked = true;
52 }
53 }
54
55 if blocked {
56 return false;
57 }
58
59 if iterator.head.is_empty() {
60 for ty in &c.variables {
61 self.bind_not_null_constraint_type_id_type_id(constraint, *ty, unsafe {
62 (*self.builtin_types).errorType
63 });
64 }
65 return true;
66 }
67
68 let next_ty = unsafe { follow_type_id(iterator.head[0]) };
69 if unsafe { !get_type_id::<FreeType>(next_ty).is_null() } {
70 let scope = unsafe { (*constraint).scope };
71 let key_ty = unsafe {
72 fresh_type(
73 &mut *self.arena,
74 &*self.builtin_types,
75 scope,
76 Polarity::Mixed,
77 )
78 };
79 let value_ty = unsafe {
80 fresh_type(
81 &mut *self.arena,
82 &*self.builtin_types,
83 scope,
84 Polarity::Mixed,
85 )
86 };
87 track_interior_free_type(scope, key_ty);
88 track_interior_free_type(scope, value_ty);
89
90 let props = Props::default();
91 let table_ty = unsafe {
92 (*self.arena).add_type(
93 TableType::table_type_props_optional_table_indexer_type_level_scope_table_state(
94 &props,
95 Some(TableIndexer {
96 index_type: key_ty,
97 index_result_type: value_ty,
98 is_read_only: false,
99 }),
100 TypeLevel::default(),
101 scope,
102 TableState::Free,
103 ),
104 )
105 };
106 track_interior_free_type(scope, table_ty);
107
108 self.constraint_solver_unify(constraint, next_ty, table_ty);
109
110 let mut it = c.variables.iter();
111 if let Some(ty) = it.next() {
112 self.bind_not_null_constraint_type_id_type_id(constraint, *ty, key_ty);
113 }
114 if let Some(ty) = it.next() {
115 self.bind_not_null_constraint_type_id_type_id(constraint, *ty, value_ty);
116 }
117 for ty in it {
118 self.bind_not_null_constraint_type_id_type_id(constraint, *ty, unsafe {
119 (*self.builtin_types).nilType
120 });
121 }
122
123 return true;
124 }
125
126 if unsafe { !get_type_id::<FunctionType>(next_ty).is_null() } {
127 let table_ty = if iterator.head.len() >= 2 {
128 iterator.head[1]
129 } else {
130 unsafe { (*self.builtin_types).nilType }
131 };
132
133 return self.try_dispatch_iterable_function(next_ty, table_ty, c, constraint);
134 }
135
136 self.try_dispatch_iterable_table(iterator.head[0], c, constraint, force)
137 }
138}