luaur_analysis/methods/
constraint_solver_try_dispatch_constraint_solver_alt_d.rs1use alloc::sync::Arc;
2
3use crate::enums::polarity::Polarity;
4use crate::functions::as_mutable_type::as_mutable_type_id;
5use crate::functions::as_mutable_type_pack::as_mutable_type_pack_id;
6use crate::functions::follow_type::follow_type_id;
7use crate::functions::follow_type_pack::follow_type_pack_id;
8use crate::functions::generalize::generalize;
9use crate::functions::generalize_type::generalize_type;
10use crate::functions::generalize_type_pack::generalize_type_pack;
11use crate::functions::get_mutable_type::get_mutable_type_id;
12use crate::functions::get_type_alt_j::get_type_id;
13use crate::functions::get_type_pack::get_type_pack_id;
14use crate::functions::is_known::is_known;
15use crate::functions::prune_unnecessary_generics::prune_unnecessary_generics;
16use crate::functions::seal_table::seal_table;
17use crate::records::blocked_type::BlockedType;
18use crate::records::code_too_complex::CodeTooComplex;
19use crate::records::constraint::Constraint;
20use crate::records::constraint_solver::ConstraintSolver;
21use crate::records::free_type::FreeType;
22use crate::records::free_type_pack::FreeTypePack;
23use crate::records::function_type::FunctionType;
24use crate::records::generalization_constraint::GeneralizationConstraint;
25use crate::records::generalization_params::GeneralizationParams;
26use crate::records::pending_expansion_type::PendingExpansionType;
27use crate::records::r#type::Type;
28use crate::records::table_type::TableType;
29use crate::records::type_pack_var::TypePackVar;
30use crate::type_aliases::type_pack_variant::TypePackVariant;
31use crate::type_aliases::type_variant::TypeVariant;
32
33impl ConstraintSolver {
34 pub fn try_dispatch_generalization_constraint_not_null_constraint(
35 &mut self,
36 c: &GeneralizationConstraint,
37 constraint: *const Constraint,
38 ) -> bool {
39 let generalized_type = unsafe { follow_type_id(c.generalized_type) };
40
41 if self.is_blocked_type_id(c.source_type) {
42 return self.block_type_id_not_null_constraint(c.source_type, constraint);
43 } else if unsafe { !get_type_id::<PendingExpansionType>(generalized_type).is_null() } {
44 return self.block_type_id_not_null_constraint(generalized_type, constraint);
45 }
46
47 let generalized_ty = generalize(
48 self.arena,
49 self.builtin_types,
50 unsafe { (*constraint).scope },
51 &mut self.generalized_types_ as *mut _,
52 c.source_type,
53 None,
54 );
55
56 if generalized_ty.is_none() {
57 self.report_error_type_error_data_location(CodeTooComplex::default().into(), unsafe {
58 &(*constraint).location
59 });
60 }
61
62 if let Some(generalized_ty) = generalized_ty {
63 prune_unnecessary_generics(
64 self.arena,
65 self.builtin_types,
66 unsafe { (*constraint).scope },
67 &mut self.generalized_types_ as *mut _,
68 generalized_ty,
69 );
70
71 if unsafe { !get_type_id::<BlockedType>(generalized_type).is_null() } {
72 self.bind_not_null_constraint_type_id_type_id(
73 constraint,
74 generalized_type,
75 generalized_ty,
76 );
77 } else {
78 self.constraint_solver_unify(constraint, generalized_type, generalized_ty);
79 }
80
81 let fty =
82 unsafe { get_mutable_type_id::<FunctionType>(follow_type_id(generalized_type)) };
83 if !fty.is_null() && c.has_deprecated_attribute {
84 unsafe {
85 (*fty).is_deprecated_function = true;
86 (*fty).deprecated_info = Some(Arc::new(c.deprecated_info.clone()));
87 }
88 }
89 } else {
90 self.report_error_type_error_data_location(CodeTooComplex::default().into(), unsafe {
91 &(*constraint).location
92 });
93 self.bind_not_null_constraint_type_id_type_id(constraint, c.generalized_type, unsafe {
94 (*self.builtin_types).errorType
95 });
96 }
97
98 unsafe {
99 let scope = (*constraint).scope;
100
101 if let Some(interior_free_types) = (*scope).interior_free_types.as_ref() {
102 let interior_free_types = interior_free_types.clone();
103 for ty in interior_free_types {
104 let ty = follow_type_id(ty);
105 let free_ty = get_type_id::<FreeType>(ty);
106
107 if !free_ty.is_null() {
108 let params = GeneralizationParams {
109 found_outside_functions: true,
110 use_count: 1,
111 polarity: (*free_ty).polarity,
112 };
113 let res =
114 generalize_type(self.arena, self.builtin_types, scope, ty, ¶ms);
115 if res.resource_limits_exceeded {
116 self.report_error_type_error_data_location(
117 CodeTooComplex::default().into(),
118 &(*scope).location,
119 );
120 }
121 } else if !get_type_id::<TableType>(ty).is_null() {
122 seal_table(scope, ty);
123 }
124
125 self.unblock_type_id_location(ty, (*constraint).location);
126 }
127 }
128
129 if let Some(interior_free_type_packs) = (*scope).interior_free_type_packs.as_ref() {
130 let interior_free_type_packs = interior_free_type_packs.clone();
131 for tp in interior_free_type_packs {
132 let tp = follow_type_pack_id(tp);
133 let free_tp = get_type_pack_id::<FreeTypePack>(tp);
134
135 if !free_tp.is_null() {
136 let params = GeneralizationParams {
137 found_outside_functions: true,
138 use_count: 1,
139 polarity: (*free_tp).polarity,
140 };
141 luaur_common::macros::luau_assert::LUAU_ASSERT!(is_known(params.polarity));
142 generalize_type_pack(self.arena, self.builtin_types, scope, tp, ¶ms);
143 }
144 }
145 }
146
147 if c.no_generics {
148 let ft = get_mutable_type_id::<FunctionType>(c.source_type);
149 if !ft.is_null() {
150 for gen in (*ft).generics.iter().copied() {
151 (*as_mutable_type_id(gen)).ty =
152 TypeVariant::Bound((*self.builtin_types).unknownType);
153 }
154 (*ft).generics.clear();
155
156 for gen in (*ft).generic_packs.iter().copied() {
157 (*as_mutable_type_pack_id(gen)).ty =
158 TypePackVariant::Bound((*self.builtin_types).unknownTypePack);
159 }
160 (*ft).generic_packs.clear();
161 }
162 }
163 }
164
165 true
166 }
167}