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