luaur_analysis/methods/
constraint_generator_lookup.rs1use crate::functions::get_def::get_def_id;
2use crate::records::blocked_type::BlockedType;
3use crate::records::cell::Cell;
4use crate::records::constraint_generator::ConstraintGenerator;
5use crate::records::phi::Phi;
6use crate::records::scope::Scope;
7use crate::records::type_ids::TypeIds;
8use crate::type_aliases::def_id_def::DefId;
9use crate::type_aliases::scope_ptr_constraint_generator::ScopePtr;
10use crate::type_aliases::type_id::TypeId;
11use luaur_ast::records::location::Location;
12
13impl ConstraintGenerator {
14 pub fn lookup(
15 &mut self,
16 scope: &ScopePtr,
17 location: Location,
18 def: DefId,
19 prototype: bool,
20 ) -> Option<TypeId> {
21 if unsafe { !get_def_id::<Cell>(def).is_null() } {
22 return scope.lookup_def_id(def);
23 }
24
25 if let Some(phi) = unsafe { get_def_id::<Phi>(def).as_ref() } {
26 if let Some(found) = scope.lookup_def_id(def) {
27 return Some(found);
28 } else if !prototype && phi.operands.len() == 1 {
29 return self.lookup(scope, location, phi.operands[0], prototype);
30 } else if !prototype {
31 return None;
32 }
33
34 let mut res = unsafe { (*self.builtin_types).neverType };
35
36 for operand in &phi.operands {
37 let mut ty = self.lookup(scope, location, *operand, false);
38 if ty.is_none() {
39 let blocked_ty = unsafe {
40 (*self.arena).add_type(BlockedType {
41 index: 0,
42 owner: core::ptr::null(),
43 })
44 };
45 self.local_types.try_insert(blocked_ty, TypeIds::type_ids());
46 unsafe {
47 *(*self.root_scope).lvalue_types.get_or_insert(*operand) = blocked_ty;
48 }
49 ty = Some(blocked_ty);
50 }
51
52 res = self.make_union_scope_ptr_location_type_id_type_id(
53 self.root_scope,
54 location,
55 res,
56 ty.unwrap(),
57 );
58 }
59
60 unsafe {
61 let scope_ptr = scope.as_ref() as *const Scope as *mut Scope;
62 *(*scope_ptr).lvalue_types.get_or_insert(def) = res;
63 }
64 return Some(res);
65 }
66
67 unsafe { (*self.ice).ice_string("ConstraintGenerator::lookup is inexhaustive?") };
68 None
69 }
70}