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}