luaur_analysis/methods/
constraint_solver_bind_constraint_solver_alt_b.rs1use crate::enums::occurs_check_result::OccursCheckResult;
5use crate::functions::as_mutable_type_pack::as_mutable_type_pack_id;
6use crate::functions::follow_type_pack::follow_type_pack_id;
7use crate::functions::get_type_pack::get_type_pack_id;
8use crate::functions::occurs_check_type_utils_alt_b::occurs_check_type_pack_id_type_pack_id;
9use crate::records::blocked_type_pack::BlockedTypePack;
10use crate::records::constraint::Constraint;
11use crate::records::constraint_solver::ConstraintSolver;
12use crate::records::free_type_pack::FreeTypePack;
13use crate::records::internal_error::InternalError;
14use crate::type_aliases::type_pack_id::TypePackId;
15use luaur_common::macros::luau_assert::LUAU_ASSERT;
16use luaur_common::FFlag;
17
18impl ConstraintSolver {
19 pub fn bind_not_null_constraint_type_pack_id_type_pack_id(
20 &mut self,
21 constraint: *const Constraint,
22 tp: TypePackId,
23 bound_to: TypePackId,
24 ) {
25 LUAU_ASSERT!(unsafe {
26 !get_type_pack_id::<BlockedTypePack>(tp).is_null()
27 || !get_type_pack_id::<FreeTypePack>(tp).is_null()
28 });
29 LUAU_ASSERT!(can_mutate_type_pack_id(tp, constraint));
30
31 let bound_to = unsafe { follow_type_pack_id(bound_to) };
32 LUAU_ASSERT!(tp != bound_to);
33
34 let location = unsafe { (*constraint).location };
35
36 if FFlag::LuauOccursCheckForAllBindings.get()
37 && occurs_check_type_pack_id_type_pack_id(tp, bound_to) == OccursCheckResult::Fail
38 {
39 self.report_error_type_error_data_location(
40 InternalError {
41 message: alloc::string::String::from("Attempted to create a type pack cycle"),
42 }
43 .into(),
44 &location,
45 );
46 let mutable_tp = unsafe { as_mutable_type_pack_id(tp) };
47 let mut err_arg = unsafe { (*self.builtin_types).errorTypePack };
48 crate::methods::unifiable_bound_type_pack_id_emplace_type_pack_bound_type_pack::emplace_type_pack(
49 mutable_tp,
50 &mut err_arg,
51 );
52 } else {
53 let mutable_tp = unsafe { as_mutable_type_pack_id(tp) };
54 let mut bound_arg = bound_to;
55 crate::methods::unifiable_bound_type_pack_id_emplace_type_pack_bound_type_pack::emplace_type_pack(
56 mutable_tp,
57 &mut bound_arg,
58 );
59 }
60
61 self.unblock_type_pack_id_location(tp, location);
62 }
63}
64
65fn can_mutate_type_pack_id(tp: TypePackId, constraint: *const Constraint) -> bool {
68 let blocked = unsafe { get_type_pack_id::<BlockedTypePack>(tp) };
69 if !blocked.is_null() {
70 let owner = unsafe { (*blocked).owner };
71 LUAU_ASSERT!(!owner.is_null());
72 return owner as *const Constraint == constraint;
73 }
74 true
75}