1#![doc = include_str!("docs.md")]
2
3mod cfg;
4mod ids;
5mod instr;
6mod types;
7
8pub mod browser_graph;
10pub 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 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}