rune/compile/v1/
linear.rs
1use core::array;
2use core::fmt;
3use core::ops::{Deref, DerefMut};
4use core::slice;
5
6use crate::alloc::{vec, Vec};
7use crate::compile;
8use crate::runtime::InstAddress;
9
10use super::Address;
11
12enum Addresses<'a, 'hir> {
13 Single(Address<'a, 'hir>),
14 List(Vec<Address<'a, 'hir>>),
15}
16
17#[must_use = "This should be freed with a call to Scopes::free_linear"]
18pub(super) struct Linear<'a, 'hir> {
19 addresses: Addresses<'a, 'hir>,
20}
21
22impl<'a, 'hir> Linear<'a, 'hir> {
23 pub(super) fn new(list: Vec<Address<'a, 'hir>>) -> Self {
25 Self {
26 addresses: Addresses::List(list),
27 }
28 }
29
30 pub(super) const fn empty() -> Self {
32 Self {
33 addresses: Addresses::List(Vec::new()),
34 }
35 }
36
37 pub(super) fn single(address: Address<'a, 'hir>) -> Self {
39 Self {
40 addresses: Addresses::Single(address),
41 }
42 }
43
44 #[inline]
45 pub(super) fn addr(&self) -> InstAddress {
46 match &self.addresses {
47 Addresses::Single(address) => address.addr(),
48 Addresses::List(list) => list.first().map_or(InstAddress::INVALID, Address::addr),
49 }
50 }
51
52 #[inline]
53 pub(super) fn iter(&self) -> slice::Iter<'_, Address<'a, 'hir>> {
54 <[_]>::iter(self)
55 }
56
57 #[inline]
58 pub(super) fn iter_mut(&mut self) -> slice::IterMut<'_, Address<'a, 'hir>> {
59 <[_]>::iter_mut(self)
60 }
61
62 #[inline]
63 pub(super) fn free(self) -> compile::Result<()> {
64 for addr in self.into_iter().rev() {
65 addr.free()?;
66 }
67
68 Ok(())
69 }
70
71 #[inline]
72 pub(super) fn free_non_dangling(self) -> compile::Result<()> {
73 for addr in self.into_iter().rev() {
74 addr.free_non_dangling()?;
75 }
76
77 Ok(())
78 }
79
80 #[inline]
81 pub(super) fn forget(self) -> compile::Result<()> {
82 for var in self {
83 var.forget()?;
84 }
85
86 Ok(())
87 }
88}
89
90impl<'b, 'a, 'hir> IntoIterator for &'b Linear<'a, 'hir> {
91 type Item = &'b Address<'a, 'hir>;
92 type IntoIter = slice::Iter<'b, Address<'a, 'hir>>;
93
94 #[inline]
95 fn into_iter(self) -> Self::IntoIter {
96 self.iter()
97 }
98}
99
100impl<'b, 'a, 'hir> IntoIterator for &'b mut Linear<'a, 'hir> {
101 type Item = &'b mut Address<'a, 'hir>;
102 type IntoIter = slice::IterMut<'b, Address<'a, 'hir>>;
103
104 #[inline]
105 fn into_iter(self) -> Self::IntoIter {
106 self.iter_mut()
107 }
108}
109
110impl<'a, 'hir> Deref for Linear<'a, 'hir> {
111 type Target = [Address<'a, 'hir>];
112
113 #[inline]
114 fn deref(&self) -> &Self::Target {
115 match &self.addresses {
116 Addresses::Single(address) => slice::from_ref(address),
117 Addresses::List(list) => list,
118 }
119 }
120}
121
122impl DerefMut for Linear<'_, '_> {
123 #[inline]
124 fn deref_mut(&mut self) -> &mut Self::Target {
125 match &mut self.addresses {
126 Addresses::Single(address) => slice::from_mut(address),
127 Addresses::List(list) => list,
128 }
129 }
130}
131
132impl fmt::Debug for Linear<'_, '_> {
133 #[inline]
134 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135 f.debug_list().entries(self.iter()).finish()
136 }
137}
138
139impl<'a, 'hir> IntoIterator for Linear<'a, 'hir> {
140 type Item = Address<'a, 'hir>;
141 type IntoIter = IntoIter<'a, 'hir>;
142
143 #[inline]
144 fn into_iter(self) -> Self::IntoIter {
145 IntoIter {
146 inner: match self.addresses {
147 Addresses::Single(address) => IntoIterRepr::Single([address].into_iter()),
148 Addresses::List(list) => IntoIterRepr::Vec(list.into_iter()),
149 },
150 }
151 }
152}
153
154enum IntoIterRepr<'a, 'hir> {
155 Vec(vec::IntoIter<Address<'a, 'hir>>),
156 Single(array::IntoIter<Address<'a, 'hir>, 1>),
157}
158
159pub(super) struct IntoIter<'a, 'hir> {
160 inner: IntoIterRepr<'a, 'hir>,
161}
162
163impl<'a, 'hir> Iterator for IntoIter<'a, 'hir> {
164 type Item = Address<'a, 'hir>;
165
166 #[inline]
167 fn next(&mut self) -> Option<Self::Item> {
168 match &mut self.inner {
169 IntoIterRepr::Vec(iter) => iter.next(),
170 IntoIterRepr::Single(iter) => iter.next(),
171 }
172 }
173}
174
175impl ExactSizeIterator for IntoIter<'_, '_> {
176 #[inline]
177 fn len(&self) -> usize {
178 match &self.inner {
179 IntoIterRepr::Vec(iter) => iter.len(),
180 IntoIterRepr::Single(iter) => iter.len(),
181 }
182 }
183}
184
185impl DoubleEndedIterator for IntoIter<'_, '_> {
186 #[inline]
187 fn next_back(&mut self) -> Option<Self::Item> {
188 match &mut self.inner {
189 IntoIterRepr::Vec(iter) => iter.next_back(),
190 IntoIterRepr::Single(iter) => iter.next_back(),
191 }
192 }
193}