1use crate::{ds::vec::BoxedSlice, err, semantic::tree::NodeIndex, Result};
2use any_intern::Interned;
3use std::{fmt::Debug, iter};
4
5#[derive(Debug, Clone, PartialEq)]
6pub enum Value<'gcx> {
7 ConstGeneric(ConstGeneric),
8 Composed(Vec<Field<'gcx>>),
9 Enum(Enum),
10 Fn(Fn),
11 Ref(Box<Value<'gcx>>),
12 Scalar(Scalar),
13 Unit,
14}
15
16impl<'gcx> Value<'gcx> {
17 pub(crate) fn contains_const_generic(&self) -> bool {
18 match self {
19 Self::ConstGeneric(_) => true,
20 Self::Composed(fields) => fields
21 .iter()
22 .any(|field| field.value.contains_const_generic()),
23 Self::Ref(inner) => inner.contains_const_generic(),
24 Self::Enum(_) | Self::Fn(_) | Self::Scalar(_) | Self::Unit => false,
25 }
26 }
27
28 pub(crate) fn iter_const_generic(&self) -> Box<dyn Iterator<Item = &ConstGeneric> + '_> {
29 match self {
30 Self::ConstGeneric(g) => Box::new(iter::once(g)),
31 Self::Composed(fields) => {
32 let iter = fields
33 .iter()
34 .flat_map(|field| field.value.iter_const_generic());
35 Box::new(iter)
36 }
37 Self::Ref(inner) => inner.iter_const_generic(),
38 Self::Enum(_) | Self::Fn(_) | Self::Scalar(_) | Self::Unit => Box::new(iter::empty()),
39 }
40 }
41
42 pub(crate) fn try_add(&self, rhs: &Self) -> Result<Self> {
43 match (self, rhs) {
44 (Self::Scalar(l), Self::Scalar(r)) => Ok(Self::Scalar(l.try_add(*r)?)),
45 (Self::Ref(l), r) => l.try_add(r),
46 (l, Self::Ref(r)) => l.try_add(r),
47 _ => err!("cannot apply `+` to {self:?} and {rhs:?}"),
48 }
49 }
50
51 pub(crate) fn try_sub(&self, rhs: &Self) -> Result<Self> {
52 match (self, rhs) {
53 (Self::Scalar(l), Self::Scalar(r)) => Ok(Self::Scalar(l.try_sub(*r)?)),
54 (Self::Ref(l), r) => l.try_sub(r),
55 (l, Self::Ref(r)) => l.try_sub(r),
56 _ => err!("cannot apply `-` to {self:?} and {rhs:?}"),
57 }
58 }
59
60 pub(crate) fn try_mul(&self, rhs: &Self) -> Result<Self> {
61 match (self, rhs) {
62 (Self::Scalar(l), Self::Scalar(r)) => Ok(Self::Scalar(l.try_mul(*r)?)),
63 (Self::Ref(l), r) => l.try_mul(r),
64 (l, Self::Ref(r)) => l.try_mul(r),
65 _ => err!("cannot apply `*` to {self:?} and {rhs:?}"),
66 }
67 }
68
69 pub(crate) fn try_div(&self, rhs: &Self) -> Result<Self> {
70 match (self, rhs) {
71 (Self::Scalar(l), Self::Scalar(r)) => Ok(Self::Scalar(l.try_div(*r)?)),
72 (Self::Ref(l), r) => l.try_div(r),
73 (l, Self::Ref(r)) => l.try_div(r),
74 _ => err!("cannot apply `/` to {self:?} and {rhs:?}"),
75 }
76 }
77
78 pub(crate) fn try_rem(&self, rhs: &Self) -> Result<Self> {
79 match (self, rhs) {
80 (Self::Scalar(l), Self::Scalar(r)) => Ok(Self::Scalar(l.try_rem(*r)?)),
81 (Self::Ref(l), r) => l.try_rem(r),
82 (l, Self::Ref(r)) => l.try_rem(r),
83 _ => err!("cannot apply `%` to {self:?} and {rhs:?}"),
84 }
85 }
86
87 pub(crate) fn try_bit_xor(&self, rhs: &Self) -> Result<Self> {
88 match (self, rhs) {
89 (Self::Scalar(l), Self::Scalar(r)) => Ok(Self::Scalar(l.try_bit_xor(*r)?)),
90 (Self::Ref(l), r) => l.try_bit_xor(r),
91 (l, Self::Ref(r)) => l.try_bit_xor(r),
92 _ => err!("cannot apply `^` to {self:?} and {rhs:?}"),
93 }
94 }
95
96 pub(crate) fn try_bit_and(&self, rhs: &Self) -> Result<Self> {
97 match (self, rhs) {
98 (Self::Scalar(l), Self::Scalar(r)) => Ok(Self::Scalar(l.try_bit_and(*r)?)),
99 (Self::Ref(l), r) => l.try_bit_and(r),
100 (l, Self::Ref(r)) => l.try_bit_and(r),
101 _ => err!("cannot apply `&` to {self:?} and {rhs:?}"),
102 }
103 }
104
105 pub(crate) fn try_bit_or(&self, rhs: &Self) -> Result<Self> {
106 match (self, rhs) {
107 (Self::Scalar(l), Self::Scalar(r)) => Ok(Self::Scalar(l.try_bit_or(*r)?)),
108 (Self::Ref(l), r) => l.try_bit_or(r),
109 (l, Self::Ref(r)) => l.try_bit_or(r),
110 _ => err!("cannot apply `|` to {self:?} and {rhs:?}"),
111 }
112 }
113
114 pub(crate) fn try_shl(&self, rhs: &Self) -> Result<Self> {
115 match (self, rhs) {
116 (Self::Scalar(l), Self::Scalar(r)) => Ok(Self::Scalar(l.try_shl(*r)?)),
117 (Self::Ref(l), r) => l.try_shl(r),
118 (l, Self::Ref(r)) => l.try_shl(r),
119 _ => err!("cannot apply `<<` to {self:?} and {rhs:?}"),
120 }
121 }
122
123 pub(crate) fn try_shr(&self, rhs: &Self) -> Result<Self> {
124 match (self, rhs) {
125 (Self::Scalar(l), Self::Scalar(r)) => Ok(Self::Scalar(l.try_shr(*r)?)),
126 (Self::Ref(l), r) => l.try_shr(r),
127 (l, Self::Ref(r)) => l.try_shr(r),
128 _ => err!("cannot apply `>>` to {self:?} and {rhs:?}"),
129 }
130 }
131
132 pub(crate) fn try_not(&self) -> Result<Self> {
133 match self {
134 Self::Scalar(v) => Ok(Self::Scalar(v.try_not()?)),
135 Self::Ref(v) => v.try_not(),
136 _ => err!("cannot apply `!` to {self:?}"),
137 }
138 }
139
140 pub(crate) fn try_neg(&self) -> Result<Self> {
141 match self {
142 Self::Scalar(v) => Ok(Self::Scalar(v.try_neg()?)),
143 Self::Ref(v) => v.try_neg(),
144 _ => err!("cannot apply `-` to {self:?}"),
145 }
146 }
147}
148
149#[derive(Debug, Clone, PartialEq)]
150pub struct Field<'gcx> {
151 pub(crate) name: Interned<'gcx, str>,
152 pub(crate) value: Value<'gcx>,
153}
154
155#[derive(Debug, Clone, Copy, PartialEq)]
156pub enum Scalar {
157 Int(i32),
158 Float(f32),
159 I8(i8),
160 I16(i16),
161 I32(i32),
162 I64(i64),
163 I128(i128),
164 Isize(isize),
165 U8(u8),
166 U16(u16),
167 U32(u32),
168 U64(u64),
169 U128(u128),
170 Usize(usize),
171 F32(f32),
172 F64(f64),
173 Bool(bool),
174}
175
176impl Scalar {
177 pub(crate) fn try_add(self, rhs: Self) -> Result<Self> {
178 match (self, rhs) {
179 (Self::Int(l), Self::Int(r)) => Ok(Self::Int(l + r)),
180 (Self::Float(l), Self::Float(r)) => Ok(Self::Float(l + r)),
181 (Self::I8(l), Self::I8(r)) => Ok(Self::I8(l + r)),
182 (Self::I16(l), Self::I16(r)) => Ok(Self::I16(l + r)),
183 (Self::I32(l), Self::I32(r)) => Ok(Self::I32(l + r)),
184 (Self::I64(l), Self::I64(r)) => Ok(Self::I64(l + r)),
185 (Self::I128(l), Self::I128(r)) => Ok(Self::I128(l + r)),
186 (Self::Isize(l), Self::Isize(r)) => Ok(Self::Isize(l + r)),
187 (Self::U8(l), Self::U8(r)) => Ok(Self::U8(l + r)),
188 (Self::U16(l), Self::U16(r)) => Ok(Self::U16(l + r)),
189 (Self::U32(l), Self::U32(r)) => Ok(Self::U32(l + r)),
190 (Self::U64(l), Self::U64(r)) => Ok(Self::U64(l + r)),
191 (Self::U128(l), Self::U128(r)) => Ok(Self::U128(l + r)),
192 (Self::Usize(l), Self::Usize(r)) => Ok(Self::Usize(l + r)),
193 (Self::F32(l), Self::F32(r)) => Ok(Self::F32(l + r)),
194 (Self::F64(l), Self::F64(r)) => Ok(Self::F64(l + r)),
195 _ => err!("cannot apply `+` to {self:?} and {rhs:?}"),
196 }
197 }
198
199 pub(crate) fn try_sub(self, rhs: Self) -> Result<Self> {
200 match (self, rhs) {
201 (Self::Int(l), Self::Int(r)) => Ok(Self::Int(l - r)),
202 (Self::Float(l), Self::Float(r)) => Ok(Self::Float(l - r)),
203 (Self::I8(l), Self::I8(r)) => Ok(Self::I8(l - r)),
204 (Self::I16(l), Self::I16(r)) => Ok(Self::I16(l - r)),
205 (Self::I32(l), Self::I32(r)) => Ok(Self::I32(l - r)),
206 (Self::I64(l), Self::I64(r)) => Ok(Self::I64(l - r)),
207 (Self::I128(l), Self::I128(r)) => Ok(Self::I128(l - r)),
208 (Self::Isize(l), Self::Isize(r)) => Ok(Self::Isize(l - r)),
209 (Self::U8(l), Self::U8(r)) => Ok(Self::U8(l - r)),
210 (Self::U16(l), Self::U16(r)) => Ok(Self::U16(l - r)),
211 (Self::U32(l), Self::U32(r)) => Ok(Self::U32(l - r)),
212 (Self::U64(l), Self::U64(r)) => Ok(Self::U64(l - r)),
213 (Self::U128(l), Self::U128(r)) => Ok(Self::U128(l - r)),
214 (Self::Usize(l), Self::Usize(r)) => Ok(Self::Usize(l - r)),
215 (Self::F32(l), Self::F32(r)) => Ok(Self::F32(l - r)),
216 (Self::F64(l), Self::F64(r)) => Ok(Self::F64(l - r)),
217 _ => err!("cannot apply `-` to {self:?} and {rhs:?}"),
218 }
219 }
220
221 pub(crate) fn try_mul(self, rhs: Self) -> Result<Self> {
222 match (self, rhs) {
223 (Self::Int(l), Self::Int(r)) => Ok(Self::Int(l * r)),
224 (Self::Float(l), Self::Float(r)) => Ok(Self::Float(l * r)),
225 (Self::I8(l), Self::I8(r)) => Ok(Self::I8(l * r)),
226 (Self::I16(l), Self::I16(r)) => Ok(Self::I16(l * r)),
227 (Self::I32(l), Self::I32(r)) => Ok(Self::I32(l * r)),
228 (Self::I64(l), Self::I64(r)) => Ok(Self::I64(l * r)),
229 (Self::I128(l), Self::I128(r)) => Ok(Self::I128(l * r)),
230 (Self::Isize(l), Self::Isize(r)) => Ok(Self::Isize(l * r)),
231 (Self::U8(l), Self::U8(r)) => Ok(Self::U8(l * r)),
232 (Self::U16(l), Self::U16(r)) => Ok(Self::U16(l * r)),
233 (Self::U32(l), Self::U32(r)) => Ok(Self::U32(l * r)),
234 (Self::U64(l), Self::U64(r)) => Ok(Self::U64(l * r)),
235 (Self::U128(l), Self::U128(r)) => Ok(Self::U128(l * r)),
236 (Self::Usize(l), Self::Usize(r)) => Ok(Self::Usize(l * r)),
237 (Self::F32(l), Self::F32(r)) => Ok(Self::F32(l * r)),
238 (Self::F64(l), Self::F64(r)) => Ok(Self::F64(l * r)),
239 _ => err!("cannot apply `*` to {self:?} and {rhs:?}"),
240 }
241 }
242
243 pub(crate) fn try_div(self, rhs: Self) -> Result<Self> {
244 match (self, rhs) {
245 (Self::Int(l), Self::Int(r)) => Ok(Self::Int(l / r)),
246 (Self::Float(l), Self::Float(r)) => Ok(Self::Float(l / r)),
247 (Self::I8(l), Self::I8(r)) => Ok(Self::I8(l / r)),
248 (Self::I16(l), Self::I16(r)) => Ok(Self::I16(l / r)),
249 (Self::I32(l), Self::I32(r)) => Ok(Self::I32(l / r)),
250 (Self::I64(l), Self::I64(r)) => Ok(Self::I64(l / r)),
251 (Self::I128(l), Self::I128(r)) => Ok(Self::I128(l / r)),
252 (Self::Isize(l), Self::Isize(r)) => Ok(Self::Isize(l / r)),
253 (Self::U8(l), Self::U8(r)) => Ok(Self::U8(l / r)),
254 (Self::U16(l), Self::U16(r)) => Ok(Self::U16(l / r)),
255 (Self::U32(l), Self::U32(r)) => Ok(Self::U32(l / r)),
256 (Self::U64(l), Self::U64(r)) => Ok(Self::U64(l / r)),
257 (Self::U128(l), Self::U128(r)) => Ok(Self::U128(l / r)),
258 (Self::Usize(l), Self::Usize(r)) => Ok(Self::Usize(l / r)),
259 (Self::F32(l), Self::F32(r)) => Ok(Self::F32(l / r)),
260 (Self::F64(l), Self::F64(r)) => Ok(Self::F64(l / r)),
261 _ => err!("cannot apply `/` to {self:?} and {rhs:?}"),
262 }
263 }
264
265 pub(crate) fn try_rem(self, rhs: Self) -> Result<Self> {
266 match (self, rhs) {
267 (Self::Int(l), Self::Int(r)) => Ok(Self::Int(l % r)),
268 (Self::Float(l), Self::Float(r)) => Ok(Self::Float(l % r)),
269 (Self::I8(l), Self::I8(r)) => Ok(Self::I8(l % r)),
270 (Self::I16(l), Self::I16(r)) => Ok(Self::I16(l % r)),
271 (Self::I32(l), Self::I32(r)) => Ok(Self::I32(l % r)),
272 (Self::I64(l), Self::I64(r)) => Ok(Self::I64(l % r)),
273 (Self::I128(l), Self::I128(r)) => Ok(Self::I128(l % r)),
274 (Self::Isize(l), Self::Isize(r)) => Ok(Self::Isize(l % r)),
275 (Self::U8(l), Self::U8(r)) => Ok(Self::U8(l % r)),
276 (Self::U16(l), Self::U16(r)) => Ok(Self::U16(l % r)),
277 (Self::U32(l), Self::U32(r)) => Ok(Self::U32(l % r)),
278 (Self::U64(l), Self::U64(r)) => Ok(Self::U64(l % r)),
279 (Self::U128(l), Self::U128(r)) => Ok(Self::U128(l % r)),
280 (Self::Usize(l), Self::Usize(r)) => Ok(Self::Usize(l % r)),
281 (Self::F32(l), Self::F32(r)) => Ok(Self::F32(l % r)),
282 (Self::F64(l), Self::F64(r)) => Ok(Self::F64(l % r)),
283 _ => err!("cannot apply `%` to {self:?} and {rhs:?}"),
284 }
285 }
286
287 pub(crate) fn try_bit_xor(self, rhs: Self) -> Result<Self> {
288 match (self, rhs) {
289 (Self::Int(l), Self::Int(r)) => Ok(Self::Int(l ^ r)),
290 (Self::I8(l), Self::I8(r)) => Ok(Self::I8(l ^ r)),
291 (Self::I16(l), Self::I16(r)) => Ok(Self::I16(l ^ r)),
292 (Self::I32(l), Self::I32(r)) => Ok(Self::I32(l ^ r)),
293 (Self::I64(l), Self::I64(r)) => Ok(Self::I64(l ^ r)),
294 (Self::I128(l), Self::I128(r)) => Ok(Self::I128(l ^ r)),
295 (Self::Isize(l), Self::Isize(r)) => Ok(Self::Isize(l ^ r)),
296 (Self::U8(l), Self::U8(r)) => Ok(Self::U8(l ^ r)),
297 (Self::U16(l), Self::U16(r)) => Ok(Self::U16(l ^ r)),
298 (Self::U32(l), Self::U32(r)) => Ok(Self::U32(l ^ r)),
299 (Self::U64(l), Self::U64(r)) => Ok(Self::U64(l ^ r)),
300 (Self::U128(l), Self::U128(r)) => Ok(Self::U128(l ^ r)),
301 (Self::Usize(l), Self::Usize(r)) => Ok(Self::Usize(l ^ r)),
302 _ => err!("cannot apply `^` to {self:?} and {rhs:?}"),
303 }
304 }
305
306 pub(crate) fn try_bit_and(self, rhs: Self) -> Result<Self> {
307 match (self, rhs) {
308 (Self::Int(l), Self::Int(r)) => Ok(Self::Int(l & r)),
309 (Self::I8(l), Self::I8(r)) => Ok(Self::I8(l & r)),
310 (Self::I16(l), Self::I16(r)) => Ok(Self::I16(l & r)),
311 (Self::I32(l), Self::I32(r)) => Ok(Self::I32(l & r)),
312 (Self::I64(l), Self::I64(r)) => Ok(Self::I64(l & r)),
313 (Self::I128(l), Self::I128(r)) => Ok(Self::I128(l & r)),
314 (Self::Isize(l), Self::Isize(r)) => Ok(Self::Isize(l & r)),
315 (Self::U8(l), Self::U8(r)) => Ok(Self::U8(l & r)),
316 (Self::U16(l), Self::U16(r)) => Ok(Self::U16(l & r)),
317 (Self::U32(l), Self::U32(r)) => Ok(Self::U32(l & r)),
318 (Self::U64(l), Self::U64(r)) => Ok(Self::U64(l & r)),
319 (Self::U128(l), Self::U128(r)) => Ok(Self::U128(l & r)),
320 (Self::Usize(l), Self::Usize(r)) => Ok(Self::Usize(l & r)),
321 _ => err!("cannot apply `&` to {self:?} and {rhs:?}"),
322 }
323 }
324
325 pub(crate) fn try_bit_or(self, rhs: Self) -> Result<Self> {
326 match (self, rhs) {
327 (Self::Int(l), Self::Int(r)) => Ok(Self::Int(l | r)),
328 (Self::I8(l), Self::I8(r)) => Ok(Self::I8(l | r)),
329 (Self::I16(l), Self::I16(r)) => Ok(Self::I16(l | r)),
330 (Self::I32(l), Self::I32(r)) => Ok(Self::I32(l | r)),
331 (Self::I64(l), Self::I64(r)) => Ok(Self::I64(l | r)),
332 (Self::I128(l), Self::I128(r)) => Ok(Self::I128(l | r)),
333 (Self::Isize(l), Self::Isize(r)) => Ok(Self::Isize(l | r)),
334 (Self::U8(l), Self::U8(r)) => Ok(Self::U8(l | r)),
335 (Self::U16(l), Self::U16(r)) => Ok(Self::U16(l | r)),
336 (Self::U32(l), Self::U32(r)) => Ok(Self::U32(l | r)),
337 (Self::U64(l), Self::U64(r)) => Ok(Self::U64(l | r)),
338 (Self::U128(l), Self::U128(r)) => Ok(Self::U128(l | r)),
339 (Self::Usize(l), Self::Usize(r)) => Ok(Self::Usize(l | r)),
340 _ => err!("cannot apply `|` to {self:?} and {rhs:?}"),
341 }
342 }
343
344 pub(crate) fn try_shl(self, rhs: Self) -> Result<Self> {
345 return match self {
346 Self::Int(l) => Ok(Self::Int(helper(l, rhs)?)),
347 Self::I8(l) => Ok(Self::I8(helper(l, rhs)?)),
348 Self::I16(l) => Ok(Self::I16(helper(l, rhs)?)),
349 Self::I32(l) => Ok(Self::I32(helper(l, rhs)?)),
350 Self::I64(l) => Ok(Self::I64(helper(l, rhs)?)),
351 Self::I128(l) => Ok(Self::I128(helper(l, rhs)?)),
352 Self::Isize(l) => Ok(Self::Isize(helper(l, rhs)?)),
353 Self::U8(l) => Ok(Self::U8(helper(l, rhs)?)),
354 Self::U16(l) => Ok(Self::U16(helper(l, rhs)?)),
355 Self::U32(l) => Ok(Self::U32(helper(l, rhs)?)),
356 Self::U64(l) => Ok(Self::U64(helper(l, rhs)?)),
357 Self::U128(l) => Ok(Self::U128(helper(l, rhs)?)),
358 Self::Usize(l) => Ok(Self::Usize(helper(l, rhs)?)),
359 _ => err!("cannot apply `<<` to {self:?} and {rhs:?}"),
360 };
361
362 use std::ops::Shl;
365 fn helper<L>(l: L, rhs: Scalar) -> Result<L>
366 where
367 L: Shl<i8, Output = L>
368 + Shl<i16, Output = L>
369 + Shl<i32, Output = L>
370 + Shl<i64, Output = L>
371 + Shl<i128, Output = L>
372 + Shl<isize, Output = L>
373 + Shl<u8, Output = L>
374 + Shl<u16, Output = L>
375 + Shl<u32, Output = L>
376 + Shl<u64, Output = L>
377 + Shl<u128, Output = L>
378 + Shl<usize, Output = L>
379 + Debug,
380 {
381 match rhs {
382 Scalar::Int(r) => Ok(l << r),
383 Scalar::I8(r) => Ok(l << r),
384 Scalar::I16(r) => Ok(l << r),
385 Scalar::I32(r) => Ok(l << r),
386 Scalar::I64(r) => Ok(l << r),
387 Scalar::I128(r) => Ok(l << r),
388 Scalar::Isize(r) => Ok(l << r),
389 Scalar::U8(r) => Ok(l << r),
390 Scalar::U16(r) => Ok(l << r),
391 Scalar::U32(r) => Ok(l << r),
392 Scalar::U64(r) => Ok(l << r),
393 Scalar::U128(r) => Ok(l << r),
394 Scalar::Usize(r) => Ok(l << r),
395 _ => err!("cannot apply `<<` to {l:?} and {rhs:?}"),
396 }
397 }
398 }
399
400 pub(crate) fn try_shr(self, rhs: Self) -> Result<Self> {
401 return match self {
402 Self::Int(l) => Ok(Self::Int(helper(l, rhs)?)),
403 Self::I8(l) => Ok(Self::I8(helper(l, rhs)?)),
404 Self::I16(l) => Ok(Self::I16(helper(l, rhs)?)),
405 Self::I32(l) => Ok(Self::I32(helper(l, rhs)?)),
406 Self::I64(l) => Ok(Self::I64(helper(l, rhs)?)),
407 Self::I128(l) => Ok(Self::I128(helper(l, rhs)?)),
408 Self::Isize(l) => Ok(Self::Isize(helper(l, rhs)?)),
409 Self::U8(l) => Ok(Self::U8(helper(l, rhs)?)),
410 Self::U16(l) => Ok(Self::U16(helper(l, rhs)?)),
411 Self::U32(l) => Ok(Self::U32(helper(l, rhs)?)),
412 Self::U64(l) => Ok(Self::U64(helper(l, rhs)?)),
413 Self::U128(l) => Ok(Self::U128(helper(l, rhs)?)),
414 Self::Usize(l) => Ok(Self::Usize(helper(l, rhs)?)),
415 _ => err!("cannot apply `>>` to {self:?} and {rhs:?}"),
416 };
417
418 use std::ops::Shr;
421 fn helper<L>(l: L, rhs: Scalar) -> Result<L>
422 where
423 L: Shr<i8, Output = L>
424 + Shr<i16, Output = L>
425 + Shr<i32, Output = L>
426 + Shr<i64, Output = L>
427 + Shr<i128, Output = L>
428 + Shr<isize, Output = L>
429 + Shr<u8, Output = L>
430 + Shr<u16, Output = L>
431 + Shr<u32, Output = L>
432 + Shr<u64, Output = L>
433 + Shr<u128, Output = L>
434 + Shr<usize, Output = L>
435 + Debug,
436 {
437 match rhs {
438 Scalar::Int(r) => Ok(l >> r),
439 Scalar::I8(r) => Ok(l >> r),
440 Scalar::I16(r) => Ok(l >> r),
441 Scalar::I32(r) => Ok(l >> r),
442 Scalar::I64(r) => Ok(l >> r),
443 Scalar::I128(r) => Ok(l >> r),
444 Scalar::Isize(r) => Ok(l >> r),
445 Scalar::U8(r) => Ok(l >> r),
446 Scalar::U16(r) => Ok(l >> r),
447 Scalar::U32(r) => Ok(l >> r),
448 Scalar::U64(r) => Ok(l >> r),
449 Scalar::U128(r) => Ok(l >> r),
450 Scalar::Usize(r) => Ok(l >> r),
451 _ => err!("cannot apply `>>` to {l:?} and {rhs:?}"),
452 }
453 }
454 }
455
456 pub(crate) fn try_not(self) -> Result<Self> {
457 if let Self::Bool(v) = self {
458 Ok(Self::Bool(!v))
459 } else {
460 err!("cannot apply `!` to {self:?}")
461 }
462 }
463
464 pub(crate) fn try_neg(self) -> Result<Self> {
465 match self {
466 Self::Int(v) => Ok(Self::Int(-v)),
467 Self::Float(v) => Ok(Self::Float(-v)),
468 Self::I8(v) => Ok(Self::I8(-v)),
469 Self::I16(v) => Ok(Self::I16(-v)),
470 Self::I32(v) => Ok(Self::I32(-v)),
471 Self::I64(v) => Ok(Self::I64(-v)),
472 Self::I128(v) => Ok(Self::I128(-v)),
473 Self::Isize(v) => Ok(Self::Isize(-v)),
474 Self::F32(v) => Ok(Self::F32(-v)),
475 Self::F64(v) => Ok(Self::F64(-v)),
476 _ => err!("cannot apply `-` to {self:?}"),
477 }
478 }
479}
480
481#[derive(Debug, Clone, PartialEq, Eq)]
482pub struct ConstGeneric {
483 pub expr: *const syn::Expr,
484 pub base: NodeIndex,
485}
486
487#[derive(Debug, Clone, PartialEq, Eq)]
488pub struct Enum {
489 pub path: String,
490 pub disc: isize,
491}
492
493#[derive(Debug, Clone, PartialEq, Eq)]
494pub struct Fn {
495 pub inputs: FnInputs,
496 pub output: *const syn::ReturnType,
497 pub body: FnBody,
498}
499
500impl Fn {
501 pub(crate) fn from_signature_and_block(sig: &syn::Signature, block: &syn::Block) -> Self {
502 let inputs = sig
503 .inputs
504 .iter()
505 .map(|input| input as *const syn::FnArg)
506 .collect();
507 let inputs = FnInputs::Params(inputs);
508 let output = &sig.output as *const _;
509 let body = FnBody::Block(block as *const _);
510 Self {
511 inputs,
512 output,
513 body,
514 }
515 }
516}
517
518#[derive(Debug, Clone, PartialEq, Eq)]
519pub enum FnInputs {
520 Params(BoxedSlice<*const syn::FnArg>),
521}
522
523#[derive(Debug, Clone, PartialEq, Eq)]
524pub enum FnBody {
525 Block(*const syn::Block),
526}