1mod cache;
6mod calc_compat;
7mod flags;
8pub mod prelude;
9mod pretty_print;
10mod supporting_types;
11mod type_kind;
12
13use crate::flags::TypeFlags;
14pub use crate::type_kind::TypeKind;
15use std::fmt::{Display, Formatter};
16use std::rc::Rc;
17
18#[derive(PartialEq, Clone, Eq, Hash, Copy, Debug)]
19pub struct TypeId(u32);
20
21impl TypeId {
22 pub const EMPTY: u32 = 0xffffffff;
23
24 #[must_use]
25 pub const fn new(id: u32) -> Self {
26 Self(id)
27 }
28
29 #[must_use]
30 pub const fn inner(&self) -> u32 {
31 self.0
32 }
33}
34
35impl Display for TypeId {
36 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
37 write!(f, "{}", self.0)
38 }
39}
40
41#[derive(Debug, Clone, PartialEq, Eq, Hash)]
42pub struct Type {
43 pub id: TypeId,
44 pub flags: TypeFlags,
45 pub kind: Rc<TypeKind>,
46}
47
48pub type TypeRef = Rc<Type>;
49
50impl Display for Type {
51 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
52 write!(f, "{}", self.kind)
53 }
54}
55
56impl Type {
57 #[inline]
58 #[must_use]
59 pub const fn is_scalar(&self) -> bool {
60 self.flags.contains(TypeFlags::IS_SCALAR)
61 }
62
63 #[inline]
64 #[must_use]
65 pub const fn can_be_stored_in_field(&self) -> bool {
66 self.flags.contains(TypeFlags::IS_STORAGE)
67 }
68
69 #[inline]
70 #[must_use]
71 pub const fn can_be_stored_in_transient_field(&self) -> bool {
72 self.flags.contains(TypeFlags::ALLOWED_FOR_SCOPED_BORROW)
73 }
74
75 #[inline]
76 #[must_use]
77 pub const fn can_be_stored_in_variable(&self) -> bool {
78 self.flags.contains(TypeFlags::ALLOWED_FOR_VARIABLE)
79 }
80
81 #[must_use]
82 pub fn is_option(&self) -> bool {
83 matches!(&*self.kind, TypeKind::Optional(_))
84 }
85
86 #[inline]
87 #[must_use]
88 pub const fn is_storage(&self) -> bool {
89 self.flags.contains(TypeFlags::IS_STORAGE)
90 }
91
92 #[inline]
93 #[must_use]
94 pub const fn allowed_as_return_type(&self) -> bool {
95 self.flags.contains(TypeFlags::IS_ALLOWED_RETURN)
96 }
97
98 #[inline]
99 #[must_use]
100 pub const fn allowed_as_parameter_type(&self) -> bool {
101 self.flags.contains(TypeFlags::IS_ALLOWED_RETURN)
102 }
103
104 #[inline]
105 #[must_use]
106 pub const fn allowed_for_scoped_borrow(&self) -> bool {
107 self.flags.contains(TypeFlags::ALLOWED_FOR_SCOPED_BORROW)
108 }
109
110 #[inline]
111 #[must_use]
112 pub const fn can_be_materialized(&self) -> bool {
113 self.flags.contains(TypeFlags::ALLOWED_FOR_SCOPED_BORROW)
114 | self.flags.contains(TypeFlags::IS_STORAGE)
115 }
116
117 #[must_use]
121 pub fn collection_view_that_needs_explicit_storage(&self) -> bool {
122 match &*self.kind {
123 TypeKind::DynamicLengthVecView(_)
125 | TypeKind::DynamicLengthMapView(_, _)
126 | TypeKind::StackView(_)
127 | TypeKind::QueueView(_)
128 | TypeKind::SparseView(_)
129 | TypeKind::GridView(_)
130 | TypeKind::SliceView(_) => true,
131
132 TypeKind::Optional(inner_type) => {
134 inner_type.collection_view_that_needs_explicit_storage()
135 }
136
137 _ => false,
138 }
139 }
140}