Skip to main content

syn_sem/semantic/eval/
value.rs

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        // === Internal helper functions ===
363
364        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        // === Internal helper functions ===
419
420        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}