luaur_analysis/functions/
are_equivalent.rs1use crate::functions::follow_type::follow_type_id;
2use crate::functions::follow_type_pack::follow_type_pack_id;
3use crate::records::type_function_instance_type::TypeFunctionInstanceType;
4use crate::records::type_function_instance_type_pack::TypeFunctionInstanceTypePack;
5use crate::type_aliases::type_id::TypeId;
6use crate::type_aliases::type_pack_id::TypePackId;
7
8pub trait TypeFunctionInstanceEquivalent {
10 fn same_function(&self, other: &Self) -> bool;
11 fn type_arguments(&self) -> &[TypeId];
12 fn pack_arguments(&self) -> &[TypePackId];
13}
14
15impl TypeFunctionInstanceEquivalent for TypeFunctionInstanceType {
16 fn same_function(&self, other: &Self) -> bool {
17 self.function == other.function
18 }
19
20 fn type_arguments(&self) -> &[TypeId] {
21 &self.type_arguments
22 }
23
24 fn pack_arguments(&self) -> &[TypePackId] {
25 &self.pack_arguments
26 }
27}
28
29impl TypeFunctionInstanceEquivalent for TypeFunctionInstanceTypePack {
30 fn same_function(&self, other: &Self) -> bool {
31 self.function == other.function
32 }
33
34 fn type_arguments(&self) -> &[TypeId] {
35 &self.typeArguments
36 }
37
38 fn pack_arguments(&self) -> &[TypePackId] {
39 &self.packArguments
40 }
41}
42
43pub fn are_equivalent<T: TypeFunctionInstanceEquivalent>(a: &T, b: &T) -> bool {
44 if !a.same_function(b) {
45 return false;
46 }
47
48 if a.type_arguments().len() != b.type_arguments().len()
49 || a.pack_arguments().len() != b.pack_arguments().len()
50 {
51 return false;
52 }
53
54 for (a_arg, b_arg) in a.type_arguments().iter().zip(b.type_arguments().iter()) {
55 if unsafe { follow_type_id(*a_arg) } != unsafe { follow_type_id(*b_arg) } {
56 return false;
57 }
58 }
59
60 for (a_arg, b_arg) in a.pack_arguments().iter().zip(b.pack_arguments().iter()) {
61 if unsafe { follow_type_pack_id(*a_arg) } != unsafe { follow_type_pack_id(*b_arg) } {
62 return false;
63 }
64 }
65
66 true
67}