ruka_mir/
lib.rs

1#![doc = include_str!("docs.md")]
2
3mod cfg;
4mod ids;
5mod instr;
6mod types;
7
8/// Browser-friendly MIR graph rendering for interactive viewers.
9pub mod browser_graph;
10/// Stable naming helpers for MIR-based outputs.
11pub mod naming;
12
13pub use cfg::*;
14pub use ids::*;
15pub use instr::*;
16pub use types::*;
17
18#[cfg(test)]
19mod tests {
20    use cranelift_entity::PrimaryMap;
21    use ruka_types::Ty;
22
23    use crate::{
24        infer_heap_ownership, LocalInfo, LocalKind, MirBlock, MirFunction, MirHeapOwnership,
25        MirInstr, MirLocalRepr, MirOwnershipMode, MirTerminator,
26    };
27
28    /// Build a small MIR function with a place-typed lhs in `IntEq`.
29    fn function_with_place_lhs_in_int_eq() -> MirFunction {
30        let mut locals = PrimaryMap::new();
31        let lhs = locals.push(LocalInfo {
32            debug_name: Some("lhs".to_owned()),
33            kind: LocalKind::Temp,
34            repr: MirLocalRepr::SharedPlace,
35            heap_ownership: MirHeapOwnership::None,
36            ty: Ty::RefRo(Box::new(Ty::I64)),
37        });
38        let rhs = locals.push(LocalInfo {
39            debug_name: Some("rhs".to_owned()),
40            kind: LocalKind::Temp,
41            repr: MirLocalRepr::Value,
42            heap_ownership: MirHeapOwnership::None,
43            ty: Ty::I64,
44        });
45        let dst = locals.push(LocalInfo {
46            debug_name: Some("dst".to_owned()),
47            kind: LocalKind::Temp,
48            repr: MirLocalRepr::Value,
49            heap_ownership: MirHeapOwnership::None,
50            ty: Ty::Bool,
51        });
52
53        let mut blocks = PrimaryMap::new();
54        let entry = blocks.push(MirBlock {
55            params: Vec::new(),
56            instrs: vec![MirInstr::IntEq { lhs, rhs, dst }],
57            terminator: MirTerminator::Return { value: dst },
58        });
59
60        MirFunction {
61            name: "test".to_owned(),
62            arity: 0,
63            return_ty: Ty::Bool,
64            locals,
65            params: Vec::new(),
66            param_modes: Vec::new(),
67            entry,
68            blocks,
69        }
70    }
71
72    #[test]
73    #[should_panic(expected = "uses place lhs")]
74    fn assert_valid_rejects_place_lhs_in_new_relational_instr() {
75        let function = function_with_place_lhs_in_int_eq();
76
77        function.assert_valid();
78    }
79
80    #[test]
81    fn infer_heap_ownership_marks_slice_place_as_borrowed_view() {
82        let ownership = infer_heap_ownership(
83            &Ty::RefRo(Box::new(Ty::Slice(Box::new(Ty::I64)))),
84            MirLocalRepr::SharedPlace,
85        );
86
87        assert_eq!(ownership, MirHeapOwnership::BorrowedView);
88    }
89
90    #[test]
91    fn infer_heap_ownership_marks_array_value_as_owned() {
92        let ownership = infer_heap_ownership(
93            &Ty::Array {
94                item: Box::new(Ty::I64),
95                len: 3,
96            },
97            MirLocalRepr::Value,
98        );
99
100        assert_eq!(ownership, MirHeapOwnership::Owned);
101    }
102
103    #[test]
104    fn param_binding_helpers_report_view_materialization_case() {
105        let mut locals = PrimaryMap::new();
106        let param = locals.push(LocalInfo {
107            debug_name: Some("p".to_owned()),
108            kind: LocalKind::Param,
109            repr: MirLocalRepr::Value,
110            heap_ownership: MirHeapOwnership::None,
111            ty: Ty::I64,
112        });
113
114        let mut blocks = PrimaryMap::new();
115        let entry = blocks.push(MirBlock {
116            params: Vec::new(),
117            instrs: Vec::new(),
118            terminator: MirTerminator::Return { value: param },
119        });
120
121        let function = MirFunction {
122            name: "test".to_owned(),
123            arity: 1,
124            return_ty: Ty::I64,
125            locals,
126            params: vec![param],
127            param_modes: vec![MirOwnershipMode::View],
128            entry,
129            blocks,
130        };
131
132        let binding = function.param_binding(0);
133        assert!(binding.expects_view());
134        assert!(!binding.expects_mut_borrow());
135        assert!(!binding.expects_owned());
136        assert!(binding.requires_materialization());
137        assert!(binding.materializes_view_from_owned());
138    }
139}