luaur_analysis/methods/
normalizer_union_normals.rs1use crate::enums::normalization_result::NormalizationResult;
2use crate::functions::get_type_alt_j::get_type_id;
3use crate::functions::tyvar_index::tyvar_index;
4use crate::records::never_type::NeverType;
5use crate::records::normalized_extern_type::NormalizedExternType;
6use crate::records::normalized_function_type::NormalizedFunctionType;
7use crate::records::normalized_string_type::NormalizedStringType;
8use crate::records::normalized_type::NormalizedType;
9use crate::records::normalizer::Normalizer;
10use crate::records::type_ids::TypeIds;
11use crate::records::unknown_type::UnknownType;
12use crate::type_aliases::error_type::ErrorType;
13use alloc::collections::BTreeMap;
14use luaur_common::FFlag;
15
16impl Normalizer {
17 pub fn union_normals(
18 &mut self,
19 here: &mut NormalizedType,
20 there: &NormalizedType,
21 ignore_smaller_tyvars: i32,
22 ) -> NormalizationResult {
23 self.consume_fuel();
24
25 here.is_cacheable &= there.is_cacheable;
26
27 let mut tops = self.union_of_tops(here.tops, there.tops);
28 if !unsafe { get_type_id::<UnknownType>(tops).is_null() }
29 && (!unsafe { get_type_id::<ErrorType>(here.errors).is_null() }
30 || !unsafe { get_type_id::<ErrorType>(there.errors).is_null() })
31 {
32 tops = unsafe { (*here.builtin_types).anyType };
33 }
34
35 if unsafe { get_type_id::<NeverType>(tops).is_null() } {
36 self.clear_normal(here);
37 here.tops = tops;
38 return NormalizationResult::True;
39 }
40
41 for (tyvar, inter_box) in &there.tyvars {
42 let index = tyvar_index(*tyvar);
43 if index <= ignore_smaller_tyvars {
44 continue;
45 }
46
47 if !here.tyvars.contains_key(tyvar) {
48 let never_type = unsafe { (*here.builtin_types).neverType };
49 let mut fresh = NormalizedType {
50 builtin_types: here.builtin_types,
51 tops: never_type,
52 booleans: never_type,
53 extern_types: NormalizedExternType {
54 extern_types: BTreeMap::new(),
55 shape_extensions: TypeIds::type_ids(),
56 ordering: Vec::new(),
57 },
58 errors: never_type,
59 nils: never_type,
60 numbers: never_type,
61 integers: never_type,
62 strings: NormalizedStringType::never,
63 threads: never_type,
64 buffers: never_type,
65 tables: TypeIds::type_ids(),
66 functions: NormalizedFunctionType {
67 is_top: false,
68 parts: TypeIds::type_ids(),
69 },
70 tyvars: BTreeMap::new(),
71 is_cacheable: true,
72 };
73 let res = self.union_normals(&mut fresh, here, index);
74 if res != NormalizationResult::True {
75 return res;
76 }
77 here.tyvars.insert(*tyvar, Box::new(fresh));
78 }
79
80 if let Some(mut current) = here.tyvars.remove(tyvar) {
81 let res = self.union_normals(&mut current, inter_box, index);
82 if res != NormalizationResult::True {
83 return res;
84 }
85 here.tyvars.insert(*tyvar, current);
86 }
87 }
88
89 here.booleans = self.union_of_bools(here.booleans, there.booleans);
90 self.union_extern_types_normalized_extern_type_normalized_extern_type(
91 &mut here.extern_types,
92 &there.extern_types,
93 );
94
95 here.errors = if !unsafe { get_type_id::<NeverType>(there.errors).is_null() } {
96 here.errors
97 } else {
98 there.errors
99 };
100 here.nils = if !unsafe { get_type_id::<NeverType>(there.nils).is_null() } {
101 here.nils
102 } else {
103 there.nils
104 };
105 here.numbers = if !unsafe { get_type_id::<NeverType>(there.numbers).is_null() } {
106 here.numbers
107 } else {
108 there.numbers
109 };
110 if FFlag::LuauIntegerType2.get() {
111 here.integers = if !unsafe { get_type_id::<NeverType>(there.integers).is_null() } {
112 here.integers
113 } else {
114 there.integers
115 };
116 }
117 self.union_strings(&mut here.strings, &there.strings);
118 here.threads = if !unsafe { get_type_id::<NeverType>(there.threads).is_null() } {
119 here.threads
120 } else {
121 there.threads
122 };
123 here.buffers = if !unsafe { get_type_id::<NeverType>(there.buffers).is_null() } {
124 here.buffers
125 } else {
126 there.buffers
127 };
128 self.union_functions(&mut here.functions, &there.functions);
129 self.union_tables(&mut here.tables, &there.tables);
130
131 NormalizationResult::True
132 }
133}