Skip to main content

luaur_analysis/methods/
constraint_generator_flatten_pack.rs

1use crate::functions::first::first;
2use crate::functions::get_mutable_type::get_mutable_type_id;
3use crate::records::blocked_type::BlockedType;
4use crate::records::constraint_generator::ConstraintGenerator;
5use crate::records::inference::Inference;
6use crate::records::inference_pack::InferencePack;
7use crate::records::unpack_constraint::UnpackConstraint;
8use crate::type_aliases::constraint_v::ConstraintV;
9use crate::type_aliases::scope_ptr_constraint_generator::ScopePtr;
10use alloc::vec;
11use luaur_ast::records::location::Location;
12
13impl ConstraintGenerator {
14    pub fn flatten_pack(
15        &mut self,
16        scope: &ScopePtr,
17        location: Location,
18        pack: InferencePack,
19    ) -> Inference {
20        let tp = pack.tp;
21        let refinements = pack.refinements;
22
23        let mut refinement = None;
24        if !refinements.is_empty() {
25            refinement = Some(refinements[0]);
26        }
27
28        if let Some(f) = first(tp, true) {
29            return Inference::inference_type_id_refinement_id(
30                f,
31                refinement.unwrap_or(core::ptr::null_mut()),
32            );
33        }
34
35        // Create a blocked type: arena->addType(BlockedType{})
36        let type_result = unsafe { (*self.arena).add_type(BlockedType::default()) };
37
38        // addConstraint(scope, location, UnpackConstraint{{typeResult}, tp})
39        let unpack_constraint = UnpackConstraint {
40            result_pack: vec![type_result],
41            source_pack: tp,
42        };
43        let constraint_ptr = self.add_constraint_scope_ptr_location_constraint_v(
44            scope,
45            location,
46            ConstraintV::Unpack(unpack_constraint),
47        );
48
49        // getMutable<BlockedType>(typeResult)->setOwner(c)
50        unsafe {
51            let blocked = get_mutable_type_id::<BlockedType>(type_result);
52            (*blocked).set_owner(constraint_ptr as *const _);
53        }
54
55        Inference::inference_type_id_refinement_id(
56            type_result,
57            refinement.unwrap_or(core::ptr::null_mut()),
58        )
59    }
60}