Skip to main content

luaur_analysis/methods/
constraint_solver_try_dispatch_constraint_solver_alt_v.rs

1use crate::functions::push_type_into::push_type_into;
2use crate::records::constraint::Constraint;
3use crate::records::constraint_solver::ConstraintSolver;
4use crate::records::internal_error_reporter::InternalErrorReporter;
5use crate::records::push_type_constraint::PushTypeConstraint;
6use crate::records::subtyping::Subtyping;
7use crate::records::unifier_2::Unifier2;
8use core::ffi::c_void;
9use core::ptr::NonNull;
10use luaur_ast::records::ast_expr::AstExpr;
11use luaur_common::records::dense_hash_map::DenseHashMap;
12use luaur_common::records::dense_hash_set::DenseHashSet;
13
14impl ConstraintSolver {
15    pub fn try_dispatch_push_type_constraint_not_null_constraint_bool(
16        &mut self,
17        c: &PushTypeConstraint,
18        constraint: *const Constraint,
19        force: bool,
20    ) -> bool {
21        let mut u2 = Unifier2::unifier_2_not_null_type_arena_not_null_builtin_types_not_null_scope_not_null_internal_error_reporter_dense_hash_set_void(
22            NonNull::new(self.arena).unwrap(),
23            NonNull::new(self.builtin_types).unwrap(),
24            NonNull::new(unsafe { (*constraint).scope }).unwrap(),
25            NonNull::new(&self.ice_reporter as *const InternalErrorReporter as *mut InternalErrorReporter).unwrap(),
26            &mut self.uninhabited_type_functions as *mut DenseHashSet<*const c_void>,
27        );
28
29        let mut subtyping = Subtyping::subtyping_owned(
30            self.builtin_types,
31            self.arena,
32            self.normalizer,
33            self.type_function_runtime,
34            &self.ice_reporter as *const InternalErrorReporter as *mut InternalErrorReporter,
35        );
36
37        // NOTE: If we don't do this check up front, we almost immediately start
38        // spawning tons of push type constraints. It's pretty important.
39        if self.is_blocked_type_id(c.expectedType) {
40            self.block_type_id_not_null_constraint(c.expectedType, constraint);
41            // If we're forcing this constraint and the expected type is blocked, we
42            // should just bail.
43            return force;
44        }
45
46        let mut empty: DenseHashSet<*const c_void> = DenseHashSet::new(core::ptr::null_mut());
47        let result = push_type_into(
48            NonNull::new(
49                c.astTypes
50                    as *mut DenseHashMap<*const AstExpr, crate::type_aliases::type_id::TypeId>,
51            )
52            .unwrap(),
53            NonNull::new(
54                c.astExpectedTypes
55                    as *mut DenseHashMap<*const AstExpr, crate::type_aliases::type_id::TypeId>,
56            )
57            .unwrap(),
58            NonNull::new(self as *mut ConstraintSolver).unwrap(),
59            NonNull::new(constraint as *mut Constraint).unwrap(),
60            NonNull::new(&mut empty as *mut DenseHashSet<*const c_void>).unwrap(),
61            NonNull::new(&mut u2 as *mut Unifier2).unwrap(),
62            NonNull::new(&mut subtyping as *mut Subtyping).unwrap(),
63            c.expectedType,
64            c.expr,
65        );
66
67        // If we're forcing this constraint, just early exit: we can continue
68        // inferring the rest of the file, we might just error when we shouldn't.
69        if force || result.incomplete_types.is_empty() {
70            return true;
71        }
72
73        for incomplete in &result.incomplete_types {
74            let addition = self.push_constraint(
75                NonNull::new(unsafe { (*constraint).scope }).unwrap(),
76                unsafe { (*constraint).location },
77                crate::type_aliases::constraint_v::ConstraintV::PushType(PushTypeConstraint {
78                    expectedType: incomplete.expectedType,
79                    targetType: incomplete.targetType,
80                    astTypes: c.astTypes,
81                    astExpectedTypes: c.astExpectedTypes,
82                    expr: incomplete.expr,
83                }),
84            );
85            self.inherit_blocks(constraint, addition.as_ptr());
86        }
87
88        true
89    }
90}