Skip to main content

luaur_analysis/methods/
mapped_generic_environment_lookup_generic_pack.rs

1use crate::functions::follow_type_pack::follow_type_pack_id;
2use crate::records::mapped_generic_environment::MappedGenericEnvironment;
3use crate::records::not_bindable::NotBindable;
4use crate::records::unmapped::Unmapped;
5use crate::type_aliases::lookup_result::LookupResult;
6use crate::type_aliases::type_pack_id::TypePackId;
7use alloc::vec::Vec;
8use luaur_common::records::variant::Variant3;
9
10impl MappedGenericEnvironment {
11    pub fn lookup_generic_pack(&self, generic_tp: TypePackId) -> LookupResult {
12        let generic_tp = unsafe { follow_type_pack_id(generic_tp) };
13
14        let mut current_frame_index = self.current_scope_index;
15
16        while let Some(index) = current_frame_index {
17            let current_frame = &self.frames[index];
18            if let Some(mapped_pack) =
19                crate::methods::subtyping_bind_generic::dense_hash_map_find_no_default(
20                    &current_frame.mappings,
21                    &generic_tp,
22                )
23            {
24                if let Some(tp) = *mapped_pack {
25                    return Variant3::V0(tp);
26                } else {
27                    return Variant3::V1(Unmapped { scope_index: index });
28                }
29            }
30            current_frame_index = current_frame.parent_scope_index;
31        }
32
33        if let Some(base_index) = self.current_scope_index {
34            let base_frame = &self.frames[base_index];
35            let mut to_check: Vec<usize> = base_frame.children.iter().copied().collect();
36
37            while let Some(curr_index) = to_check.pop() {
38                let current_frame = &self.frames[curr_index];
39                if let Some(mapped_pack) =
40                    crate::methods::subtyping_bind_generic::dense_hash_map_find_no_default(
41                        &current_frame.mappings,
42                        &generic_tp,
43                    )
44                {
45                    if let Some(tp) = *mapped_pack {
46                        return Variant3::V0(tp);
47                    } else {
48                        return Variant3::V1(Unmapped {
49                            scope_index: curr_index,
50                        });
51                    }
52                }
53                to_check.extend(current_frame.children.iter().copied());
54            }
55        }
56
57        Variant3::V2(NotBindable { _unused: None })
58    }
59}