Skip to main content

inkwell/types/
enums.rs

1use llvm_sys::LLVMTypeKind;
2use llvm_sys::core::LLVMGetTypeKind;
3use llvm_sys::prelude::LLVMTypeRef;
4
5use crate::support::LLVMString;
6use crate::types::MetadataType;
7use crate::types::traits::AsTypeRef;
8use crate::types::{
9    ArrayType, FloatType, FunctionType, IntType, PointerType, ScalableVectorType, StructType, VectorType, VoidType,
10};
11use crate::values::{BasicValue, BasicValueEnum, IntValue};
12
13use std::convert::TryFrom;
14use std::fmt::{self, Display};
15
16macro_rules! enum_type_set {
17    ($(#[$enum_attrs:meta])* $enum_name:ident: { $($(#[$variant_attrs:meta])* $args:ident,)+ }) => (
18        #[derive(Debug, PartialEq, Eq, Clone, Copy)]
19        $(#[$enum_attrs])*
20        pub enum $enum_name<'ctx> {
21            $(
22                $(#[$variant_attrs])*
23                $args($args<'ctx>),
24            )*
25        }
26
27        unsafe impl AsTypeRef for $enum_name<'_> {
28            fn as_type_ref(&self) -> LLVMTypeRef {
29                match *self {
30                    $(
31                        $enum_name::$args(ref t) => t.as_type_ref(),
32                    )*
33                }
34            }
35        }
36
37        $(
38            impl<'ctx> From<$args<'ctx>> for $enum_name<'ctx> {
39                fn from(value: $args) -> $enum_name {
40                    $enum_name::$args(value)
41                }
42            }
43
44            impl<'ctx> TryFrom<$enum_name<'ctx>> for $args<'ctx> {
45                type Error = ();
46
47                fn try_from(value: $enum_name<'ctx>) -> Result<Self, Self::Error> {
48                    match value {
49                        $enum_name::$args(ty) => Ok(ty),
50                        _ => Err(()),
51                    }
52                }
53            }
54        )*
55    );
56}
57
58enum_type_set! {
59    /// A wrapper for any `BasicType`, `VoidType`, or `FunctionType`.
60    AnyTypeEnum: {
61        /// A contiguous homogeneous container type.
62        ArrayType,
63        /// A floating point type.
64        FloatType,
65        /// A function return and parameter definition.
66        FunctionType,
67        /// An integer type.
68        IntType,
69        /// A pointer type.
70        PointerType,
71        /// A contiguous heterogeneous container type.
72        StructType,
73        /// A contiguous homogeneous "SIMD" container type.
74        VectorType,
75        /// A contiguous homogeneous scalable "SIMD" container type.
76        ScalableVectorType,
77        /// A valueless type.
78        VoidType,
79    }
80}
81enum_type_set! {
82    /// A wrapper for any `BasicType`.
83    BasicTypeEnum: {
84        /// A contiguous homogeneous container type.
85        ArrayType,
86        /// A floating point type.
87        FloatType,
88        /// An integer type.
89        IntType,
90        /// A pointer type.
91        PointerType,
92        /// A contiguous heterogeneous container type.
93        StructType,
94        /// A contiguous homogeneous "SIMD" container type.
95        VectorType,
96        /// A contiguous homogeneous scalable "SIMD" container type.
97        ScalableVectorType,
98    }
99}
100enum_type_set! {
101    BasicMetadataTypeEnum: {
102        ArrayType,
103        FloatType,
104        IntType,
105        PointerType,
106        StructType,
107        VectorType,
108        ScalableVectorType,
109        MetadataType,
110    }
111}
112
113impl<'ctx> BasicMetadataTypeEnum<'ctx> {
114    /// Create [`BasicMetadataTypeEnum`] from [`LLVMTypeRef`].
115    ///
116    /// # Safety
117    ///
118    /// Undefined behavior if the referenced type cannot be represented as [`BasicMetadataTypeEnum`],
119    /// or the underlying pointer is null.
120    pub unsafe fn new(type_: LLVMTypeRef) -> Self {
121        unsafe {
122            match LLVMGetTypeKind(type_) {
123                LLVMTypeKind::LLVMMetadataTypeKind => Self::MetadataType(MetadataType::new(type_)),
124                _ => BasicTypeEnum::new(type_).into(),
125            }
126        }
127    }
128
129    pub fn into_array_type(self) -> ArrayType<'ctx> {
130        if let BasicMetadataTypeEnum::ArrayType(t) = self {
131            t
132        } else {
133            panic!("Found {self:?} but expected another variant");
134        }
135    }
136
137    pub fn into_float_type(self) -> FloatType<'ctx> {
138        if let BasicMetadataTypeEnum::FloatType(t) = self {
139            t
140        } else {
141            panic!("Found {self:?} but expected another variant");
142        }
143    }
144
145    pub fn into_int_type(self) -> IntType<'ctx> {
146        if let BasicMetadataTypeEnum::IntType(t) = self {
147            t
148        } else {
149            panic!("Found {self:?} but expected another variant");
150        }
151    }
152
153    pub fn into_pointer_type(self) -> PointerType<'ctx> {
154        if let BasicMetadataTypeEnum::PointerType(t) = self {
155            t
156        } else {
157            panic!("Found {self:?} but expected another variant");
158        }
159    }
160
161    pub fn into_struct_type(self) -> StructType<'ctx> {
162        if let BasicMetadataTypeEnum::StructType(t) = self {
163            t
164        } else {
165            panic!("Found {self:?} but expected another variant");
166        }
167    }
168
169    pub fn into_vector_type(self) -> VectorType<'ctx> {
170        if let BasicMetadataTypeEnum::VectorType(t) = self {
171            t
172        } else {
173            panic!("Found {self:?} but expected another variant");
174        }
175    }
176
177    pub fn into_scalable_vector_type(self) -> ScalableVectorType<'ctx> {
178        if let BasicMetadataTypeEnum::ScalableVectorType(t) = self {
179            t
180        } else {
181            panic!("Found {self:?} but expected another variant");
182        }
183    }
184
185    pub fn into_metadata_type(self) -> MetadataType<'ctx> {
186        if let BasicMetadataTypeEnum::MetadataType(t) = self {
187            t
188        } else {
189            panic!("Found {self:?} but expected another variant");
190        }
191    }
192
193    pub fn is_array_type(self) -> bool {
194        matches!(self, BasicMetadataTypeEnum::ArrayType(_))
195    }
196
197    pub fn is_float_type(self) -> bool {
198        matches!(self, BasicMetadataTypeEnum::FloatType(_))
199    }
200
201    pub fn is_int_type(self) -> bool {
202        matches!(self, BasicMetadataTypeEnum::IntType(_))
203    }
204
205    pub fn is_metadata_type(self) -> bool {
206        matches!(self, BasicMetadataTypeEnum::MetadataType(_))
207    }
208
209    pub fn is_pointer_type(self) -> bool {
210        matches!(self, BasicMetadataTypeEnum::PointerType(_))
211    }
212
213    pub fn is_struct_type(self) -> bool {
214        matches!(self, BasicMetadataTypeEnum::StructType(_))
215    }
216
217    pub fn is_vector_type(self) -> bool {
218        matches!(self, BasicMetadataTypeEnum::VectorType(_))
219    }
220
221    pub fn is_scalable_vector_type(self) -> bool {
222        matches!(self, BasicMetadataTypeEnum::ScalableVectorType(_))
223    }
224
225    /// Print the definition of a `BasicMetadataTypeEnum` to `LLVMString`.
226    pub fn print_to_string(self) -> LLVMString {
227        match self {
228            BasicMetadataTypeEnum::ArrayType(t) => t.print_to_string(),
229            BasicMetadataTypeEnum::IntType(t) => t.print_to_string(),
230            BasicMetadataTypeEnum::FloatType(t) => t.print_to_string(),
231            BasicMetadataTypeEnum::PointerType(t) => t.print_to_string(),
232            BasicMetadataTypeEnum::StructType(t) => t.print_to_string(),
233            BasicMetadataTypeEnum::VectorType(t) => t.print_to_string(),
234            BasicMetadataTypeEnum::ScalableVectorType(t) => t.print_to_string(),
235            BasicMetadataTypeEnum::MetadataType(t) => t.print_to_string(),
236        }
237    }
238}
239
240impl<'ctx> AnyTypeEnum<'ctx> {
241    /// Create `AnyTypeEnum` from [`LLVMTypeRef`]
242    ///
243    /// # Safety
244    /// Undefined behavior, if referenced type isn't part of `AnyTypeEnum`
245    pub unsafe fn new(type_: LLVMTypeRef) -> Self {
246        unsafe {
247            match LLVMGetTypeKind(type_) {
248                LLVMTypeKind::LLVMVoidTypeKind => AnyTypeEnum::VoidType(VoidType::new(type_)),
249                LLVMTypeKind::LLVMHalfTypeKind
250                | LLVMTypeKind::LLVMFloatTypeKind
251                | LLVMTypeKind::LLVMDoubleTypeKind
252                | LLVMTypeKind::LLVMX86_FP80TypeKind
253                | LLVMTypeKind::LLVMFP128TypeKind
254                | LLVMTypeKind::LLVMPPC_FP128TypeKind => AnyTypeEnum::FloatType(FloatType::new(type_)),
255                LLVMTypeKind::LLVMBFloatTypeKind => AnyTypeEnum::FloatType(FloatType::new(type_)),
256                LLVMTypeKind::LLVMLabelTypeKind => panic!("FIXME: Unsupported type: Label"),
257                LLVMTypeKind::LLVMIntegerTypeKind => AnyTypeEnum::IntType(IntType::new(type_)),
258                LLVMTypeKind::LLVMFunctionTypeKind => AnyTypeEnum::FunctionType(FunctionType::new(type_)),
259                LLVMTypeKind::LLVMStructTypeKind => AnyTypeEnum::StructType(StructType::new(type_)),
260                LLVMTypeKind::LLVMArrayTypeKind => AnyTypeEnum::ArrayType(ArrayType::new(type_)),
261                LLVMTypeKind::LLVMPointerTypeKind => AnyTypeEnum::PointerType(PointerType::new(type_)),
262                LLVMTypeKind::LLVMVectorTypeKind => AnyTypeEnum::VectorType(VectorType::new(type_)),
263                LLVMTypeKind::LLVMScalableVectorTypeKind => {
264                    AnyTypeEnum::ScalableVectorType(ScalableVectorType::new(type_))
265                },
266                // FIXME: should inkwell support metadata as AnyType?
267                LLVMTypeKind::LLVMMetadataTypeKind => panic!("Metadata type is not supported as AnyType."),
268
269                #[cfg(not(any(feature = "llvm20-1", feature = "llvm21-1", feature = "llvm22-1")))]
270                LLVMTypeKind::LLVMX86_MMXTypeKind => panic!("FIXME: Unsupported type: MMX"),
271                LLVMTypeKind::LLVMX86_AMXTypeKind => panic!("FIXME: Unsupported type: AMX"),
272                LLVMTypeKind::LLVMTokenTypeKind => panic!("FIXME: Unsupported type: Token"),
273                #[cfg(any(
274                    feature = "llvm16-0",
275                    feature = "llvm17-0",
276                    feature = "llvm18-1",
277                    feature = "llvm19-1",
278                    feature = "llvm20-1",
279                    feature = "llvm21-1",
280                    feature = "llvm22-1",
281                ))]
282                LLVMTypeKind::LLVMTargetExtTypeKind => panic!("FIXME: Unsupported type: TargetExt"),
283            }
284        }
285    }
286
287    /// This will panic if type is a void or function type.
288    pub(crate) fn as_basic_type_enum(&self) -> BasicTypeEnum<'ctx> {
289        unsafe { BasicTypeEnum::new(self.as_type_ref()) }
290    }
291
292    pub fn into_array_type(self) -> ArrayType<'ctx> {
293        if let AnyTypeEnum::ArrayType(t) = self {
294            t
295        } else {
296            panic!("Found {self:?} but expected the ArrayType variant");
297        }
298    }
299
300    pub fn into_float_type(self) -> FloatType<'ctx> {
301        if let AnyTypeEnum::FloatType(t) = self {
302            t
303        } else {
304            panic!("Found {self:?} but expected the FloatType variant");
305        }
306    }
307
308    pub fn into_function_type(self) -> FunctionType<'ctx> {
309        if let AnyTypeEnum::FunctionType(t) = self {
310            t
311        } else {
312            panic!("Found {self:?} but expected the FunctionType variant");
313        }
314    }
315
316    pub fn into_int_type(self) -> IntType<'ctx> {
317        if let AnyTypeEnum::IntType(t) = self {
318            t
319        } else {
320            panic!("Found {self:?} but expected the IntType variant");
321        }
322    }
323
324    pub fn into_pointer_type(self) -> PointerType<'ctx> {
325        if let AnyTypeEnum::PointerType(t) = self {
326            t
327        } else {
328            panic!("Found {self:?} but expected the PointerType variant");
329        }
330    }
331
332    pub fn into_struct_type(self) -> StructType<'ctx> {
333        if let AnyTypeEnum::StructType(t) = self {
334            t
335        } else {
336            panic!("Found {self:?} but expected the StructType variant");
337        }
338    }
339
340    pub fn into_vector_type(self) -> VectorType<'ctx> {
341        if let AnyTypeEnum::VectorType(t) = self {
342            t
343        } else {
344            panic!("Found {self:?} but expected the VectorType variant");
345        }
346    }
347
348    pub fn into_scalable_vector_type(self) -> ScalableVectorType<'ctx> {
349        if let AnyTypeEnum::ScalableVectorType(t) = self {
350            t
351        } else {
352            panic!("Found {self:?} but expected the ScalableVectorType variant");
353        }
354    }
355
356    pub fn into_void_type(self) -> VoidType<'ctx> {
357        if let AnyTypeEnum::VoidType(t) = self {
358            t
359        } else {
360            panic!("Found {self:?} but expected the VoidType variant");
361        }
362    }
363
364    pub fn is_array_type(self) -> bool {
365        matches!(self, AnyTypeEnum::ArrayType(_))
366    }
367
368    pub fn is_float_type(self) -> bool {
369        matches!(self, AnyTypeEnum::FloatType(_))
370    }
371
372    pub fn is_function_type(self) -> bool {
373        matches!(self, AnyTypeEnum::FunctionType(_))
374    }
375
376    pub fn is_int_type(self) -> bool {
377        matches!(self, AnyTypeEnum::IntType(_))
378    }
379
380    pub fn is_pointer_type(self) -> bool {
381        matches!(self, AnyTypeEnum::PointerType(_))
382    }
383
384    pub fn is_struct_type(self) -> bool {
385        matches!(self, AnyTypeEnum::StructType(_))
386    }
387
388    pub fn is_vector_type(self) -> bool {
389        matches!(self, AnyTypeEnum::VectorType(_))
390    }
391
392    pub fn is_void_type(self) -> bool {
393        matches!(self, AnyTypeEnum::VoidType(_))
394    }
395
396    pub fn size_of(&self) -> Option<IntValue<'ctx>> {
397        match self {
398            AnyTypeEnum::ArrayType(t) => t.size_of(),
399            AnyTypeEnum::FloatType(t) => Some(t.size_of()),
400            AnyTypeEnum::IntType(t) => Some(t.size_of()),
401            AnyTypeEnum::PointerType(t) => Some(t.size_of()),
402            AnyTypeEnum::StructType(t) => t.size_of(),
403            AnyTypeEnum::VectorType(t) => t.size_of(),
404            AnyTypeEnum::ScalableVectorType(t) => t.size_of(),
405            AnyTypeEnum::VoidType(_) => None,
406            AnyTypeEnum::FunctionType(_) => None,
407        }
408    }
409
410    /// Print the definition of a `AnyTypeEnum` to `LLVMString`.
411    pub fn print_to_string(self) -> LLVMString {
412        match self {
413            AnyTypeEnum::ArrayType(t) => t.print_to_string(),
414            AnyTypeEnum::FloatType(t) => t.print_to_string(),
415            AnyTypeEnum::IntType(t) => t.print_to_string(),
416            AnyTypeEnum::PointerType(t) => t.print_to_string(),
417            AnyTypeEnum::StructType(t) => t.print_to_string(),
418            AnyTypeEnum::VectorType(t) => t.print_to_string(),
419            AnyTypeEnum::ScalableVectorType(t) => t.print_to_string(),
420            AnyTypeEnum::VoidType(t) => t.print_to_string(),
421            AnyTypeEnum::FunctionType(t) => t.print_to_string(),
422        }
423    }
424}
425
426impl<'ctx> BasicTypeEnum<'ctx> {
427    /// Create `BasicTypeEnum` from [`LLVMTypeRef`]
428    ///
429    /// # Safety
430    /// Undefined behavior, if referenced type isn't part of basic type enum.
431    pub unsafe fn new(type_: LLVMTypeRef) -> Self {
432        unsafe {
433            match LLVMGetTypeKind(type_) {
434                LLVMTypeKind::LLVMHalfTypeKind
435                | LLVMTypeKind::LLVMFloatTypeKind
436                | LLVMTypeKind::LLVMDoubleTypeKind
437                | LLVMTypeKind::LLVMX86_FP80TypeKind
438                | LLVMTypeKind::LLVMFP128TypeKind
439                | LLVMTypeKind::LLVMPPC_FP128TypeKind => BasicTypeEnum::FloatType(FloatType::new(type_)),
440                LLVMTypeKind::LLVMBFloatTypeKind => BasicTypeEnum::FloatType(FloatType::new(type_)),
441                LLVMTypeKind::LLVMIntegerTypeKind => BasicTypeEnum::IntType(IntType::new(type_)),
442                LLVMTypeKind::LLVMStructTypeKind => BasicTypeEnum::StructType(StructType::new(type_)),
443                LLVMTypeKind::LLVMPointerTypeKind => BasicTypeEnum::PointerType(PointerType::new(type_)),
444                LLVMTypeKind::LLVMArrayTypeKind => BasicTypeEnum::ArrayType(ArrayType::new(type_)),
445                LLVMTypeKind::LLVMVectorTypeKind => BasicTypeEnum::VectorType(VectorType::new(type_)),
446                LLVMTypeKind::LLVMScalableVectorTypeKind => {
447                    BasicTypeEnum::ScalableVectorType(ScalableVectorType::new(type_))
448                },
449                LLVMTypeKind::LLVMMetadataTypeKind => panic!("Unsupported basic type: Metadata"),
450                // see https://llvm.org/docs/LangRef.html#x86-mmx-type
451                #[cfg(not(any(feature = "llvm20-1", feature = "llvm21-1", feature = "llvm22-1")))]
452                LLVMTypeKind::LLVMX86_MMXTypeKind => panic!("Unsupported basic type: MMX"),
453                // see https://llvm.org/docs/LangRef.html#x86-amx-type
454                LLVMTypeKind::LLVMX86_AMXTypeKind => unreachable!("Unsupported basic type: AMX"),
455                LLVMTypeKind::LLVMLabelTypeKind => unreachable!("Unsupported basic type: Label"),
456                LLVMTypeKind::LLVMVoidTypeKind => unreachable!("Unsupported basic type: VoidType"),
457                LLVMTypeKind::LLVMFunctionTypeKind => unreachable!("Unsupported basic type: FunctionType"),
458                LLVMTypeKind::LLVMTokenTypeKind => unreachable!("Unsupported basic type: Token"),
459                #[cfg(any(
460                    feature = "llvm16-0",
461                    feature = "llvm17-0",
462                    feature = "llvm18-1",
463                    feature = "llvm19-1",
464                    feature = "llvm20-1",
465                    feature = "llvm21-1",
466                    feature = "llvm22-1",
467                ))]
468                LLVMTypeKind::LLVMTargetExtTypeKind => unreachable!("Unsupported basic type: TargetExt"),
469            }
470        }
471    }
472
473    pub fn into_array_type(self) -> ArrayType<'ctx> {
474        if let BasicTypeEnum::ArrayType(t) = self {
475            t
476        } else {
477            panic!("Found {self:?} but expected the ArrayType variant");
478        }
479    }
480
481    pub fn into_float_type(self) -> FloatType<'ctx> {
482        if let BasicTypeEnum::FloatType(t) = self {
483            t
484        } else {
485            panic!("Found {self:?} but expected the FloatType variant");
486        }
487    }
488
489    pub fn into_int_type(self) -> IntType<'ctx> {
490        if let BasicTypeEnum::IntType(t) = self {
491            t
492        } else {
493            panic!("Found {self:?} but expected the IntType variant");
494        }
495    }
496
497    pub fn into_pointer_type(self) -> PointerType<'ctx> {
498        if let BasicTypeEnum::PointerType(t) = self {
499            t
500        } else {
501            panic!("Found {self:?} but expected the PointerType variant");
502        }
503    }
504
505    pub fn into_struct_type(self) -> StructType<'ctx> {
506        if let BasicTypeEnum::StructType(t) = self {
507            t
508        } else {
509            panic!("Found {self:?} but expected the StructType variant");
510        }
511    }
512
513    pub fn into_vector_type(self) -> VectorType<'ctx> {
514        if let BasicTypeEnum::VectorType(t) = self {
515            t
516        } else {
517            panic!("Found {self:?} but expected the VectorType variant");
518        }
519    }
520
521    pub fn into_scalable_vector_type(self) -> ScalableVectorType<'ctx> {
522        if let BasicTypeEnum::ScalableVectorType(t) = self {
523            t
524        } else {
525            panic!("Found {self:?} but expected the ScalableVectorType variant");
526        }
527    }
528
529    pub fn is_array_type(self) -> bool {
530        matches!(self, BasicTypeEnum::ArrayType(_))
531    }
532
533    pub fn is_float_type(self) -> bool {
534        matches!(self, BasicTypeEnum::FloatType(_))
535    }
536
537    pub fn is_int_type(self) -> bool {
538        matches!(self, BasicTypeEnum::IntType(_))
539    }
540
541    pub fn is_pointer_type(self) -> bool {
542        matches!(self, BasicTypeEnum::PointerType(_))
543    }
544
545    pub fn is_struct_type(self) -> bool {
546        matches!(self, BasicTypeEnum::StructType(_))
547    }
548
549    pub fn is_vector_type(self) -> bool {
550        matches!(self, BasicTypeEnum::VectorType(_))
551    }
552
553    pub fn is_scalable_vector_type(self) -> bool {
554        matches!(self, BasicTypeEnum::ScalableVectorType(_))
555    }
556
557    /// Creates a constant `BasicValueZero`.
558    ///
559    /// # Example
560    /// ```
561    /// use inkwell::context::Context;
562    /// use crate::inkwell::types::BasicType;
563    ///
564    /// let context = Context::create();
565    /// let f32_type = context.f32_type().as_basic_type_enum();
566    /// let f32_zero = f32_type.const_zero();
567    /// ```
568    pub fn const_zero(self) -> BasicValueEnum<'ctx> {
569        match self {
570            BasicTypeEnum::ArrayType(ty) => ty.const_zero().as_basic_value_enum(),
571            BasicTypeEnum::FloatType(ty) => ty.const_zero().as_basic_value_enum(),
572            BasicTypeEnum::IntType(ty) => ty.const_zero().as_basic_value_enum(),
573            BasicTypeEnum::PointerType(ty) => ty.const_zero().as_basic_value_enum(),
574            BasicTypeEnum::StructType(ty) => ty.const_zero().as_basic_value_enum(),
575            BasicTypeEnum::VectorType(ty) => ty.const_zero().as_basic_value_enum(),
576            BasicTypeEnum::ScalableVectorType(ty) => ty.const_zero().as_basic_value_enum(),
577        }
578    }
579
580    /// Print the definition of a `BasicTypeEnum` to `LLVMString`.
581    pub fn print_to_string(self) -> LLVMString {
582        match self {
583            BasicTypeEnum::ArrayType(t) => t.print_to_string(),
584            BasicTypeEnum::FloatType(t) => t.print_to_string(),
585            BasicTypeEnum::IntType(t) => t.print_to_string(),
586            BasicTypeEnum::PointerType(t) => t.print_to_string(),
587            BasicTypeEnum::StructType(t) => t.print_to_string(),
588            BasicTypeEnum::VectorType(t) => t.print_to_string(),
589            BasicTypeEnum::ScalableVectorType(t) => t.print_to_string(),
590        }
591    }
592}
593
594impl<'ctx> TryFrom<AnyTypeEnum<'ctx>> for BasicTypeEnum<'ctx> {
595    type Error = ();
596
597    fn try_from(value: AnyTypeEnum<'ctx>) -> Result<Self, Self::Error> {
598        use AnyTypeEnum::*;
599        Ok(match value {
600            ArrayType(at) => at.into(),
601            FloatType(ft) => ft.into(),
602            IntType(it) => it.into(),
603            PointerType(pt) => pt.into(),
604            StructType(st) => st.into(),
605            VectorType(vt) => vt.into(),
606            ScalableVectorType(vt) => vt.into(),
607            VoidType(_) | FunctionType(_) => return Err(()),
608        })
609    }
610}
611
612impl<'ctx> TryFrom<AnyTypeEnum<'ctx>> for BasicMetadataTypeEnum<'ctx> {
613    type Error = ();
614
615    fn try_from(value: AnyTypeEnum<'ctx>) -> Result<Self, Self::Error> {
616        use AnyTypeEnum::*;
617        Ok(match value {
618            ArrayType(at) => at.into(),
619            FloatType(ft) => ft.into(),
620            IntType(it) => it.into(),
621            PointerType(pt) => pt.into(),
622            StructType(st) => st.into(),
623            VectorType(vt) => vt.into(),
624            ScalableVectorType(vt) => vt.into(),
625            VoidType(_) | FunctionType(_) => return Err(()),
626        })
627    }
628}
629
630impl<'ctx> TryFrom<BasicMetadataTypeEnum<'ctx>> for BasicTypeEnum<'ctx> {
631    type Error = ();
632
633    fn try_from(value: BasicMetadataTypeEnum<'ctx>) -> Result<Self, Self::Error> {
634        use BasicMetadataTypeEnum::*;
635        Ok(match value {
636            ArrayType(at) => at.into(),
637            FloatType(ft) => ft.into(),
638            IntType(it) => it.into(),
639            PointerType(pt) => pt.into(),
640            StructType(st) => st.into(),
641            VectorType(vt) => vt.into(),
642            ScalableVectorType(vt) => vt.into(),
643            MetadataType(_) => return Err(()),
644        })
645    }
646}
647
648impl<'ctx> From<BasicTypeEnum<'ctx>> for BasicMetadataTypeEnum<'ctx> {
649    fn from(value: BasicTypeEnum<'ctx>) -> Self {
650        use BasicTypeEnum::*;
651        match value {
652            ArrayType(at) => at.into(),
653            FloatType(ft) => ft.into(),
654            IntType(it) => it.into(),
655            PointerType(pt) => pt.into(),
656            StructType(st) => st.into(),
657            VectorType(vt) => vt.into(),
658            ScalableVectorType(vt) => vt.into(),
659        }
660    }
661}
662
663impl Display for AnyTypeEnum<'_> {
664    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
665        write!(f, "{}", self.print_to_string())
666    }
667}
668
669impl Display for BasicTypeEnum<'_> {
670    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
671        write!(f, "{}", self.print_to_string())
672    }
673}
674
675impl Display for BasicMetadataTypeEnum<'_> {
676    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
677        write!(f, "{}", self.print_to_string())
678    }
679}