luaur_analysis/methods/
constraint_solver_unify.rs1use core::ptr::NonNull;
6
7use crate::enums::unify_result::UnifyResult;
8use crate::records::constraint::Constraint;
9use crate::records::constraint_solver::ConstraintSolver;
10use crate::records::internal_error_reporter::InternalErrorReporter;
11use crate::records::occurs_check_failed::OccursCheckFailed;
12use crate::records::scope::Scope;
13use crate::records::subtyping::Subtyping;
14use crate::records::subtyping_result::SubtypingResult;
15use crate::records::subtyping_unifier::SubtypingUnifier;
16use crate::records::unification_too_complex::UnificationTooComplex;
17use crate::type_aliases::type_id::TypeId;
18use crate::type_aliases::type_pack_id::TypePackId;
19
20pub trait UnifyTid: Copy {
23 fn is_subtype_in(
24 self,
25 subtyping: &mut Subtyping,
26 super_ty: Self,
27 scope: *mut Scope,
28 ) -> SubtypingResult;
29}
30
31impl UnifyTid for TypeId {
32 fn is_subtype_in(
33 self,
34 subtyping: &mut Subtyping,
35 super_ty: Self,
36 scope: *mut Scope,
37 ) -> SubtypingResult {
38 subtyping.is_subtype_type_id_type_id_not_null_scope(self, super_ty, scope)
39 }
40}
41
42impl UnifyTid for TypePackId {
43 fn is_subtype_in(
44 self,
45 subtyping: &mut Subtyping,
46 super_ty: Self,
47 scope: *mut Scope,
48 ) -> SubtypingResult {
49 subtyping.is_subtype_type_pack_id_type_pack_id_not_null_scope_vector_type_id(
50 self,
51 super_ty,
52 scope,
53 &alloc::vec::Vec::new(),
54 )
55 }
56}
57
58impl ConstraintSolver {
59 pub fn constraint_solver_unify<TID: UnifyTid>(
60 &mut self,
61 constraint: *const Constraint,
62 sub_ty: TID,
63 super_ty: TID,
64 ) -> bool {
65 let scope = unsafe { (*constraint).scope };
66 let location = unsafe { (*constraint).location };
67 let ice_ptr =
68 &self.ice_reporter as *const InternalErrorReporter as *mut InternalErrorReporter;
69
70 let mut subtyping = Subtyping::subtyping_owned(
71 self.builtin_types,
72 self.arena,
73 self.normalizer,
74 self.type_function_runtime,
75 ice_ptr,
76 );
77 let mut stu = SubtypingUnifier::subtyping_unifier(self.arena, self.builtin_types, ice_ptr);
78
79 let mut result = sub_ty.is_subtype_in(&mut subtyping, super_ty, scope);
80
81 let unifier_result =
82 stu.dispatch_constraints(constraint, core::mem::take(&mut result.assumed_constraints));
83
84 for cv in unifier_result.outstanding_constraints.iter() {
85 let new_constraint =
86 self.push_constraint(NonNull::new(scope).unwrap(), location, cv.clone());
87 self.inherit_blocks(constraint, new_constraint.as_ptr());
88 }
89
90 for (ty, new_upper_bounds) in unifier_result.upper_bound_contributors.iter() {
91 let upper_bounds = self.upper_bound_contributors.get_or_insert(*ty);
92 upper_bounds.extend(new_upper_bounds.iter().cloned());
93 }
94
95 match unifier_result.unified {
96 UnifyResult::OccursCheckFailed => {
97 self.report_error_type_error_data_location(
98 OccursCheckFailed::default().into(),
99 &location,
100 );
101 false
102 }
103 UnifyResult::TooComplex => {
104 self.report_error_type_error_data_location(
105 UnificationTooComplex::default().into(),
106 &location,
107 );
108 false
109 }
110 UnifyResult::Ok => true,
111 }
112 }
113}