luaur_analysis/methods/
unifier_occurs_check_unifier.rs1use crate::functions::get_type_alt_j::get_type_id;
3use crate::records::intersection_type::IntersectionType;
4use crate::records::occurs_check_failed::OccursCheckFailed;
5use crate::records::r#type::Type;
6use crate::records::unifier::Unifier;
7use crate::records::union_type::UnionType;
8use crate::type_aliases::type_error_data::TypeErrorData;
9use crate::type_aliases::type_id::TypeId;
10use crate::type_aliases::type_variant::TypeVariant;
11
12impl Unifier {
13 pub fn occurs_check_type_id_type_id_bool(
15 &mut self,
16 needle: TypeId,
17 haystack: TypeId,
18 reversed: bool,
19 ) -> bool {
20 let shared_state = unsafe { &mut *self.shared_state };
21 shared_state.temp_seen_ty.clear();
22
23 let occurs = self.occurs_check_dense_hash_set_type_id_type_id_type_id(
24 &mut shared_state.temp_seen_ty,
25 needle,
26 haystack,
27 );
28
29 if occurs {
30 let mut inner_state = self.unifier_make_child_unifier();
31 let ut = unsafe { get_type_id::<UnionType>(haystack) };
32 let it = unsafe { get_type_id::<IntersectionType>(haystack) };
33
34 if !ut.is_null() {
35 if reversed {
36 inner_state.unifier_try_unify_union_with_type(haystack, ut, needle);
37 } else {
38 inner_state
39 .unifier_try_unify_type_with_union(needle, haystack, ut, false, false);
40 }
41 } else if !it.is_null() {
42 if reversed {
43 inner_state.unifier_try_unify_intersection_with_type(
44 haystack, it, needle, false, false,
45 );
46 } else {
47 inner_state.unifier_try_unify_type_with_intersection(needle, haystack, it);
48 }
49 } else {
50 inner_state.failure = true;
51 }
52
53 if inner_state.failure {
54 self.report_error_location_type_error_data(
55 self.location,
56 TypeErrorData::OccursCheckFailed(OccursCheckFailed::default()),
57 );
58 let error_ty = unsafe { (*self.builtin_types).errorType };
60 self.log
61 .replace_type_id_t(needle, Type::new(TypeVariant::Bound(error_ty)));
62 }
63 }
64
65 occurs
66 }
67}