Skip to main content

luaur_analysis/methods/
constraint_solver_try_dispatch_constraint_solver_alt_j.rs

1use crate::functions::follow_type::follow_type_id;
2use crate::functions::get_type_alt_j::get_type_id;
3use crate::functions::maybe_singleton::maybe_singleton;
4use crate::records::constraint::Constraint;
5use crate::records::constraint_solver::ConstraintSolver;
6use crate::records::free_type::FreeType;
7use crate::records::pending_expansion_type::PendingExpansionType;
8use crate::records::primitive_type_constraint::PrimitiveTypeConstraint;
9use luaur_common::FFlag;
10
11impl ConstraintSolver {
12    pub fn try_dispatch_primitive_type_constraint_not_null_constraint(
13        &mut self,
14        c: &PrimitiveTypeConstraint,
15        constraint: *const Constraint,
16    ) -> bool {
17        let expected_type = if c.expected_type.is_some() {
18            Some(unsafe { follow_type_id(c.expected_type.unwrap()) })
19        } else {
20            None
21        };
22
23        if let Some(et) = expected_type {
24            if self.is_blocked_type_id(et)
25                || !unsafe { get_type_id::<PendingExpansionType>(et) }.is_null()
26            {
27                return self.block_type_id_not_null_constraint(et, constraint);
28            }
29        }
30
31        let free_type = unsafe { get_type_id::<FreeType>(follow_type_id(c.free_type)) };
32
33        if free_type.is_null() {
34            return true;
35        }
36
37        if FFlag::LuauConstraintGraph.get() {
38            if unsafe {
39                (*self.cgraph).has_strictly_more_than_one_dependency(
40                    crate::type_aliases::constraint_vertex::ConstraintVertex::V0(c.free_type),
41                )
42            } {
43                self.block_type_id_not_null_constraint(c.free_type, constraint);
44                return false;
45            }
46        } else {
47            if let Some(it) = self.deprecated_type_to_constraint_set.get(&c.free_type) {
48                if it.len() > 1 {
49                    self.block_type_id_not_null_constraint(c.free_type, constraint);
50                    return false;
51                }
52            }
53        }
54
55        let mut bind_to = c.primitive_type;
56
57        let free_type_ref = unsafe { &*free_type };
58        if free_type_ref.upper_bound != c.primitive_type
59            && maybe_singleton(free_type_ref.upper_bound)
60        {
61            bind_to = free_type_ref.lower_bound;
62        } else if let Some(et) = expected_type {
63            if maybe_singleton(et) {
64                bind_to = free_type_ref.lower_bound;
65            }
66        }
67
68        let ty = unsafe { follow_type_id(c.free_type) };
69        if !FFlag::LuauConstraintGraph.get() {
70            self.deprecate_d_shift_references(ty, bind_to);
71        }
72        self.bind_not_null_constraint_type_id_type_id(constraint, ty, bind_to);
73
74        true
75    }
76}