ruka_mir/types.rs
1use ruka_types::Ty;
2
3use crate::MirLocalId;
4
5/// Ownership mode carried into MIR from source function signatures.
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum MirOwnershipMode {
8 /// Read-only borrowed access.
9 View,
10 /// Mutable borrowed access.
11 MutBorrow,
12 /// Owned value transfer.
13 Owned,
14}
15
16/// Runtime/storage representation tracked for one MIR local.
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub enum MirLocalRepr {
19 /// Local stores a direct runtime value.
20 Value,
21 /// Local stores a read-only place/reference.
22 SharedPlace,
23 /// Local stores a mutable place/reference.
24 MutablePlace,
25}
26
27/// Heap ownership policy carried by one MIR local.
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub enum MirHeapOwnership {
30 /// Local does not participate in runtime heap retain/release operations.
31 None,
32 /// Local owns one runtime heap allocation that must be released.
33 Owned,
34 /// Local owns one runtime container whose nested payload is borrowed/shared.
35 OwnedShallow,
36 /// Local denotes a borrowed slice view and must not run retain/release.
37 BorrowedView,
38}
39
40impl MirHeapOwnership {
41 /// Return whether this ownership class requires runtime retain/release operations.
42 pub fn uses_heap_ops(self) -> bool {
43 matches!(self, Self::Owned | Self::OwnedShallow)
44 }
45}
46
47impl MirLocalRepr {
48 /// Return whether the local stores a place/reference.
49 pub fn is_place(self) -> bool {
50 matches!(self, Self::SharedPlace | Self::MutablePlace)
51 }
52
53 /// Return whether the local stores a mutable place/reference.
54 pub fn is_mutable_place(self) -> bool {
55 matches!(self, Self::MutablePlace)
56 }
57}
58
59/// Type syntax retained in MIR for emitted aggregate declarations.
60#[derive(Debug, Clone, PartialEq, Eq)]
61pub enum MirTypeExpr {
62 /// Named type constructor.
63 Named(String),
64 /// Pointer type constructor.
65 Pointer {
66 /// Type of the pointed-to value.
67 item: Box<MirTypeExpr>,
68 },
69 /// Fixed-size array type constructor.
70 Array {
71 /// Type of the pointed-to value.
72 item: Box<MirTypeExpr>,
73 /// Compile-time array length.
74 len: usize,
75 },
76 /// Borrowed slice type constructor.
77 Slice {
78 /// Type of the pointed-to value.
79 item: Box<MirTypeExpr>,
80 },
81 /// Tuple type constructor.
82 Tuple(Vec<MirTypeExpr>),
83 /// Type application with explicit arguments.
84 Apply {
85 /// Type constructor being applied.
86 callee: String,
87 /// Explicit type arguments to the constructor.
88 args: Vec<MirTypeExpr>,
89 },
90}
91
92/// Ownership mode used at MIR call sites.
93#[derive(Debug, Clone, Copy, PartialEq, Eq)]
94pub enum MirArgMode {
95 /// Mutable borrowed access.
96 Borrowed,
97 /// Mutable borrowed access.
98 MutableBorrow,
99 /// Owned move from the source location.
100 OwnedMove,
101 /// Owned copy from the source location.
102 OwnedCopy,
103}
104
105/// Single call argument with explicit ownership mode.
106#[derive(Debug, Clone)]
107pub struct MirCallArg {
108 /// Ownership mode applied to the argument.
109 pub mode: MirArgMode,
110 /// Local id supplying the argument value.
111 pub local: MirLocalId,
112}
113
114impl MirCallArg {
115 /// Return whether the call argument mode is mutable borrow.
116 pub fn is_mutable_borrow(&self) -> bool {
117 matches!(self.mode, MirArgMode::MutableBorrow)
118 }
119}
120
121/// Shared call-argument query object used by validation and backends.
122#[derive(Debug, Clone, Copy)]
123pub struct MirCallArgBinding<'a> {
124 /// Call argument payload.
125 pub arg: &'a MirCallArg,
126 /// Local metadata referenced by the argument.
127 pub local: &'a LocalInfo,
128}
129
130impl<'a> MirCallArgBinding<'a> {
131 /// Return the referenced local id.
132 pub fn local_id(self) -> MirLocalId {
133 self.arg.local
134 }
135
136 /// Return whether the argument mode is read-only borrow.
137 pub fn is_borrowed(self) -> bool {
138 matches!(self.arg.mode, MirArgMode::Borrowed)
139 }
140
141 /// Return whether the argument mode is mutable borrow.
142 pub fn is_mutable_borrow(self) -> bool {
143 matches!(self.arg.mode, MirArgMode::MutableBorrow)
144 }
145
146 /// Return whether the argument mode is owned move.
147 pub fn is_owned_move(self) -> bool {
148 matches!(self.arg.mode, MirArgMode::OwnedMove)
149 }
150
151 /// Return whether the argument mode is owned copy.
152 pub fn is_owned_copy(self) -> bool {
153 matches!(self.arg.mode, MirArgMode::OwnedCopy)
154 }
155
156 /// Return whether the argument local stores a place/reference.
157 pub fn is_place(self) -> bool {
158 self.local.is_place()
159 }
160
161 /// Return whether the argument local stores a mutable place/reference.
162 pub fn is_mutable_place(self) -> bool {
163 self.local.is_mutable_place()
164 }
165
166 /// Return the local semantic type.
167 pub fn local_ty(self) -> &'a Ty {
168 &self.local.ty
169 }
170
171 /// Return the place item type, when the local is place-shaped.
172 pub fn place_item_ty(self) -> Option<&'a Ty> {
173 self.local.place_item_ty()
174 }
175
176 /// Return whether reading the argument as a value requires dereferencing.
177 pub fn requires_deref_read(self) -> bool {
178 self.is_place() && !self.is_slice_place()
179 }
180
181 /// Return whether the place item is a slice view.
182 pub fn is_slice_place(self) -> bool {
183 matches!(self.place_item_ty(), Some(Ty::Slice(_)))
184 }
185}
186
187/// Single aggregate construction argument with explicit ownership mode.
188#[derive(Debug, Clone)]
189pub struct MirAggregateArg {
190 /// Ownership mode applied to the argument.
191 pub mode: MirArgMode,
192 /// Local id supplying the argument value.
193 pub local: MirLocalId,
194}
195
196impl MirAggregateArg {
197 /// Return whether the aggregate argument mode is owned move.
198 pub fn is_owned_move(&self) -> bool {
199 matches!(self.mode, MirArgMode::OwnedMove)
200 }
201
202 /// Return whether the aggregate argument mode is owned copy.
203 pub fn is_owned_copy(&self) -> bool {
204 matches!(self.mode, MirArgMode::OwnedCopy)
205 }
206}
207
208/// Builtin intrinsic operation invoked directly by generated code.
209#[derive(Debug, Clone, Copy, PartialEq, Eq)]
210pub enum MirIntrinsic {
211 /// Pointer allocation intrinsic.
212 Ptr,
213 /// Array construction intrinsic.
214 Array,
215}
216
217/// Metadata tracked for each MIR local.
218#[derive(Debug, Clone)]
219pub struct LocalInfo {
220 /// Optional debug-facing name for the local.
221 pub debug_name: Option<String>,
222 /// Provenance category of the local.
223 pub kind: LocalKind,
224 /// Runtime/storage representation of the local.
225 pub repr: MirLocalRepr,
226 /// Heap ownership policy used for retain/release and validation.
227 pub heap_ownership: MirHeapOwnership,
228 /// Semantic type assigned to the local.
229 pub ty: Ty,
230}
231
232impl LocalInfo {
233 /// Return whether this local stores a place/reference.
234 pub fn is_place(&self) -> bool {
235 self.repr.is_place()
236 }
237
238 /// Return whether this local stores a mutable place/reference.
239 pub fn is_mutable_place(&self) -> bool {
240 self.repr.is_mutable_place()
241 }
242
243 /// Return the semantic item type behind a place local, when applicable.
244 pub fn place_item_ty(&self) -> Option<&Ty> {
245 match &self.ty {
246 Ty::RefRo(inner) | Ty::RefMut(inner) => Some(inner.as_ref()),
247 _ => None,
248 }
249 }
250
251 /// Return whether this local needs runtime heap retain/release operations.
252 pub fn uses_heap_ops(&self) -> bool {
253 self.heap_ownership.uses_heap_ops()
254 }
255}
256
257/// Struct declaration retained for backend aggregate emission.
258#[derive(Debug, Clone)]
259pub struct MirStructDecl {
260 /// User-visible function or field name.
261 pub name: String,
262 /// Generic type parameters declared on the struct.
263 pub type_params: Vec<String>,
264 /// Fields declared on the struct.
265 pub fields: Vec<MirStructField>,
266}
267
268/// Named field declaration for a MIR struct type.
269#[derive(Debug, Clone)]
270pub struct MirStructField {
271 /// User-visible function or field name.
272 pub name: String,
273 /// Type expression declared for the field.
274 pub ty: MirTypeExpr,
275}
276
277/// Enum declaration retained for backend aggregate emission.
278#[derive(Debug, Clone)]
279pub struct MirEnumDecl {
280 /// User-visible enum name.
281 pub name: String,
282 /// Generic type parameters declared on the enum.
283 pub type_params: Vec<String>,
284 /// Variants declared on the enum.
285 pub variants: Vec<MirEnumVariant>,
286}
287
288/// Enum variant declaration for a MIR enum type.
289#[derive(Debug, Clone)]
290pub struct MirEnumVariant {
291 /// User-visible variant constructor name.
292 pub name: String,
293 /// Ordered payload type expressions.
294 pub payload: Vec<MirTypeExpr>,
295}
296
297/// Local provenance category.
298#[derive(Debug, Clone, Copy, PartialEq, Eq)]
299pub enum LocalKind {
300 /// Incoming function parameter local.
301 Param,
302 /// User binding local created by lowering.
303 Binding,
304 /// Compiler-generated temporary local.
305 Temp,
306}
307
308/// Infer heap ownership policy from one local type and representation.
309pub fn infer_heap_ownership(ty: &Ty, repr: MirLocalRepr) -> MirHeapOwnership {
310 if repr.is_place()
311 && matches!(ty, Ty::RefRo(inner) | Ty::RefMut(inner) if matches!(inner.as_ref(), Ty::Slice(_)))
312 {
313 return MirHeapOwnership::BorrowedView;
314 }
315 if matches!(
316 ty,
317 Ty::Pointer(_) | Ty::String | Ty::Array { .. } | Ty::Enum { .. }
318 ) {
319 return MirHeapOwnership::Owned;
320 }
321 MirHeapOwnership::None
322}