midenc_hir/ir/value/
aliasing.rs1use core::{fmt, num::NonZeroU8};
2
3use super::*;
4
5#[derive(Copy, Clone)]
11pub struct ValueOrAlias {
12 value: ValueRef,
14 value_id: ValueId,
16 alias_id: u8,
20}
21
22impl ValueOrAlias {
23 pub fn new(value: ValueRef) -> Self {
25 let value_id = value.borrow().id();
26 Self {
27 value,
28 value_id,
29 alias_id: 0,
30 }
31 }
32
33 pub fn stack_size(&self) -> usize {
35 self.value.borrow().ty().size_in_felts()
36 }
37
38 pub fn copy(mut self, id: NonZeroU8) -> Self {
44 self.alias_id = id.get();
45 self
46 }
47
48 pub fn unaliased(mut self) -> Self {
50 self.alias_id = 0;
51 self
52 }
53
54 pub fn set_alias(&mut self, id: NonZeroU8) {
60 self.alias_id = id.get();
61 }
62
63 pub fn value(self) -> ValueRef {
65 self.value
66 }
67
68 pub fn borrow_value(&self) -> EntityRef<'_, dyn Value> {
70 self.value.borrow()
71 }
72
73 pub fn alias(self) -> Option<NonZeroU8> {
75 NonZeroU8::new(self.alias_id)
76 }
77
78 pub fn unwrap_alias(self) -> NonZeroU8 {
80 NonZeroU8::new(self.alias_id).unwrap_or_else(|| panic!("expected {self:?} to be an alias"))
81 }
82
83 pub fn is_alias(&self) -> bool {
85 self.alias_id != 0
86 }
87}
88
89impl core::borrow::Borrow<ValueRef> for ValueOrAlias {
90 #[inline(always)]
91 fn borrow(&self) -> &ValueRef {
92 &self.value
93 }
94}
95
96impl core::borrow::Borrow<ValueRef> for &ValueOrAlias {
97 #[inline(always)]
98 fn borrow(&self) -> &ValueRef {
99 &self.value
100 }
101}
102
103impl core::borrow::Borrow<ValueRef> for &mut ValueOrAlias {
104 #[inline(always)]
105 fn borrow(&self) -> &ValueRef {
106 &self.value
107 }
108}
109
110impl Eq for ValueOrAlias {}
111
112impl PartialEq for ValueOrAlias {
113 fn eq(&self, other: &Self) -> bool {
114 self.value_id == other.value_id && self.alias_id == other.alias_id
115 }
116}
117
118impl core::hash::Hash for ValueOrAlias {
119 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
120 self.value_id.hash(state);
121 self.alias_id.hash(state);
122 }
123}
124
125impl Ord for ValueOrAlias {
126 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
127 self.value_id.cmp(&other.value_id).then(self.alias_id.cmp(&other.alias_id))
128 }
129}
130
131impl PartialEq<ValueRef> for ValueOrAlias {
132 fn eq(&self, other: &ValueRef) -> bool {
133 &self.value == other
134 }
135}
136
137impl PartialOrd for ValueOrAlias {
138 #[inline]
139 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
140 Some(self.cmp(other))
141 }
142}
143
144impl From<ValueRef> for ValueOrAlias {
145 #[inline]
146 fn from(value: ValueRef) -> Self {
147 Self::new(value)
148 }
149}
150
151impl From<ValueOrAlias> for ValueRef {
152 #[inline]
153 fn from(value: ValueOrAlias) -> Self {
154 value.value
155 }
156}
157
158impl fmt::Display for ValueOrAlias {
159 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
160 match self.alias() {
161 None => write!(f, "{}", &self.value_id),
162 Some(alias) => write!(f, "{}.{alias}", &self.value_id),
163 }
164 }
165}
166
167impl fmt::Debug for ValueOrAlias {
168 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
169 fmt::Display::fmt(self, f)
170 }
171}