Skip to main content

luaur_analysis/methods/
constraint_solver_try_dispatch_constraint_solver_alt_s.rs

1use crate::functions::as_mutable_type::as_mutable_type_id;
2use crate::functions::emplace_type::emplace_type;
3use crate::functions::follow_type::follow_type_id;
4use crate::records::bound_type::BoundType;
5use crate::records::builtin_types::BuiltinTypes;
6use crate::records::constraint::Constraint;
7use crate::records::constraint_solver::ConstraintSolver;
8use crate::records::find_all_union_members::FindAllUnionMembers;
9use crate::records::generic_type_visitor::GenericTypeVisitorTrait;
10use crate::records::simplify_constraint::SimplifyConstraint;
11use crate::records::union_type::UnionType;
12use luaur_common::FFlag;
13
14impl ConstraintSolver {
15    pub fn try_dispatch_simplify_constraint_not_null_constraint_bool(
16        &mut self,
17        c: &SimplifyConstraint,
18        constraint: *const Constraint,
19        force: bool,
20    ) -> bool {
21        let target = unsafe { follow_type_id(c.ty) };
22
23        unsafe {
24            if (*target).persistent
25                || (*target).owning_arena != self.arena
26                || crate::functions::get_type_alt_j::get_type_id::<UnionType>(target).is_null()
27            {
28                return true;
29            }
30        }
31
32        let mut finder = FindAllUnionMembers::new();
33        finder.traverse_type_id(target);
34
35        if !finder.blocked_tys.empty() && !force {
36            for ty in &finder.blocked_tys.order {
37                self.block_type_id_not_null_constraint(*ty, constraint);
38            }
39            return false;
40        }
41
42        let mut result = unsafe { (*self.builtin_types).neverType };
43        for ty in &finder.recorded_tys.order {
44            let ty_followed = unsafe { follow_type_id(*ty) };
45            if ty_followed == target {
46                continue;
47            }
48            result = self.simplify_union(
49                unsafe { (*constraint).scope },
50                unsafe { (*constraint).location },
51                result,
52                ty_followed,
53            );
54        }
55
56        if force {
57            for ty in &finder.blocked_tys.order {
58                let ty_followed = unsafe { follow_type_id(*ty) };
59                if ty_followed == target {
60                    continue;
61                }
62                result = self.simplify_union(
63                    unsafe { (*constraint).scope },
64                    unsafe { (*constraint).location },
65                    result,
66                    ty_followed,
67                );
68            }
69        }
70
71        let mutable_target = unsafe { as_mutable_type_id(target) };
72        let mut result_arg = result;
73        crate::methods::unifiable_bound_type_id_emplace_type_bound_type::unifiable_bound_type_id_emplace_type_bound_type(
74            unsafe { &mut *mutable_target },
75            &mut result_arg,
76        );
77
78        if FFlag::LuauConstraintGraph.get() {
79            unsafe { (*self.cgraph).shift_references_type_id(target, result) };
80        }
81
82        true
83    }
84}