luaur_analysis/methods/
subtyping_is_sub_tail_covariant_with.rs1use crate::enums::early_exit::EarlyExit;
4use crate::enums::pack_field::PackField;
5use crate::enums::subtyping_suppression_policy::SubtypingSuppressionPolicy;
6use crate::enums::variant::Variant;
7use crate::functions::get_type_pack::get_type_pack_id;
8use crate::functions::slice_type_pack::slice_type_pack;
9use crate::records::error_type_pack::ErrorTypePack;
10use crate::records::free_type_pack::FreeTypePack;
11use crate::records::generic_pack_mapping::GenericPackMapping;
12use crate::records::generic_type_pack::GenericTypePack;
13use crate::records::index::Index;
14use crate::records::pack_slice::PackSlice;
15use crate::records::pack_subtype_constraint::PackSubtypeConstraint;
16use crate::records::scope::Scope;
17use crate::records::subtyping::Subtyping;
18use crate::records::subtyping_environment::SubtypingEnvironment;
19use crate::records::subtyping_result::SubtypingResult;
20use crate::records::type_error::TypeError;
21use crate::records::type_pack::TypePack;
22use crate::records::unexpected_type_pack_in_subtyping::UnexpectedTypePackInSubtyping;
23use crate::records::variadic_type_pack::VariadicTypePack;
24use crate::type_aliases::component::Component;
25use crate::type_aliases::constraint_v::ConstraintV;
26use crate::type_aliases::lookup_result::LookupResult;
27use crate::type_aliases::path::Path;
28use crate::type_aliases::type_id::TypeId;
29use crate::type_aliases::type_pack_id::TypePackId;
30
31use crate::functions::follow_type_pack::follow_type_pack_id;
32use crate::methods::path_builder_build::PathBuilderBuild;
33use crate::methods::path_builder_tail::PathBuilderTail;
34use crate::methods::path_builder_variadic::PathBuilderVariadic;
35use crate::records::path_builder::PathBuilder;
36
37impl Subtyping {
38 pub fn is_sub_tail_covariant_with(
39 &mut self,
40 env: &mut SubtypingEnvironment,
41 output_result: &mut SubtypingResult,
42 sub_tp: TypePackId,
43 sub_tail: TypePackId,
44 super_tp: TypePackId,
45 super_head_start_index: usize,
46 super_head: &Vec<TypeId>,
47 super_tail: Option<TypePackId>,
48 scope: *mut Scope,
49 ) -> EarlyExit {
50 let _ = sub_tp;
51
52 if let Some(vt) = unsafe { get_type_pack_id::<VariadicTypePack>(sub_tail).as_ref() } {
53 for i in super_head_start_index..super_head.len() {
54 let mut next = self
55 .is_covariant_with_subtyping_environment_type_id_type_id_not_null_scope(
56 env,
57 vt.ty,
58 super_head[i],
59 scope,
60 );
61 next.with_sub_path(
62 PathBuilder {
63 components: alloc::vec::Vec::new(),
64 }
65 .tail()
66 .variadic()
67 .build(),
68 );
69 next.with_super_component(Component::Index(Index {
70 index: i,
71 variant: Variant::Pack,
72 }));
73 output_result.and_also(next, SubtypingSuppressionPolicy::Any);
74 }
75 EarlyExit::No
76 } else if !unsafe { get_type_pack_id::<GenericTypePack>(sub_tail).is_null() } {
77 let lookup_result = env.lookup_generic_pack(sub_tail);
78 let result: SubtypingResult;
79 if let LookupResult::V2(_) = lookup_result {
80 let mut r = SubtypingResult {
82 is_subtype: false,
83 normalization_too_complex: false,
84 is_cacheable: false,
85 ..Default::default()
86 };
87 r.with_sub_component(Component::PackField(PackField::Tail));
88 r.with_super_component(Component::PackSlice(PackSlice {
89 start_index: super_head_start_index,
90 }));
91 result = r;
92 } else {
93 let super_tail_pack = slice_type_pack(
94 super_head_start_index,
95 super_tp,
96 super_head,
97 super_tail,
98 unsafe { &*self.builtin_types },
99 unsafe { &mut *self.arena },
100 );
101
102 if let LookupResult::V0(mapped_gen) = lookup_result {
103 let mut sub_tp_to_compare = mapped_gen;
105
106 let tp = unsafe { get_type_pack_id::<TypePack>(mapped_gen).as_ref() };
109 if let Some(tp) = tp {
110 if let Some(tail) = tp.tail {
111 let vtp = unsafe {
112 get_type_pack_id::<VariadicTypePack>(follow_type_pack_id(tail))
113 .as_ref()
114 };
115 if let Some(vtp) = vtp {
116 if vtp.hidden {
117 sub_tp_to_compare = unsafe {
118 (*self.arena)
119 .add_type_pack_initializer_list_type_id(&tp.head)
120 };
121 }
122 }
123 }
124 }
125
126 let mut r = self
127 .is_covariant_with_subtyping_environment_type_pack_id_type_pack_id_not_null_scope(
128 env,
129 sub_tp_to_compare,
130 super_tail_pack,
131 scope,
132 );
133 r.with_sub_path(Path::from_components(alloc::vec![
134 Component::PackField(PackField::Tail),
135 Component::GenericPackMapping(GenericPackMapping {
136 mappedType: mapped_gen
137 }),
138 ]));
139 r.with_super_component(Component::PackSlice(PackSlice {
140 start_index: super_head_start_index,
141 }));
142 result = r;
143 } else {
144 let ok = env
146 .mapped_generic_packs
147 .bind_generic(sub_tail, super_tail_pack);
148 let mut r = SubtypingResult {
149 is_subtype: ok,
150 normalization_too_complex: false,
151 is_cacheable: false,
152 ..Default::default()
153 };
154 r.with_sub_component(Component::PackField(PackField::Tail));
155 r.with_super_component(Component::PackSlice(PackSlice {
156 start_index: super_head_start_index,
157 }));
158 result = r;
159 }
160 }
161
162 output_result.and_also(result, SubtypingSuppressionPolicy::Any);
163 EarlyExit::Yes
164 } else if !unsafe { get_type_pack_id::<ErrorTypePack>(sub_tail).is_null() } {
165 let mut r = SubtypingResult {
166 is_subtype: true,
167 ..Default::default()
168 };
169 r.with_sub_component(Component::PackField(PackField::Tail));
170 *output_result = r;
171 EarlyExit::Yes
172 } else if !unsafe { get_type_pack_id::<FreeTypePack>(sub_tail).is_null() } {
173 let super_tail_pack = slice_type_pack(
174 super_head_start_index,
175 super_tp,
176 super_head,
177 super_tail,
178 unsafe { &*self.builtin_types },
179 unsafe { &mut *self.arena },
180 );
181 let mut r = SubtypingResult {
182 is_subtype: true,
183 ..Default::default()
184 };
185 r.with_sub_component(Component::PackField(PackField::Tail));
186 r.with_assumed_constraint(ConstraintV::PackSubtype(PackSubtypeConstraint {
187 sub_pack: sub_tail,
188 super_pack: super_tail_pack,
189 returns: false,
190 }));
191 output_result.and_also(r, SubtypingSuppressionPolicy::Any);
192 EarlyExit::Yes
193 } else {
194 let mut r = SubtypingResult {
195 is_subtype: false,
196 ..Default::default()
197 };
198 r.with_sub_component(Component::PackField(PackField::Tail));
199 r.with_error(TypeError::type_error_location_type_error_data(
200 unsafe { (*scope).location.clone() },
201 UnexpectedTypePackInSubtyping { tp: sub_tail }.into(),
202 ));
203 *output_result = r;
204 EarlyExit::Yes
205 }
206 }
207}