Repository: mun-lang/mun (language: rust)

Issue:
Refactor Mun ABI to safely support `StructInfo` in `TypeInfo`
Currently, `StructInfo` is appended to a `TypeInfo` struct - for types that are structs. We can obtain the `StructInfo` as follows:
```rust
/// Retrieves the type's struct information, if available.
pub fn as_struct(&self) -> Option<&StructInfo> {
    if self.group.is_struct() {
        let ptr = (self as *const TypeInfo).cast::<u8>();
        let ptr = ptr.wrapping_add(mem::size_of::<TypeInfo>());
        let offset = ptr.align_offset(mem::align_of::<StructInfo>());
        let ptr = ptr.wrapping_add(offset);
        Some(unsafe { &*ptr.cast::<StructInfo>() })
    } else {
        None
    }
}
```
As this is `unsafe`, we want to add proper ABI support for `StructInfo` inside the `TypeInfo`, by adding:
```rust
#[derive(AsValue)]
#[repr(u8)]
pub enum TypeInfoData {
    Primitive,
    Struct(StructInfo),
}
```
to the `TypeInfo`:
```rust
#[derive(AsValue)]
pub struct TypeInfo {
    ...
    pub data: TypeInfoData,
}
```

Depends on #275 


Discussion / hints:

Fix patch:
diff --git a/crates/mun_abi/ffi b/crates/mun_abi/ffi
index 4e6b5421c..c60db3e4d 160000
--- a/crates/mun_abi/ffi
+++ b/crates/mun_abi/ffi
@@ -1,1 +1,1 @@
-Subproject commit 4e6b5421c058e489af886b447c8c13ad4cd04a1c
+Subproject commit c60db3e4db4b7f40aae219c4ee44dd8f44d31358
diff --git a/crates/mun_abi/src/dispatch_table.rs b/crates/mun_abi/src/dispatch_table.rs
index 339ff72f6..06cca44a3 100644
--- a/crates/mun_abi/src/dispatch_table.rs
+++ b/crates/mun_abi/src/dispatch_table.rs
@@ -113,7 +113,7 @@ mod tests {
         test_utils::{
             fake_dispatch_table, fake_fn_prototype, fake_type_info, FAKE_FN_NAME, FAKE_TYPE_NAME,
         },
-        TypeGroup,
+        TypeInfoData,
     };
     use std::{ffi::CString, ptr};
 
@@ -130,7 +130,7 @@ mod tests {
     #[test]
     fn test_dispatch_table_iter_mut_some() {
         let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name.");
-        let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1);
+        let type_info = fake_type_info(&type_name, 1, 1, TypeInfoData::Primitive);
 
         let return_type = Some(&type_info);
         let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name.");
@@ -163,7 +163,7 @@ mod tests {
     #[test]
     fn test_dispatch_table_ptrs_mut_some() {
         let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name.");
-        let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1);
+        let type_info = fake_type_info(&type_name, 1, 1, TypeInfoData::Primitive);
 
         let return_type = Some(&type_info);
         let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name.");
@@ -192,7 +192,7 @@ mod tests {
     #[test]
     fn test_dispatch_table_signatures_some() {
         let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name.");
-        let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1);
+        let type_info = fake_type_info(&type_name, 1, 1, TypeInfoData::Primitive);
 
         let return_type = Some(&type_info);
         let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name.");
@@ -214,7 +214,7 @@ mod tests {
     #[test]
     fn test_dispatch_table_get_ptr_unchecked() {
         let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name.");
-        let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1);
+        let type_info = fake_type_info(&type_name, 1, 1, TypeInfoData::Primitive);
 
         let return_type = Some(&type_info);
         let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name.");
@@ -230,7 +230,7 @@ mod tests {
     #[test]
     fn test_dispatch_table_get_ptr_none() {
         let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name.");
-        let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1);
+        let type_info = fake_type_info(&type_name, 1, 1, TypeInfoData::Primitive);
 
         let return_type = Some(&type_info);
         let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name.");
@@ -246,7 +246,7 @@ mod tests {
     #[test]
     fn test_dispatch_table_get_ptr_some() {
         let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name.");
-        let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1);
+        let type_info = fake_type_info(&type_name, 1, 1, TypeInfoData::Primitive);
 
         let return_type = Some(&type_info);
         let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name.");
@@ -262,7 +262,7 @@ mod tests {
     #[test]
     fn test_dispatch_table_get_ptr_unchecked_mut() {
         let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name.");
-        let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1);
+        let type_info = fake_type_info(&type_name, 1, 1, TypeInfoData::Primitive);
 
         let return_type = Some(&type_info);
         let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name.");
@@ -281,7 +281,7 @@ mod tests {
     #[test]
     fn test_dispatch_table_get_ptr_mut_none() {
         let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name.");
-        let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1);
+        let type_info = fake_type_info(&type_name, 1, 1, TypeInfoData::Primitive);
 
         let return_type = Some(&type_info);
         let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name.");
@@ -297,7 +297,7 @@ mod tests {
     #[test]
     fn test_dispatch_table_get_ptr_mut_some() {
         let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name.");
-        let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1);
+        let type_info = fake_type_info(&type_name, 1, 1, TypeInfoData::Primitive);
 
         let return_type = Some(&type_info);
         let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name.");
diff --git a/crates/mun_abi/src/function_info.rs b/crates/mun_abi/src/function_info.rs
index 5d5dbb2fb..d7f3bf288 100644
--- a/crates/mun_abi/src/function_info.rs
+++ b/crates/mun_abi/src/function_info.rs
@@ -233,7 +233,7 @@ mod tests {
         test_utils::{
             fake_fn_prototype, fake_fn_signature, fake_type_info, FAKE_FN_NAME, FAKE_TYPE_NAME,
         },
-        TypeGroup,
+        TypeInfoData,
     };
     use std::ffi::CString;
 
@@ -256,7 +256,7 @@ mod tests {
     #[test]
     fn test_fn_signature_arg_types_some() {
         let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name.");
-        let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1);
+        let type_info = fake_type_info(&type_name, 1, 1, TypeInfoData::Primitive);
 
         let arg_types = &[&type_info];
         let fn_signature = fake_fn_signature(arg_types, None);
@@ -275,7 +275,7 @@ mod tests {
     #[test]
     fn test_fn_signature_return_type_some() {
         let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name.");
-        let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1);
+        let type_info = fake_type_info(&type_name, 1, 1, TypeInfoData::Primitive);
 
         let return_type = Some(&type_info);
         let fn_signature = fake_fn_signature(&[], return_type);
diff --git a/crates/mun_abi/src/lib.rs b/crates/mun_abi/src/lib.rs
index fb7c0df14..3b6e7414f 100644
--- a/crates/mun_abi/src/lib.rs
+++ b/crates/mun_abi/src/lib.rs
@@ -24,13 +24,13 @@ pub use function_info::{
 };
 pub use module_info::ModuleInfo;
 pub use struct_info::{StructInfo, StructMemoryKind};
-pub use type_info::{HasStaticTypeInfo, TypeGroup, TypeInfo};
+pub use type_info::{HasStaticTypeInfo, TypeInfo, TypeInfoData};
 
 /// The Mun ABI prelude
 ///
 /// The *prelude* contains imports that are used almost every time.
 pub mod prelude {
-    pub use crate::{HasStaticTypeInfo, IntoFunctionDefinition, StructMemoryKind, TypeGroup};
+    pub use crate::{HasStaticTypeInfo, IntoFunctionDefinition, StructMemoryKind};
 }
 
 /// Defines the current ABI version
diff --git a/crates/mun_abi/src/module_info.rs b/crates/mun_abi/src/module_info.rs
index 7fb1ef34d..162d1f626 100644
--- a/crates/mun_abi/src/module_info.rs
+++ b/crates/mun_abi/src/module_info.rs
@@ -65,12 +65,12 @@ unsafe impl Sync for ModuleInfo {}
 mod tests {
     use crate::{
         test_utils::{
-            fake_fn_prototype, fake_module_info, fake_struct_info, fake_struct_type_info,
-            fake_type_info, FAKE_FN_NAME, FAKE_MODULE_PATH, FAKE_STRUCT_NAME, FAKE_TYPE_NAME,
+            fake_fn_prototype, fake_module_info, fake_struct_info, fake_type_info, FAKE_FN_NAME,
+            FAKE_MODULE_PATH, FAKE_STRUCT_NAME, FAKE_TYPE_NAME,
         },
-        FunctionDefinition, TypeGroup, TypeInfo,
+        FunctionDefinition, TypeInfo, TypeInfoData,
     };
-    use std::{ffi::CString, mem, ptr};
+    use std::{ffi::CString, ptr};
 
     #[test]
     fn test_module_info_path() {
@@ -94,7 +94,7 @@ mod tests {
     #[test]
     fn test_module_info_types_some() {
         let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name.");
-        let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1);
+        let type_info = fake_type_info(&type_name, 1, 1, TypeInfoData::Primitive);
 
         let return_type = Some(&type_info);
         let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name.");
@@ -108,8 +108,8 @@ mod tests {
 
         let struct_name = CString::new(FAKE_STRUCT_NAME).expect("Invalid fake struct name");
         let struct_info = fake_struct_info(&[], &[], &[], Default::default());
-        let struct_type_info = fake_struct_type_info(&struct_name, struct_info, 1, 1);
-        let types = &[unsafe { mem::transmute(&struct_type_info) }];
+        let type_info = fake_type_info(&struct_name, 1, 1, TypeInfoData::Struct(struct_info));
+        let types = &[&type_info];
 
         let module_path = CString::new(FAKE_MODULE_PATH).expect("Invalid fake module path.");
         let module = fake_module_info(&module_path, functions, types);
@@ -134,11 +134,14 @@ mod tests {
         for (lhs, rhs) in result_types.iter().zip(types.iter()) {
             assert_eq!(lhs, rhs);
             assert_eq!(lhs.name(), rhs.name());
-            assert_eq!(lhs.group, rhs.group);
-            if lhs.group == TypeGroup::StructTypes {
-                let lhs_struct = lhs.as_struct().unwrap();
-                let rhs_struct = rhs.as_struct().unwrap();
-                assert_eq!(lhs_struct.field_types(), rhs_struct.field_types());
+            assert_eq!(lhs.data.is_struct(), rhs.data.is_struct());
+            assert_eq!(lhs.data.is_primitive(), rhs.data.is_primitive());
+            if let TypeInfoData::Struct(lhs) = &lhs.data {
+                if let TypeInfoData::Struct(rhs) = &rhs.data {
+                    assert_eq!(lhs.field_types(), rhs.field_types());
+                } else {
+                    assert!(false);
+                }
             }
         }
     }
diff --git a/crates/mun_abi/src/struct_info.rs b/crates/mun_abi/src/struct_info.rs
index f618e377b..19c231c32 100644
--- a/crates/mun_abi/src/struct_info.rs
+++ b/crates/mun_abi/src/struct_info.rs
@@ -3,6 +3,7 @@ use std::{ffi::CStr, os::raw::c_char, slice, str};
 
 /// Represents a struct declaration.
 #[repr(C)]
+#[derive(Debug)]
 pub struct StructInfo {
     /// Struct fields' names
     pub field_names: *const *const c_char,
@@ -116,7 +117,7 @@ mod tests {
     use super::StructMemoryKind;
     use crate::{
         test_utils::{fake_struct_info, fake_type_info, FAKE_FIELD_NAME, FAKE_TYPE_NAME},
-        TypeGroup,
+        TypeInfoData,
     };
     use std::ffi::CString;
 
@@ -137,7 +138,7 @@ mod tests {
     fn test_struct_info_fields_some() {
         let field_name = CString::new(FAKE_FIELD_NAME).expect("Invalid fake field name.");
         let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name.");
-        let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1);
+        let type_info = fake_type_info(&type_name, 1, 1, TypeInfoData::Primitive);
 
         let field_names = &[field_name.as_ptr()];
         let field_types = &[&type_info];
diff --git a/crates/mun_abi/src/type_info.rs b/crates/mun_abi/src/type_info.rs
index 1f8192de9..4385bf6bf 100644
--- a/crates/mun_abi/src/type_info.rs
+++ b/crates/mun_abi/src/type_info.rs
@@ -4,7 +4,6 @@ use std::{
     convert::TryInto,
     ffi::{CStr, CString},
     fmt::{self, Formatter},
-    mem,
     os::raw::c_char,
     str,
     sync::Once,
@@ -26,17 +25,17 @@ pub struct TypeInfo {
     /// The alignment of the type
     pub(crate) alignment: u8,
     /// Type group
-    pub group: TypeGroup,
+    pub data: TypeInfoData,
 }
 
-/// Represents a group of types that illicit the same characteristics.
+/// Contains data specific to a group of types that illicit the same characteristics.
 #[repr(u8)]
-#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
-pub enum TypeGroup {
-    /// Fundamental types (i.e. `()`, `bool`, `float`, `int`, etc.)
-    FundamentalTypes = 0,
+#[derive(Debug)]
+pub enum TypeInfoData {
+    /// Primitive types (i.e. `()`, `bool`, `float`, `int`, etc.)
+    Primitive,
     /// Struct types (i.e. record, tuple, or unit structs)
-    StructTypes = 1,
+    Struct(StructInfo),
 }
 
 impl TypeInfo {
@@ -47,12 +46,8 @@ impl TypeInfo {
 
     /// Retrieves the type's struct information, if available.
     pub fn as_struct(&self) -> Option<&StructInfo> {
-        if self.group.is_struct() {
-            let ptr = (self as *const TypeInfo).cast::<u8>();
-            let ptr = ptr.wrapping_add(mem::size_of::<TypeInfo>());
-            let offset = ptr.align_offset(mem::align_of::<StructInfo>());
-            let ptr = ptr.wrapping_add(offset);
-            Some(unsafe { &*ptr.cast::<StructInfo>() })
+        if let TypeInfoData::Struct(s) = &self.data {
+            Some(s)
         } else {
             None
         }
@@ -101,15 +96,15 @@ impl std::hash::Hash for TypeInfo {
 unsafe impl Send for TypeInfo {}
 unsafe impl Sync for TypeInfo {}
 
-impl TypeGroup {
+impl TypeInfoData {
     /// Returns whether this is a fundamental type.
-    pub fn is_fundamental(self) -> bool {
-        self == TypeGroup::FundamentalTypes
+    pub fn is_primitive(&self) -> bool {
+        matches!(self, TypeInfoData::Primitive)
     }
 
     /// Returns whether this is a struct type.
-    pub fn is_struct(self) -> bool {
-        self == TypeGroup::StructTypes
+    pub fn is_struct(&self) -> bool {
+        matches!(self, TypeInfoData::Struct(_))
     }
 }
 
@@ -157,13 +152,13 @@ impl<T: HasStaticTypeInfoName + 'static> HasStaticTypeInfo for *const T {
                 TypeInfo {
                     guid,
                     name: name_ptr,
-                    group: TypeGroup::FundamentalTypes,
                     size_in_bits: (std::mem::size_of::<*const T>() * 8)
                         .try_into()
                         .expect("size of T is larger than the maximum allowed ABI size. Please file a bug."),
                     alignment: (std::mem::align_of::<*const T>())
                         .try_into()
                         .expect("alignment of T is larger than the maximum allowed ABI size. Please file a bug."),
+                    data: TypeInfoData::Primitive,
                 },
             )
         })
@@ -193,13 +188,13 @@ impl<T: HasStaticTypeInfoName + 'static> HasStaticTypeInfo for *mut T {
                 TypeInfo {
                     guid,
                     name: name_ptr,
-                    group: TypeGroup::FundamentalTypes,
                     size_in_bits: (std::mem::size_of::<*const T>() * 8)
                         .try_into()
                         .expect("size of T is larger than the maximum allowed ABI size. Please file a bug."),
                     alignment: (std::mem::align_of::<*const T>())
                         .try_into()
                         .expect("alignment of T is larger than the maximum allowed ABI size. Please file a bug."),
+                    data: TypeInfoData::Primitive,
                 },
             )
         })
@@ -207,7 +202,7 @@ impl<T: HasStaticTypeInfoName + 'static> HasStaticTypeInfo for *mut T {
     }
 }
 
-macro_rules! impl_basic_type_info {
+macro_rules! impl_primitive_type_info {
     ($(
         $ty:ty
     ),+) => {
@@ -223,13 +218,13 @@ macro_rules! impl_basic_type_info {
                         TypeInfo {
                             guid: Guid(md5::compute(&type_info_name.as_bytes()).0),
                             name: type_info_name.as_ptr(),
-                            group: TypeGroup::FundamentalTypes,
                             size_in_bits: (std::mem::size_of::<$ty>() * 8)
                                 .try_into()
                                 .expect("size of T is larger than the maximum allowed ABI size. Please file a bug."),
                             alignment: (std::mem::align_of::<$ty>())
                                 .try_into()
                                 .expect("alignment of T is larger than the maximum allowed ABI size. Please file a bug."),
+                            data: TypeInfoData::Primitive,
                         }
                     })
                 }
@@ -255,7 +250,7 @@ macro_rules! impl_has_type_info_name {
     }
 }
 
-impl_basic_type_info!(i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, f32, f64, bool);
+impl_primitive_type_info!(i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, f32, f64, bool);
 
 impl_has_type_info_name!(
     std::ffi::c_void => "core::void",
@@ -292,14 +287,14 @@ impl HasStaticTypeInfo for isize {
 
 #[cfg(test)]
 mod tests {
-    use super::{HasStaticTypeInfoName, TypeGroup};
-    use crate::test_utils::{fake_type_info, FAKE_TYPE_NAME};
+    use super::{HasStaticTypeInfoName, TypeInfoData};
+    use crate::test_utils::{fake_struct_info, fake_type_info, FAKE_TYPE_NAME};
     use std::ffi::CString;
 
     #[test]
     fn test_type_info_name() {
         let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name.");
-        let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1);
+        let type_info = fake_type_info(&type_name, 1, 1, TypeInfoData::Primitive);
 
         assert_eq!(type_info.name(), FAKE_TYPE_NAME);
     }
@@ -307,7 +302,7 @@ mod tests {
     #[test]
     fn test_type_info_size_alignment() {
         let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name.");
-        let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 24, 8);
+        let type_info = fake_type_info(&type_name, 24, 8, TypeInfoData::Primitive);
 
         assert_eq!(type_info.size_in_bits(), 24);
         assert_eq!(type_info.size_in_bytes(), 3);
@@ -317,29 +312,32 @@ mod tests {
     #[test]
     fn test_type_info_group_fundamental() {
         let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name.");
-        let type_group = TypeGroup::FundamentalTypes;
-        let type_info = fake_type_info(&type_name, type_group, 1, 1);
+        let type_info = fake_type_info(&type_name, 1, 1, TypeInfoData::Primitive);
 
-        assert_eq!(type_info.group, type_group);
-        assert!(type_info.group.is_fundamental());
-        assert!(!type_info.group.is_struct());
+        assert!(type_info.data.is_primitive());
+        assert!(!type_info.data.is_struct());
     }
 
     #[test]
     fn test_type_info_group_struct() {
         let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name.");
-        let type_group = TypeGroup::StructTypes;
-        let type_info = fake_type_info(&type_name, type_group, 1, 1);
 
-        assert_eq!(type_info.group, type_group);
-        assert!(type_info.group.is_struct());
-        assert!(!type_info.group.is_fundamental());
+        let field_names = &[];
+        let field_types = &[];
+        let field_offsets = &[];
+        let struct_info =
+            fake_struct_info(field_names, field_types, field_offsets, Default::default());
+
+        let type_info = fake_type_info(&type_name, 1, 1, TypeInfoData::Struct(struct_info));
+
+        assert!(type_info.data.is_struct());
+        assert!(!type_info.data.is_primitive());
     }
 
     #[test]
     fn test_type_info_eq() {
         let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name.");
-        let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1);
+        let type_info = fake_type_info(&type_name, 1, 1, TypeInfoData::Primitive);
 
         assert_eq!(type_info, type_info);
     }
diff --git a/crates/mun_codegen/src/ir/ty.rs b/crates/mun_codegen/src/ir/ty.rs
index 3b9d9acae..89c83a006 100644
--- a/crates/mun_codegen/src/ir/ty.rs
+++ b/crates/mun_codegen/src/ir/ty.rs
@@ -230,7 +230,7 @@ impl<'db, 'ink> HirTypeCache<'db, 'ink> {
                 TypeCtor::Float(ty) => {
                     let ir_ty = self.get_float_type(ty);
                     let type_size = TypeSize::from_ir_type(&ir_ty, &self.target_data);
-                    TypeInfo::new_fundamental(
+                    TypeInfo::new_primitive(
                         format!("core::{}", ty.resolve(&self.db.target_data_layout())),
                         type_size,
                     )
@@ -238,7 +238,7 @@ impl<'db, 'ink> HirTypeCache<'db, 'ink> {
                 TypeCtor::Int(ty) => {
                     let ir_ty = self.get_int_type(ty);
                     let type_size = TypeSize::from_ir_type(&ir_ty, &self.target_data);
-                    TypeInfo::new_fundamental(
+                    TypeInfo::new_primitive(
                         format!("core::{}", ty.resolve(&self.db.target_data_layout())),
                         type_size,
                     )
@@ -246,7 +246,7 @@ impl<'db, 'ink> HirTypeCache<'db, 'ink> {
                 TypeCtor::Bool => {
                     let ir_ty = self.get_bool_type();
                     let type_size = TypeSize::from_ir_type(&ir_ty, &self.target_data);
-                    TypeInfo::new_fundamental("core::bool", type_size)
+                    TypeInfo::new_primitive("core::bool", type_size)
                 }
                 TypeCtor::Struct(s) => {
                     let ir_ty = self.get_struct_type(s);
diff --git a/crates/mun_codegen/src/ir/type_table.rs b/crates/mun_codegen/src/ir/type_table.rs
index ff96d269e..b7b76ddfb 100644
--- a/crates/mun_codegen/src/ir/type_table.rs
+++ b/crates/mun_codegen/src/ir/type_table.rs
@@ -2,7 +2,7 @@ use super::types as ir;
 use crate::{
     ir::dispatch_table::{DispatchTable, FunctionPrototype},
     ir::ty::HirTypeCache,
-    type_info::{TypeGroup, TypeInfo},
+    type_info::{TypeInfo, TypeInfoData},
     value::{AsValue, CanInternalize, Global, IrValueContext, IterAsIrValue, Value},
     ModuleGroup,
 };
@@ -147,7 +147,7 @@ impl<'db, 'ink, 't> TypeTableBuilder<'db, 'ink, 't> {
 
     /// Collects unique `TypeInfo` from the given `Ty`.
     fn collect_type(&mut self, type_info: TypeInfo) {
-        if let TypeGroup::StructTypes(hir_struct) = type_info.group {
+        if let TypeInfoData::Struct(hir_struct) = type_info.data {
             self.collect_struct(hir_struct);
         } else {
             self.entries.insert(type_info);
@@ -251,29 +251,15 @@ impl<'db, 'ink, 't> TypeTableBuilder<'db, 'ink, 't> {
                 .alignment
                 .try_into()
                 .expect("could not convert alignment to smaller size"),
-            group: type_info.group.to_abi_type(),
+            data: self.gen_type_info_data(type_info_to_ir, &type_info.data),
         }
         .as_value(self.value_context);
 
         // Build the global value for the ir::TypeInfo
         let type_ir_name = type_info_global_name(type_info);
-        let value = match type_info.group {
-            TypeGroup::FundamentalTypes => type_info_ir
-                .into_const_private_global(&type_ir_name, self.value_context)
-                .as_value(self.value_context),
-            TypeGroup::StructTypes(s) => {
-                // In case of a struct the `Global<ir::TypeInfo>` is actually a
-                // `Global<(ir::TypeInfo, ir::StructInfo)>`.
-                let struct_info_ir = self.gen_struct_info(type_info_to_ir, s);
-                let compound_type_ir = (type_info_ir, struct_info_ir).as_value(self.value_context);
-                let compound_global =
-                    compound_type_ir.into_const_private_global(&type_ir_name, self.value_context);
-                Value::<*const ir::TypeInfo>::with_cast(
-                    compound_global.value.as_pointer_value(),
-                    self.value_context,
-                )
-            }
-        };
+        let value = type_info_ir
+            .into_const_private_global(&type_ir_name, self.value_context)
+            .as_value(self.value_context);
 
         // Insert the value in this case, so we don't recompute and generate multiple values.
         type_info_to_ir.insert(type_info.clone(), value);
@@ -281,11 +267,24 @@ impl<'db, 'ink, 't> TypeTableBuilder<'db, 'ink, 't> {
         value
     }
 
+    fn gen_type_info_data(
+        &self,
+        type_info_to_ir: &mut HashMap<TypeInfo, Value<'ink, *const ir::TypeInfo<'ink>>>,
+        data: &TypeInfoData,
+    ) -> ir::TypeInfoData<'ink> {
+        match data {
+            TypeInfoData::Primitive => ir::TypeInfoData::Primitive,
+            TypeInfoData::Struct(s) => {
+                ir::TypeInfoData::Struct(self.gen_struct_info(type_info_to_ir, *s))
+            }
+        }
+    }
+
     fn gen_struct_info(
         &self,
         type_info_to_ir: &mut HashMap<TypeInfo, Value<'ink, *const ir::TypeInfo<'ink>>>,
         hir_struct: hir::Struct,
-    ) -> Value<'ink, ir::StructInfo<'ink>> {
+    ) -> ir::StructInfo<'ink> {
         let struct_ir = self.hir_types.get_struct_type(hir_struct);
         let name = hir_struct.full_name(self.db);
         let fields = hir_struct.fields(self.db);
@@ -344,7 +343,6 @@ impl<'db, 'ink, 't> TypeTableBuilder<'db, 'ink, 't> {
                 .expect("could not convert num_fields to smaller bit size"),
             memory_kind: hir_struct.data(self.db.upcast()).memory_kind.clone(),
         }
-        .as_value(self.value_context)
     }
 
     /// Constructs a `TypeTable` from all *used* types.
diff --git a/crates/mun_codegen/src/ir/types.rs b/crates/mun_codegen/src/ir/types.rs
index bc9ac7c2a..ed9b39596 100644
--- a/crates/mun_codegen/src/ir/types.rs
+++ b/crates/mun_codegen/src/ir/types.rs
@@ -28,18 +28,6 @@ impl<'ink> TransparentValue<'ink> for abi::Privacy {
     }
 }
 
-impl<'ink> TransparentValue<'ink> for abi::TypeGroup {
-    type Target = u8;
-
-    fn as_target_value(&self, context: &IrValueContext<'ink, '_, '_>) -> Value<'ink, Self::Target> {
-        (*self as u8).as_value(context)
-    }
-
-    fn as_bytes_and_ptrs(&self, _: &IrTypeContext<'ink, '_>) -> Vec<BytesOrPtr<'ink>> {
-        vec![vec![*self as u8].into()]
-    }
-}
-
 impl<'ink> TransparentValue<'ink> for abi::StructMemoryKind {
     type Target = u8;
 
@@ -58,7 +46,14 @@ pub struct TypeInfo<'ink> {
     pub name: Value<'ink, *const u8>,
     pub size_in_bits: u32,
     pub alignment: u8,
-    pub group: abi::TypeGroup,
+    pub data: TypeInfoData<'ink>,
+}
+
+#[derive(AsValue)]
+#[repr(u8)]
+pub enum TypeInfoData<'ink> {
+    Primitive,
+    Struct(StructInfo<'ink>),
 }
 
 #[derive(AsValue)]
diff --git a/crates/mun_codegen/src/type_info.rs b/crates/mun_codegen/src/type_info.rs
index 03660cf5b..ab2d56b73 100644
--- a/crates/mun_codegen/src/type_info.rs
+++ b/crates/mun_codegen/src/type_info.rs
@@ -7,27 +7,9 @@ use inkwell::types::AnyType;
 use std::hash::{Hash, Hasher};
 
 #[derive(Clone, Debug, Eq, PartialEq)]
-pub enum TypeGroup {
-    FundamentalTypes,
-    StructTypes(hir::Struct),
-}
-
-impl From<TypeGroup> for u64 {
-    fn from(group: TypeGroup) -> Self {
-        match group {
-            TypeGroup::FundamentalTypes => 0,
-            TypeGroup::StructTypes(_) => 1,
-        }
-    }
-}
-
-impl TypeGroup {
-    pub fn to_abi_type(&self) -> abi::TypeGroup {
-        match self {
-            TypeGroup::FundamentalTypes => abi::TypeGroup::FundamentalTypes,
-            TypeGroup::StructTypes(_) => abi::TypeGroup::StructTypes,
-        }
-    }
+pub enum TypeInfoData {
+    Primitive,
+    Struct(hir::Struct),
 }
 
 #[derive(Clone, Debug, Eq, PartialEq)]
@@ -60,8 +42,8 @@ impl TypeSize {
 pub struct TypeInfo {
     pub guid: Guid,
     pub name: String,
-    pub group: TypeGroup,
     pub size: TypeSize,
+    pub data: TypeInfoData,
 }
 
 impl Hash for TypeInfo {
@@ -89,12 +71,12 @@ impl PartialOrd for TypeInfo {
 }
 
 impl TypeInfo {
-    pub fn new_fundamental<S: AsRef<str>>(name: S, type_size: TypeSize) -> TypeInfo {
+    pub fn new_primitive<S: AsRef<str>>(name: S, type_size: TypeSize) -> TypeInfo {
         TypeInfo {
             name: name.as_ref().to_string(),
             guid: Guid(md5::compute(name.as_ref()).0),
-            group: TypeGroup::FundamentalTypes,
             size: type_size,
+            data: TypeInfoData::Primitive,
         }
     }
 
@@ -122,8 +104,8 @@ impl TypeInfo {
         Self {
             guid: Guid(md5::compute(&guid_string).0),
             name,
-            group: TypeGroup::StructTypes(s),
             size: type_size,
+            data: TypeInfoData::Struct(s),
         }
     }
 }
@@ -164,7 +146,7 @@ macro_rules! impl_fundamental_static_type_info {
             impl HasStaticTypeInfo for $ty {
                 fn type_info(context: &Context, target: &TargetData) -> TypeInfo {
                     let ty = <$ty as IsIrType>::ir_type(context, target);
-                    TypeInfo::new_fundamental(
+                    TypeInfo::new_primitive(
                         format!("core::{}", stringify!($ty)),
                         TypeSize::from_ir_type(&ty, target)
                     )
@@ -181,7 +163,7 @@ impl_fundamental_static_type_info!(
 impl<T: HasStaticTypeName> HasStaticTypeInfo for *mut T {
     fn type_info(context: &Context, target: &TargetData) -> TypeInfo {
         let ty = context.ptr_sized_int_type(target, None);
-        TypeInfo::new_fundamental(
+        TypeInfo::new_primitive(
             format!("*mut {}", T::type_name(context, target)),
             TypeSize::from_ir_type(&ty, target),
         )
@@ -194,7 +176,7 @@ impl<T: HasStaticTypeName> HasStaticTypeInfo for *const T {
         target: &inkwell::targets::TargetData,
     ) -> TypeInfo {
         let ty = context.ptr_sized_int_type(target, None);
-        TypeInfo::new_fundamental(
+        TypeInfo::new_primitive(
             format!("*const {}", T::type_name(context, target)),
             TypeSize::from_ir_type(&ty, target),
         )
diff --git a/crates/mun_memory/src/diff.rs b/crates/mun_memory/src/diff.rs
index 97d848998..12a5d664f 100644
--- a/crates/mun_memory/src/diff.rs
+++ b/crates/mun_memory/src/diff.rs
@@ -1,6 +1,6 @@
 pub mod myers;
 
-use crate::{TypeDesc, TypeFields};
+use crate::{TypeDesc, TypeFields, TypeGroup};
 
 #[derive(Clone, Debug, Eq, PartialEq)]
 pub enum FieldEditKind {
@@ -80,35 +80,35 @@ where
     let mut mapping: Vec<Diff> = Vec::with_capacity(diff.len());
     let (deletions, insertions) = myers::split_diff(&diff);
 
-    // ASSUMPTION: `FundamentalTypes` can never be converted to `StructTypes`, hence they can be
+    // ASSUMPTION: `Primitive` types can never be converted to `Struct` types, hence they can be
     // compared separately.
-    let deleted_fundamentals = deletions
+    let deleted_primitives = deletions
         .iter()
-        .filter(|idx| unsafe { old.get_unchecked(**idx) }.group().is_fundamental())
+        .filter(|idx| unsafe { old.get_unchecked(**idx) }.group() == TypeGroup::Primitive)
         .cloned()
         .collect();
     let deleted_structs = deletions
         .iter()
-        .filter(|idx| unsafe { old.get_unchecked(**idx) }.group().is_struct())
+        .filter(|idx| unsafe { old.get_unchecked(**idx) }.group() == TypeGroup::Struct)
         .cloned()
         .collect();
 
-    let inserted_fundamentals = insertions
+    let inserted_primitives = insertions
         .iter()
-        .filter(|idx| unsafe { new.get_unchecked(**idx) }.group().is_fundamental())
+        .filter(|idx| unsafe { new.get_unchecked(**idx) }.group() == TypeGroup::Primitive)
         .cloned()
         .collect();
     let inserted_structs = insertions
         .iter()
-        .filter(|idx| unsafe { new.get_unchecked(**idx) }.group().is_struct())
+        .filter(|idx| unsafe { new.get_unchecked(**idx) }.group() == TypeGroup::Struct)
         .cloned()
         .collect();
 
-    append_fundamental_mapping(
+    append_primitive_mapping(
         old,
         new,
-        deleted_fundamentals,
-        inserted_fundamentals,
+        deleted_primitives,
+        inserted_primitives,
         &mut mapping,
     );
     append_struct_mapping(old, new, deleted_structs, inserted_structs, &mut mapping);
@@ -119,7 +119,7 @@ where
     mapping
 }
 
-fn append_fundamental_mapping<T>(
+fn append_primitive_mapping<T>(
     old: &[T],
     new: &[T],
     deletions: Vec<usize>,
diff --git a/crates/mun_memory/src/gc/mark_sweep.rs b/crates/mun_memory/src/gc/mark_sweep.rs
index 7e0d99f48..50429e222 100644
--- a/crates/mun_memory/src/gc/mark_sweep.rs
+++ b/crates/mun_memory/src/gc/mark_sweep.rs
@@ -2,7 +2,7 @@ use crate::{
     cast,
     gc::{Event, GcPtr, GcRuntime, Observer, RawGcPtr, Stats, TypeTrace},
     mapping::{self, FieldMapping, MemoryMapper},
-    TypeDesc, TypeMemory,
+    TypeDesc, TypeGroup, TypeMemory,
 };
 use mapping::{Conversion, Mapping};
 use parking_lot::RwLock;
@@ -315,8 +315,8 @@ where
                             src as *mut u8
                         };
 
-                        if old_ty.group().is_struct() {
-                            debug_assert!(new_ty.group().is_struct());
+                        if old_ty.group() == TypeGroup::Struct {
+                            debug_assert_eq!(new_ty.group(), TypeGroup::Struct);
 
                             // When the name is the same, we are dealing with the same struct,
                             // but different internals
diff --git a/crates/mun_memory/src/lib.rs b/crates/mun_memory/src/lib.rs
index 0f4b3dcf8..f96361fe0 100644
--- a/crates/mun_memory/src/lib.rs
+++ b/crates/mun_memory/src/lib.rs
@@ -10,6 +10,21 @@ pub mod prelude {
     pub use crate::mapping::{Action, FieldMapping};
 }
 
+#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
+pub enum TypeGroup {
+    Primitive,
+    Struct,
+}
+
+impl<'t> From<&'t abi::TypeInfoData> for TypeGroup {
+    fn from(data: &'t abi::TypeInfoData) -> Self {
+        match data {
+            abi::TypeInfoData::Primitive => TypeGroup::Primitive,
+            abi::TypeInfoData::Struct(_) => TypeGroup::Struct,
+        }
+    }
+}
+
 /// A trait used to obtain a type's description.
 pub trait TypeDesc: Send + Sync {
     /// Returns the name of this type.
@@ -17,7 +32,7 @@ pub trait TypeDesc: Send + Sync {
     /// Returns the `Guid` of this type.
     fn guid(&self) -> &abi::Guid;
     /// Returns the `TypeGroup` of this type.
-    fn group(&self) -> abi::TypeGroup;
+    fn group(&self) -> TypeGroup;
 }
 
 /// A trait used to obtain a type's memory description.
diff --git a/crates/mun_memory/src/mapping.rs b/crates/mun_memory/src/mapping.rs
index ef96645dd..9215a7a01 100644
--- a/crates/mun_memory/src/mapping.rs
+++ b/crates/mun_memory/src/mapping.rs
@@ -1,7 +1,7 @@
 use crate::{
     diff::{diff, Diff, FieldDiff, FieldEditKind},
     gc::GcPtr,
-    TypeDesc, TypeFields, TypeMemory,
+    TypeDesc, TypeFields, TypeGroup, TypeMemory,
 };
 use std::{
     collections::{HashMap, HashSet},
@@ -83,7 +83,7 @@ where
         let mut new_candidates: HashSet<T> = new
             .iter()
             // Filter non-struct types
-            .filter(|ty| ty.group().is_struct())
+            .filter(|ty| ty.group() == TypeGroup::Struct)
             // Filter inserted structs
             .filter(|ty| !insertions.contains(*ty))
             .cloned()
@@ -92,7 +92,7 @@ where
         let mut old_candidates: HashSet<T> = old
             .iter()
             // Filter non-struct types
-            .filter(|ty| ty.group().is_struct())
+            .filter(|ty| ty.group() == TypeGroup::Struct)
             // Filter deleted structs
             .filter(|ty| !deletions.contains(*ty))
             // Filter edited types
diff --git a/crates/mun_runtime/src/adt.rs b/crates/mun_runtime/src/adt.rs
index 551f2126f..658788468 100644
--- a/crates/mun_runtime/src/adt.rs
+++ b/crates/mun_runtime/src/adt.rs
@@ -305,7 +305,7 @@ impl RootedStruct {
             let runtime_ref = runtime.borrow();
             // Safety: The type returned from `ptr_type` is guaranteed to live at least as long as
             // `Runtime` does not change. As we hold a shared reference to `Runtime`, this is safe.
-            assert!(unsafe { gc.ptr_type(raw.0).into_inner().as_ref().group.is_struct() });
+            assert!(unsafe { gc.ptr_type(raw.0).into_inner().as_ref().data.is_struct() });
 
             GcRootPtr::new(&runtime_ref.gc, raw.0)
         };
diff --git a/crates/mun_runtime/src/garbage_collector.rs b/crates/mun_runtime/src/garbage_collector.rs
index 53986a45d..058c787d8 100644
--- a/crates/mun_runtime/src/garbage_collector.rs
+++ b/crates/mun_runtime/src/garbage_collector.rs
@@ -1,4 +1,7 @@
-use memory::gc::{self, HasIndirectionPtr};
+use memory::{
+    gc::{self, HasIndirectionPtr},
+    TypeGroup,
+};
 use std::{alloc::Layout, hash::Hash, ptr::NonNull};
 
 /// `UnsafeTypeInfo` is a type that wraps a `NonNull<TypeInfo>` and indicates unsafe interior
@@ -50,8 +53,8 @@ impl memory::TypeDesc for UnsafeTypeInfo {
         unsafe { &self.0.as_ref().guid }
     }
 
-    fn group(&self) -> abi::TypeGroup {
-        unsafe { self.0.as_ref().group }
+    fn group(&self) -> TypeGroup {
+        TypeGroup::from(unsafe { &self.0.as_ref().data })
     }
 }
 
diff --git a/crates/mun_runtime/src/reflection.rs b/crates/mun_runtime/src/reflection.rs
index f5650c260..496db48e9 100644
--- a/crates/mun_runtime/src/reflection.rs
+++ b/crates/mun_runtime/src/reflection.rs
@@ -19,13 +19,13 @@ pub fn equals_argument_type<'e, 'f, T: ArgumentReflection>(
 pub fn equals_return_type<T: ReturnTypeReflection>(
     type_info: &abi::TypeInfo,
 ) -> Result<(), (&str, &str)> {
-    match type_info.group {
-        abi::TypeGroup::FundamentalTypes => {
+    match type_info.data {
+        abi::TypeInfoData::Primitive => {
             if type_info.guid != T::type_guid() {
                 return Err((type_info.name(), T::type_name()));
             }
         }
-        abi::TypeGroup::StructTypes => {
+        abi::TypeInfoData::Struct(_) => {
             if <StructRef as ReturnTypeReflection>::type_guid() != T::type_guid() {
                 return Err(("struct", T::type_name()));
             }
diff --git a/crates/mun_runtime_capi/ffi b/crates/mun_runtime_capi/ffi
index 02b0e9681..c80ad66fb 160000
--- a/crates/mun_runtime_capi/ffi
+++ b/crates/mun_runtime_capi/ffi
@@ -1,1 +1,1 @@
-Subproject commit 02b0e96812c570fb1541ccf29ae475e32d5f08b7
+Subproject commit c80ad66fb95803f13f7f3412b941288d18b6aa01
diff --git a/crates/tools/Cargo.toml b/crates/tools/Cargo.toml
index 4f24fe857..fc4dee593 100644
--- a/crates/tools/Cargo.toml
+++ b/crates/tools/Cargo.toml
@@ -9,5 +9,5 @@ teraron = "0.1.0"
 clap = "2.32.0"
 anyhow = "1.0.31"
 ron = "0.4.2"
-cbindgen = "= 0.14.2"
+cbindgen = "= 0.16.0"
 difference = "2.0"
diff --git a/examples/buoyancy/mun.toml b/examples/buoyancy/mun.toml
new file mode 100644
index 000000000..c76d4ba29
--- /dev/null
+++ b/examples/buoyancy/mun.toml
@@ -0,0 +1,4 @@
+[package]
+name="buoyancy"
+authors=[]
+version="0.1.0"
diff --git a/examples/buoyancy/src/mod.mun b/examples/buoyancy/src/mod.mun
new file mode 100644
index 000000000..cad23023c
--- /dev/null
+++ b/examples/buoyancy/src/mod.mun
@@ -0,0 +1,91 @@
+extern fn log_f32(value: f32);
+
+struct SimContext {
+    sphere: Sphere,
+    water: Water,
+    gravity: f32,
+}
+
+struct Sphere {
+    radius: f32,
+    mass: f32,      // density: f32,
+    height: f32,
+    velocity: f32,
+}
+
+struct Water {
+    density: f32,
+}
+
+pub fn new_sim() -> SimContext {
+    SimContext {
+        sphere: new_sphere(),
+        water: new_water(),
+        gravity: 9.81,
+    }
+}
+
+fn new_sphere() -> Sphere {
+    let radius = 1.0;
+    let density = 250.0;
+
+    let volume = calc_sphere_volume(radius);
+    let mass = density * volume;
+
+    Sphere {
+        radius,
+        mass,
+        height: 1.0,
+        velocity: 0.0,
+    }
+}
+
+fn new_water() -> Water {
+    Water {
+        density: 1000.0,
+    }
+}
+
+fn calc_submerged_ratio(s: Sphere) -> f32 {
+    let bottom = s.height - s.radius;
+    let diameter = 2.0 * s.radius;
+    if bottom >= 0.0 {
+        0.0
+    } else if bottom <= -diameter {
+        1.0
+    } else {
+        -bottom / diameter
+    }
+}
+
+fn calc_sphere_volume(radius: f32) -> f32 {
+    let pi = 3.1415926535897;
+    let r = radius;
+
+    3.0/4.0 * pi * r * r * r
+}
+
+fn calc_buoyancy_force(s: Sphere, w: Water, gravity: f32, submerged_ratio: f32) -> f32 {
+    let volume = calc_sphere_volume(s.radius);
+    volume * submerged_ratio * w.density * gravity
+}
+
+pub fn sim_update(ctx: SimContext, elapsed_secs: f32) {
+    let submerged_ratio = calc_submerged_ratio(ctx.sphere);
+    if submerged_ratio > 0.0 {
+        let buoyancy_force = calc_buoyancy_force(
+            ctx.sphere,
+            ctx.water,
+            ctx.gravity,
+            submerged_ratio
+        );
+        let buoyancy_acc = buoyancy_force / ctx.sphere.mass;
+        ctx.sphere.velocity += buoyancy_acc * elapsed_secs;
+    }
+
+    ctx.sphere.velocity -= ctx.gravity * elapsed_secs;
+
+    ctx.sphere.height += ctx.sphere.velocity * elapsed_secs;
+
+    log_f32(ctx.sphere.height);
+}
diff --git a/examples/extern/mun.toml b/examples/extern/mun.toml
new file mode 100644
index 000000000..3d2097acc
--- /dev/null
+++ b/examples/extern/mun.toml
@@ -0,0 +1,4 @@
+[package]
+name = "extern"
+authors = []
+version = "0.1.0"
diff --git a/examples/extern/src/mod.mun b/examples/extern/src/mod.mun
new file mode 100644
index 000000000..0cd8c61ba
--- /dev/null
+++ b/examples/extern/src/mod.mun
@@ -0,0 +1,5 @@
+extern fn extern_fn(a: u32, b: u32) -> u32;
+
+pub fn main(a: u32, b: u32) -> u32 {
+    extern_fn(a,b)
+}
diff --git a/examples/fibonacci/mun.toml b/examples/fibonacci/mun.toml
new file mode 100644
index 000000000..314a3d13a
--- /dev/null
+++ b/examples/fibonacci/mun.toml
@@ -0,0 +1,4 @@
+[package]
+name = "fibonacci"
+authors = []
+version = "0.1.0"
diff --git a/examples/fibonacci/src/mod.mun b/examples/fibonacci/src/mod.mun
new file mode 100644
index 000000000..a9875f734
--- /dev/null
+++ b/examples/fibonacci/src/mod.mun
@@ -0,0 +1,16 @@
+pub fn fibonacci_n() -> i64 {
+    let n = arg();
+    fibonacci(n)
+}
+
+pub fn arg() -> i64 {
+    5
+}
+
+pub fn fibonacci(n: i64) -> i64 {
+    if n <= 1 {
+        n
+    } else {
+        fibonacci(n - 1) + fibonacci(n - 2)
+    }
+}
diff --git a/examples/marshal/mun.toml b/examples/marshal/mun.toml
new file mode 100644
index 000000000..3d551de39
--- /dev/null
+++ b/examples/marshal/mun.toml
@@ -0,0 +1,4 @@
+[package]
+name = "marshal"
+authors = []
+version = "0.1.0"
diff --git a/examples/marshal/src/mod.mun b/examples/marshal/src/mod.mun
new file mode 100644
index 000000000..bfcbea757
--- /dev/null
+++ b/examples/marshal/src/mod.mun
@@ -0,0 +1,103 @@
+// TODO: Add 128-bit integers
+
+pub fn marshal_bool(a: bool, b: bool) -> bool { a || b }
+pub fn marshal_float(a: f32, b: f32) -> f32 { a + b }
+pub fn marshal_double(a: f64, b: f64) -> f64 { a + b }
+pub fn marshal_int8_t(a: i8, b: i8) -> i8 { a + b }
+pub fn marshal_int16_t(a: i16, b: i16) -> i16 { a + b }
+pub fn marshal_int32_t(a: i32, b: i32) -> i32 { a + b }
+pub fn marshal_int64_t(a: i64, b: i64) -> i64 { a + b }
+// pub fn marshal_int128_t(a: i128, b: i128) -> i128 { a + b }
+pub fn marshal_uint8_t(a: u8, b: u8) -> u8 { a + b }
+pub fn marshal_uint16_t(a: u16, b: u16) -> u16 { a + b }
+pub fn marshal_uint32_t(a: u32, b: u32) -> u32 { a + b }
+pub fn marshal_uint64_t(a: u64, b: u64) -> u64 { a + b }
+// pub fn marshal_uint128_t(a: u128, b: u128) -> u8 { a + b }
+
+struct bool_struct(bool, bool);
+struct float_struct(f32, f32);
+struct double_struct(f64, f64);
+struct int8_t_struct(i8, i8);
+struct int16_t_struct(i16, i16);
+struct int32_t_struct(i32, i32);
+struct int64_t_struct(i64, i64);
+// struct int128_t_struct(i128, i128);
+struct uint8_t_struct(u8, u8);
+struct uint16_t_struct(u16, u16);
+struct uint32_t_struct(u32, u32);
+struct uint64_t_struct(u64, u64);
+// struct uint128_t_struct(u128, u128);
+
+pub fn new_bool(a: bool, b: bool) -> bool_struct {
+    bool_struct(a, b)
+}
+
+pub fn new_float(a: f32, b: f32) -> float_struct {
+    float_struct(a, b)
+}
+
+pub fn new_double(a: f64, b: f64) -> double_struct {
+    double_struct(a, b)
+}
+
+pub fn new_int8_t(a: i8, b: i8) -> int8_t_struct {
+    int8_t_struct(a, b)
+}
+
+pub fn new_int16_t(a: i16, b: i16) -> int16_t_struct {
+    int16_t_struct(a, b)
+}
+
+pub fn new_int32_t(a: i32, b: i32) -> int32_t_struct {
+    int32_t_struct(a, b)
+}
+
+pub fn new_int64_t(a: i64, b: i64) -> int64_t_struct {
+    int64_t_struct(a, b)
+}
+
+// pub fn new_int128_t(a: i128, b: i128) -> int128_t_struct {
+//     int128_t_struct(a, b)
+// }
+
+pub fn new_uint8_t(a: u8, b: u8) -> uint8_t_struct {
+    uint8_t_struct(a, b)
+}
+
+pub fn new_uint16_t(a: u16, b: u16) -> uint16_t_struct {
+    uint16_t_struct(a, b)
+}
+
+pub fn new_uint32_t(a: u32, b: u32) -> uint32_t_struct {
+    uint32_t_struct(a, b)
+}
+
+pub fn new_uint64_t(a: u64, b: u64) -> uint64_t_struct {
+    uint64_t_struct(a, b)
+}
+
+// pub fn new_uint128_t(a: u128, b: u128) -> uint128_t_struct {
+//     uint128_t_struct(a, b)
+// }
+
+struct(gc) GcStruct(f32, f32);
+struct(value) ValueStruct(f32, f32);
+
+struct(gc) GcWrapper(GcStruct, ValueStruct)
+struct(value) ValueWrapper(GcStruct, ValueStruct);
+
+pub fn new_gc_struct(a: f32, b: f32) -> GcStruct {
+    GcStruct(a, b)
+}
+
+pub fn new_value_struct(a: f32, b: f32) -> ValueStruct {
+    ValueStruct(a, b)
+}
+
+pub fn new_gc_wrapper(a: GcStruct, b: ValueStruct) -> GcWrapper {
+    GcWrapper(a, b)
+}
+
+pub fn new_value_wrapper(a: GcStruct, b: ValueStruct) -> ValueWrapper {
+    ValueWrapper(a, b)
+}


Test patch:
diff --git a/crates/mun_abi/src/test_utils.rs b/crates/mun_abi/src/test_utils.rs
index e87c4243e..4fd7cb4ef 100644
--- a/crates/mun_abi/src/test_utils.rs
+++ b/crates/mun_abi/src/test_utils.rs
@@ -1,6 +1,6 @@
 use crate::{
     AssemblyInfo, DispatchTable, FunctionDefinition, FunctionPrototype, FunctionSignature, Guid,
-    ModuleInfo, StructInfo, StructMemoryKind, TypeGroup, TypeInfo,
+    ModuleInfo, StructInfo, StructMemoryKind, TypeInfo, TypeInfoData,
 };
 use std::{
     ffi::{c_void, CStr},
@@ -17,12 +17,6 @@ pub(crate) const FAKE_MODULE_PATH: &str = "path::to::module";
 pub(crate) const FAKE_STRUCT_NAME: &str = "StructName";
 pub(crate) const FAKE_TYPE_NAME: &str = "TypeName";
 
-/// A dummy struct for initializing a struct's `TypeInfo`
-pub(crate) struct StructTypeInfo {
-    _type_info: TypeInfo,
-    _struct_info: StructInfo,
-}
-
 pub(crate) fn fake_assembly_info(
     symbols: ModuleInfo,
     dispatch_table: DispatchTable,
@@ -103,24 +97,17 @@ pub(crate) fn fake_struct_info(
     }
 }
 
-pub(crate) fn fake_struct_type_info(
+pub(crate) fn fake_type_info(
     name: &CStr,
-    struct_info: StructInfo,
     size: u32,
     alignment: u8,
-) -> StructTypeInfo {
-    StructTypeInfo {
-        _type_info: fake_type_info(name, TypeGroup::StructTypes, size, alignment),
-        _struct_info: struct_info,
-    }
-}
-
-pub(crate) fn fake_type_info(name: &CStr, group: TypeGroup, size: u32, alignment: u8) -> TypeInfo {
+    data: TypeInfoData,
+) -> TypeInfo {
     TypeInfo {
         guid: FAKE_TYPE_GUID,
         name: name.as_ptr(),
         size_in_bits: size,
         alignment,
-        group,
+        data,
     }
 }
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_f32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_f32.snap
index 06e4aa5e6..8c90f823b 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_f32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_f32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn add(a: f32, b: f32) -> f32 { a + b }\n    pub fn subtr
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -44,9 +45,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::f32>::name" = private unnamed_addr constant [10 x i8] c"core::f32\00"
-@"type_info::<core::f32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"P\19b7\A8k\F2\81P\FB\83\F5P\B0\82!", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::f32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"P\19b7\A8k\F2\81P\FB\83\F5P\B0\82!", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_f64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_f64.snap
index 53f83a45a..3f7d3feca 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_f64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_f64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn add(a: f64, b: f64) -> f64 { a + b }\n    pub fn subtr
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -44,9 +45,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::f64>::name" = private unnamed_addr constant [10 x i8] c"core::f64\00"
-@"type_info::<core::f64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::f64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i128.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i128.snap
index b772c187d..5a7cc45b5 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i128.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i128.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn add(a: i128, b: i128) -> i128 { a + b }\n    pub fn su
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -44,9 +45,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i128>::name" = private unnamed_addr constant [11 x i8] c"core::i128\00"
-@"type_info::<core::i128>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\BDkp\09RRM\EBc\02\A0\DB47\A7\E3", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::i128>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i128>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\BDkp\09RRM\EBc\02\A0\DB47\A7\E3", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::i128>::name", i32 0, i32 0), [48 x i8] c"\80\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i128>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i16.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i16.snap
index e4b82eaa0..d2c7342b6 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i16.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i16.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn add(a: i16, b: i16) -> i16 { a + b }\n    pub fn subtr
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -44,9 +45,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i16>::name" = private unnamed_addr constant [10 x i8] c"core::i16\00"
-@"type_info::<core::i16>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\05\CD|\F8Bv\D8\B1\E8\8B\8C\D8\8D\B5\89\B0", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i16>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 16, [0 x i64] zeroinitializer, i8 2, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i16>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\05\CD|\F8Bv\D8\B1\E8\8B\8C\D8\8D\B5\89\B0", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i16>::name", i32 0, i32 0), [48 x i8] c"\10\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i16>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i32.snap
index 8ba8dd7f7..9b5d3fed4 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn add(a: i32, b: i32) -> i32 { a + b }\n    pub fn subtr
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -44,9 +45,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i64.snap
index b6a185f64..70ce78009 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn add(a: i64, b: i64) -> i64 { a + b }\n    pub fn subtr
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -44,9 +45,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i64>::name" = private unnamed_addr constant [10 x i8] c"core::i64\00"
-@"type_info::<core::i64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i8.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i8.snap
index 71b820a23..c06dd3f0c 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i8.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_i8.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn add(a: i8, b: i8) -> i8 { a + b }\n    pub fn subtract
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -44,9 +45,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i8>::name" = private unnamed_addr constant [9 x i8] c"core::i8\00"
-@"type_info::<core::i8>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\EF\C4\B1Z\E7\12\B1\91q\F1\0B\80U\FC\A6\0F", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::i8>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 8, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i8>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\EF\C4\B1Z\E7\12\B1\91q\F1\0B\80U\FC\A6\0F", i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::i8>::name", i32 0, i32 0), [48 x i8] c"\08\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i8>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u128.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u128.snap
index 5e6ad2ce5..dbc51720f 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u128.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u128.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn add(a: u128, b: u128) -> u128 { a + b }\n    pub fn su
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -44,9 +45,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u128>::name" = private unnamed_addr constant [11 x i8] c"core::u128\00"
-@"type_info::<core::u128>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\E67\1BU\E9k\95\93d\14}\1C\96S\95\F0", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::u128>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u128>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\E67\1BU\E9k\95\93d\14}\1C\96S\95\F0", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::u128>::name", i32 0, i32 0), [48 x i8] c"\80\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u128>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u16.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u16.snap
index ffab42d45..9bf7372bc 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u16.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u16.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn add(a: u16, b: u16) -> u16 { a + b }\n    pub fn subtr
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -44,9 +45,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u16>::name" = private unnamed_addr constant [10 x i8] c"core::u16\00"
-@"type_info::<core::u16>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"0\01\BC\BBK\E0\F2\7F&l\01\CD|q\F2\B3", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u16>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 16, [0 x i64] zeroinitializer, i8 2, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u16>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"0\01\BC\BBK\E0\F2\7F&l\01\CD|q\F2\B3", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u16>::name", i32 0, i32 0), [48 x i8] c"\10\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u16>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u32.snap
index dfc34dc6c..48abfe5bd 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn add(a: u32, b: u32) -> u32 { a + b }\n    pub fn subtr
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -44,9 +45,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u32>::name" = private unnamed_addr constant [10 x i8] c"core::u32\00"
-@"type_info::<core::u32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"daz5d\A6\BE\88\81=&Y\A1+\C6\1D", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"daz5d\A6\BE\88\81=&Y\A1+\C6\1D", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u64.snap
index 7505979e1..656a8fc02 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn add(a: u64, b: u64) -> u64 { a + b }\n    pub fn subtr
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -44,9 +45,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u64>::name" = private unnamed_addr constant [10 x i8] c"core::u64\00"
-@"type_info::<core::u64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u8.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u8.snap
index 2ad508fc7..feb4568a8 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u8.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__arithmetic_op_u8.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn add(a: u8, b: u8) -> u8 { a + b }\n    pub fn subtract
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -44,9 +45,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u8>::name" = private unnamed_addr constant [9 x i8] c"core::u8\00"
-@"type_info::<core::u8>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\A0y\A7S\B6(n\F7f&H\E1\F9\AD\04>", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::u8>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 8, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u8>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\A0y\A7S\B6(n\F7f&H\E1\F9\AD\04>", i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::u8>::name", i32 0, i32 0), [48 x i8] c"\08\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u8>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_bool.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_bool.snap
index 50c41a54a..66cdf8a2a 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_bool.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_bool.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_bitand(a: bool, b: bool) -> bool {\n        a &
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -32,9 +33,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i128.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i128.snap
index 322df115b..8c134bd33 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i128.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i128.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_bitand(a: i128, b: i128) -> i128 {\n        a &
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -32,9 +33,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i128>::name" = private unnamed_addr constant [11 x i8] c"core::i128\00"
-@"type_info::<core::i128>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\BDkp\09RRM\EBc\02\A0\DB47\A7\E3", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::i128>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i128>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\BDkp\09RRM\EBc\02\A0\DB47\A7\E3", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::i128>::name", i32 0, i32 0), [48 x i8] c"\80\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i128>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i16.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i16.snap
index 5095c050f..dc074f773 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i16.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i16.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_bitand(a: i16, b: i16) -> i16 {\n        a &= b
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -32,9 +33,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i16>::name" = private unnamed_addr constant [10 x i8] c"core::i16\00"
-@"type_info::<core::i16>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\05\CD|\F8Bv\D8\B1\E8\8B\8C\D8\8D\B5\89\B0", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i16>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 16, [0 x i64] zeroinitializer, i8 2, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i16>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\05\CD|\F8Bv\D8\B1\E8\8B\8C\D8\8D\B5\89\B0", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i16>::name", i32 0, i32 0), [48 x i8] c"\10\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i16>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i32.snap
index 73478976b..5b7012ee6 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_bitand(a: i32, b: i32) -> i32 {\n        a &= b
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -32,9 +33,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i64.snap
index 0885214f3..6a3a3b2f8 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_bitand(a: i64, b: i64) -> i64 {\n        a &= b
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -32,9 +33,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i64>::name" = private unnamed_addr constant [10 x i8] c"core::i64\00"
-@"type_info::<core::i64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i8.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i8.snap
index 7a12a9d0c..8fda48c76 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i8.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_i8.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_bitand(a: i8, b: i8) -> i8 {\n        a &= b;\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -32,9 +33,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i8>::name" = private unnamed_addr constant [9 x i8] c"core::i8\00"
-@"type_info::<core::i8>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\EF\C4\B1Z\E7\12\B1\91q\F1\0B\80U\FC\A6\0F", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::i8>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 8, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i8>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\EF\C4\B1Z\E7\12\B1\91q\F1\0B\80U\FC\A6\0F", i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::i8>::name", i32 0, i32 0), [48 x i8] c"\08\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i8>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u128.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u128.snap
index f7a92de2a..e7ac8f73c 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u128.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u128.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_bitand(a: u128, b: u128) -> u128 {\n        a &
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -32,9 +33,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u128>::name" = private unnamed_addr constant [11 x i8] c"core::u128\00"
-@"type_info::<core::u128>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\E67\1BU\E9k\95\93d\14}\1C\96S\95\F0", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::u128>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u128>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\E67\1BU\E9k\95\93d\14}\1C\96S\95\F0", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::u128>::name", i32 0, i32 0), [48 x i8] c"\80\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u128>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u16.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u16.snap
index 1ca489d99..d342d4c96 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u16.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u16.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_bitand(a: u16, b: u16) -> u16 {\n        a &= b
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -32,9 +33,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u16>::name" = private unnamed_addr constant [10 x i8] c"core::u16\00"
-@"type_info::<core::u16>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"0\01\BC\BBK\E0\F2\7F&l\01\CD|q\F2\B3", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u16>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 16, [0 x i64] zeroinitializer, i8 2, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u16>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"0\01\BC\BBK\E0\F2\7F&l\01\CD|q\F2\B3", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u16>::name", i32 0, i32 0), [48 x i8] c"\10\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u16>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u32.snap
index df63fab43..ef59eaa69 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_bitand(a: u32, b: u32) -> u32 {\n        a &= b
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -32,9 +33,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u32>::name" = private unnamed_addr constant [10 x i8] c"core::u32\00"
-@"type_info::<core::u32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"daz5d\A6\BE\88\81=&Y\A1+\C6\1D", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"daz5d\A6\BE\88\81=&Y\A1+\C6\1D", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u64.snap
index 0a004b113..b768f2a10 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_bitand(a: u64, b: u64) -> u64 {\n        a &= b
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -32,9 +33,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u64>::name" = private unnamed_addr constant [10 x i8] c"core::u64\00"
-@"type_info::<core::u64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u8.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u8.snap
index 75fa8b43e..6b93fbfea 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u8.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_bit_op_u8.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_bitand(a: u8, b: u8) -> u8 {\n        a &= b;\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -32,9 +33,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u8>::name" = private unnamed_addr constant [9 x i8] c"core::u8\00"
-@"type_info::<core::u8>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\A0y\A7S\B6(n\F7f&H\E1\F9\AD\04>", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::u8>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 8, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u8>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\A0y\A7S\B6(n\F7f&H\E1\F9\AD\04>", i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::u8>::name", i32 0, i32 0), [48 x i8] c"\08\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u8>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i128.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i128.snap
index 85d008ef8..34afb9b15 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i128.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i128.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_leftshift(a: i128, b: i128) -> i128 {\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i128>::name" = private unnamed_addr constant [11 x i8] c"core::i128\00"
-@"type_info::<core::i128>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\BDkp\09RRM\EBc\02\A0\DB47\A7\E3", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::i128>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i128>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\BDkp\09RRM\EBc\02\A0\DB47\A7\E3", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::i128>::name", i32 0, i32 0), [48 x i8] c"\80\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i128>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i16.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i16.snap
index feca4f22f..778c7275f 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i16.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i16.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_leftshift(a: i16, b: i16) -> i16 {\n        a <
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i16>::name" = private unnamed_addr constant [10 x i8] c"core::i16\00"
-@"type_info::<core::i16>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\05\CD|\F8Bv\D8\B1\E8\8B\8C\D8\8D\B5\89\B0", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i16>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 16, [0 x i64] zeroinitializer, i8 2, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i16>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\05\CD|\F8Bv\D8\B1\E8\8B\8C\D8\8D\B5\89\B0", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i16>::name", i32 0, i32 0), [48 x i8] c"\10\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i16>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i32.snap
index 850f915ad..155e30366 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_leftshift(a: i32, b: i32) -> i32 {\n        a <
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i64.snap
index 72037248a..eb5cf4cc8 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_leftshift(a: i64, b: i64) -> i64 {\n        a <
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i64>::name" = private unnamed_addr constant [10 x i8] c"core::i64\00"
-@"type_info::<core::i64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i8.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i8.snap
index 1d91e8577..3487f9106 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i8.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_i8.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_leftshift(a: i8, b: i8) -> i8 {\n        a <<=
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i8>::name" = private unnamed_addr constant [9 x i8] c"core::i8\00"
-@"type_info::<core::i8>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\EF\C4\B1Z\E7\12\B1\91q\F1\0B\80U\FC\A6\0F", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::i8>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 8, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i8>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\EF\C4\B1Z\E7\12\B1\91q\F1\0B\80U\FC\A6\0F", i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::i8>::name", i32 0, i32 0), [48 x i8] c"\08\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i8>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u128.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u128.snap
index b76ad7f55..f0e690a50 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u128.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u128.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_leftshift(a: u128, b: u128) -> u128 {\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u128>::name" = private unnamed_addr constant [11 x i8] c"core::u128\00"
-@"type_info::<core::u128>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\E67\1BU\E9k\95\93d\14}\1C\96S\95\F0", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::u128>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u128>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\E67\1BU\E9k\95\93d\14}\1C\96S\95\F0", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::u128>::name", i32 0, i32 0), [48 x i8] c"\80\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u128>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u16.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u16.snap
index 2db4fb88d..455d45840 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u16.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u16.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_leftshift(a: u16, b: u16) -> u16 {\n        a <
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u16>::name" = private unnamed_addr constant [10 x i8] c"core::u16\00"
-@"type_info::<core::u16>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"0\01\BC\BBK\E0\F2\7F&l\01\CD|q\F2\B3", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u16>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 16, [0 x i64] zeroinitializer, i8 2, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u16>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"0\01\BC\BBK\E0\F2\7F&l\01\CD|q\F2\B3", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u16>::name", i32 0, i32 0), [48 x i8] c"\10\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u16>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u32.snap
index 330cbe86b..aa74b1734 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_leftshift(a: u32, b: u32) -> u32 {\n        a <
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u32>::name" = private unnamed_addr constant [10 x i8] c"core::u32\00"
-@"type_info::<core::u32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"daz5d\A6\BE\88\81=&Y\A1+\C6\1D", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"daz5d\A6\BE\88\81=&Y\A1+\C6\1D", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u64.snap
index 421507608..23b8563f4 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_leftshift(a: u64, b: u64) -> u64 {\n        a <
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u64>::name" = private unnamed_addr constant [10 x i8] c"core::u64\00"
-@"type_info::<core::u64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u8.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u8.snap
index 07d49e8cf..78364efa7 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u8.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assign_shift_op_u8.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign_leftshift(a: u8, b: u8) -> u8 {\n        a <<=
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u8>::name" = private unnamed_addr constant [9 x i8] c"core::u8\00"
-@"type_info::<core::u8>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\A0y\A7S\B6(n\F7f&H\E1\F9\AD\04>", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::u8>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 8, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u8>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\A0y\A7S\B6(n\F7f&H\E1\F9\AD\04>", i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::u8>::name", i32 0, i32 0), [48 x i8] c"\08\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u8>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_bool.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_bool.snap
index 96d05fb7e..134a28bfe 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_bool.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_bool.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign(a: bool, b: bool) -> bool {\n        a = b;\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -19,9 +20,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_f32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_f32.snap
index 4cd39516e..4af2692bd 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_f32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_f32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign(a: f32, b: f32) -> f32 {\n        a = b;\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -49,9 +50,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::f32>::name" = private unnamed_addr constant [10 x i8] c"core::f32\00"
-@"type_info::<core::f32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"P\19b7\A8k\F2\81P\FB\83\F5P\B0\82!", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::f32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"P\19b7\A8k\F2\81P\FB\83\F5P\B0\82!", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_f64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_f64.snap
index c0109fc70..c9a6e5b2e 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_f64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_f64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign(a: f64, b: f64) -> f64 {\n        a = b;\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -49,9 +50,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::f64>::name" = private unnamed_addr constant [10 x i8] c"core::f64\00"
-@"type_info::<core::f64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::f64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i128.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i128.snap
index 0ae22bd5e..05d8133e3 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i128.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i128.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign(a: i128, b: i128) -> i128 {\n        a = b;\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -49,9 +50,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i128>::name" = private unnamed_addr constant [11 x i8] c"core::i128\00"
-@"type_info::<core::i128>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\BDkp\09RRM\EBc\02\A0\DB47\A7\E3", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::i128>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i128>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\BDkp\09RRM\EBc\02\A0\DB47\A7\E3", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::i128>::name", i32 0, i32 0), [48 x i8] c"\80\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i128>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i16.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i16.snap
index 14ad8c446..f20dcd391 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i16.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i16.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign(a: i16, b: i16) -> i16 {\n        a = b;\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -49,9 +50,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i16>::name" = private unnamed_addr constant [10 x i8] c"core::i16\00"
-@"type_info::<core::i16>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\05\CD|\F8Bv\D8\B1\E8\8B\8C\D8\8D\B5\89\B0", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i16>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 16, [0 x i64] zeroinitializer, i8 2, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i16>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\05\CD|\F8Bv\D8\B1\E8\8B\8C\D8\8D\B5\89\B0", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i16>::name", i32 0, i32 0), [48 x i8] c"\10\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i16>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i32.snap
index 67ec46b8a..a3f14625b 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign(a: i32, b: i32) -> i32 {\n        a = b;\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -49,9 +50,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i64.snap
index 2dc69aef1..a08728fdf 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign(a: i64, b: i64) -> i64 {\n        a = b;\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -49,9 +50,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i64>::name" = private unnamed_addr constant [10 x i8] c"core::i64\00"
-@"type_info::<core::i64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i8.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i8.snap
index 710888a48..6e0d77789 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i8.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_i8.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign(a: i8, b: i8) -> i8 {\n        a = b;\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -49,9 +50,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i8>::name" = private unnamed_addr constant [9 x i8] c"core::i8\00"
-@"type_info::<core::i8>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\EF\C4\B1Z\E7\12\B1\91q\F1\0B\80U\FC\A6\0F", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::i8>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 8, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i8>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\EF\C4\B1Z\E7\12\B1\91q\F1\0B\80U\FC\A6\0F", i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::i8>::name", i32 0, i32 0), [48 x i8] c"\08\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i8>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_struct.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_struct.snap
index 0e7b15e83..20ede238c 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_struct.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_struct.snap
@@ -7,7 +7,8 @@ expression: "\n    struct(value) Value(i32, i32);\n    struct(gc) Heap(f64, f64)
 source_filename = "mod"
 
 %DispatchTable = type { i8** (i8*, i8*)* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 %Value = type { i32, i32 }
 %Heap = type { double, double }
 
@@ -50,34 +51,34 @@ body:
 source_filename = "group_name"
 
 %DispatchTable = type { i8** (i8*, i8*)* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
-%"mun_codegen::ir::types::StructInfo" = type <{ [0 x i64], i8**, [0 x i64], %"mun_codegen::ir::types::TypeInfo"**, [0 x i64], i16*, [0 x i64], i16, [0 x i64], i8, [5 x i8] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @dispatchTable = global %DispatchTable zeroinitializer
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<Value>::name" = private unnamed_addr constant [6 x i8] c"Value\00"
 @"struct_info::<Value>::field_names.0" = private unnamed_addr constant [2 x i8] c"0\00"
 @"struct_info::<Value>::field_names.1" = private unnamed_addr constant [2 x i8] c"1\00"
 @"struct_info::<Value>::field_names" = private unnamed_addr constant [2 x i8*] [i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<Value>::field_names.0", i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<Value>::field_names.1", i32 0, i32 0)]
 @"struct_info::<Value>::field_types" = private unnamed_addr constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 @"struct_info::<Value>::field_offsets" = private unnamed_addr constant [2 x i16] [i16 0, i16 4]
-@"type_info::<Value>" = private unnamed_addr constant { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" } { %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"(3\1C%q\83\13+L\A6Q\F7\1DX\A6\9B", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @"type_info::<Value>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 1, [1 x i16] zeroinitializer }>, %"mun_codegen::ir::types::StructInfo" <{ [0 x i64] zeroinitializer, i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @"struct_info::<Value>::field_names", i32 0, i32 0), [0 x i64] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([2 x %"mun_codegen::ir::types::TypeInfo"*], [2 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<Value>::field_types", i32 0, i32 0), [0 x i64] zeroinitializer, i16* getelementptr inbounds ([2 x i16], [2 x i16]* @"struct_info::<Value>::field_offsets", i32 0, i32 0), [0 x i64] zeroinitializer, i16 2, [0 x i64] zeroinitializer, i8 1, [5 x i8] zeroinitializer }> }
+@"type_info::<Value>" = private unnamed_addr constant <{ [16 x i8], i8*, [16 x i8], i8**, [0 x i8], %"mun_codegen::ir::types::TypeInfo"**, [0 x i8], i16*, [8 x i8] }> <{ [16 x i8] c"(3\1C%q\83\13+L\A6Q\F7\1DX\A6\9B", i8* getelementptr inbounds ([6 x i8], [6 x i8]* @"type_info::<Value>::name", i32 0, i32 0), [16 x i8] c"@\00\00\00\04\00\00\00\01\00\00\00\00\00\00\00", i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @"struct_info::<Value>::field_names", i32 0, i32 0), [0 x i8] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([2 x %"mun_codegen::ir::types::TypeInfo"*], [2 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<Value>::field_types", i32 0, i32 0), [0 x i8] zeroinitializer, i16* getelementptr inbounds ([2 x i16], [2 x i16]* @"struct_info::<Value>::field_offsets", i32 0, i32 0), [8 x i8] c"\02\00\01\00\00\00\00\00" }>
 @"type_info::<Heap>::name" = private unnamed_addr constant [5 x i8] c"Heap\00"
 @"struct_info::<Heap>::field_names.0" = private unnamed_addr constant [2 x i8] c"0\00"
 @"struct_info::<Heap>::field_names.1" = private unnamed_addr constant [2 x i8] c"1\00"
 @"struct_info::<Heap>::field_names" = private unnamed_addr constant [2 x i8*] [i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<Heap>::field_names.0", i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<Heap>::field_names.1", i32 0, i32 0)]
 @"type_info::<core::f64>::name" = private unnamed_addr constant [10 x i8] c"core::f64\00"
-@"type_info::<core::f64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::f64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"struct_info::<Heap>::field_types" = private unnamed_addr constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f64>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f64>"]
 @"struct_info::<Heap>::field_offsets" = private unnamed_addr constant [2 x i16] [i16 0, i16 8]
-@"type_info::<Heap>" = private unnamed_addr constant { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" } { %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"1\1CC\F80{\17\AFq\94\89\FB4\AC\A8\F3", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"type_info::<Heap>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 1, [1 x i16] zeroinitializer }>, %"mun_codegen::ir::types::StructInfo" <{ [0 x i64] zeroinitializer, i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @"struct_info::<Heap>::field_names", i32 0, i32 0), [0 x i64] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([2 x %"mun_codegen::ir::types::TypeInfo"*], [2 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<Heap>::field_types", i32 0, i32 0), [0 x i64] zeroinitializer, i16* getelementptr inbounds ([2 x i16], [2 x i16]* @"struct_info::<Heap>::field_offsets", i32 0, i32 0), [0 x i64] zeroinitializer, i16 2, [0 x i64] zeroinitializer, i8 0, [5 x i8] zeroinitializer }> }
+@"type_info::<Heap>" = private unnamed_addr constant <{ [16 x i8], i8*, [16 x i8], i8**, [0 x i8], %"mun_codegen::ir::types::TypeInfo"**, [0 x i8], i16*, [8 x i8] }> <{ [16 x i8] c"1\1CC\F80{\17\AFq\94\89\FB4\AC\A8\F3", i8* getelementptr inbounds ([5 x i8], [5 x i8]* @"type_info::<Heap>::name", i32 0, i32 0), [16 x i8] c"\80\00\00\00\08\00\00\00\01\00\00\00\00\00\00\00", i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @"struct_info::<Heap>::field_names", i32 0, i32 0), [0 x i8] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([2 x %"mun_codegen::ir::types::TypeInfo"*], [2 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<Heap>::field_types", i32 0, i32 0), [0 x i8] zeroinitializer, i16* getelementptr inbounds ([2 x i16], [2 x i16]* @"struct_info::<Heap>::field_offsets", i32 0, i32 0), [8 x i8] c"\02\00\00\00\00\00\00\00" }>
 @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00"
-@"type_info::<*const TypeInfo>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*const TypeInfo>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<*const TypeInfo>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*const TypeInfo>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00"
-@"type_info::<*const *mut core::void>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @"type_info::<*const *mut core::void>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<*const *mut core::void>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", i8* getelementptr inbounds ([23 x i8], [23 x i8]* @"type_info::<*const *mut core::void>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00"
-@"type_info::<*mut core::void>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*mut core::void>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
-@global_type_table = constant [7 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>", %"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<Value>", i32 0, i32 0), %"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<Heap>", i32 0, i32 0), %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const TypeInfo>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f64>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const *mut core::void>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*mut core::void>"]
+@"type_info::<*mut core::void>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*mut core::void>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
+@global_type_table = constant [7 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<Value>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<Heap>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const TypeInfo>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f64>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const *mut core::void>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*mut core::void>"]
 @allocatorHandle = unnamed_addr global i8* null
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u128.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u128.snap
index e55d64998..5852c7862 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u128.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u128.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign(a: u128, b: u128) -> u128 {\n        a = b;\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -49,9 +50,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u128>::name" = private unnamed_addr constant [11 x i8] c"core::u128\00"
-@"type_info::<core::u128>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\E67\1BU\E9k\95\93d\14}\1C\96S\95\F0", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::u128>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u128>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\E67\1BU\E9k\95\93d\14}\1C\96S\95\F0", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::u128>::name", i32 0, i32 0), [48 x i8] c"\80\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u128>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u16.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u16.snap
index 1925bd7b8..4779537a7 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u16.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u16.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign(a: u16, b: u16) -> u16 {\n        a = b;\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -49,9 +50,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u16>::name" = private unnamed_addr constant [10 x i8] c"core::u16\00"
-@"type_info::<core::u16>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"0\01\BC\BBK\E0\F2\7F&l\01\CD|q\F2\B3", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u16>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 16, [0 x i64] zeroinitializer, i8 2, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u16>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"0\01\BC\BBK\E0\F2\7F&l\01\CD|q\F2\B3", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u16>::name", i32 0, i32 0), [48 x i8] c"\10\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u16>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u32.snap
index 9de008514..58088f9af 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign(a: u32, b: u32) -> u32 {\n        a = b;\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -49,9 +50,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u32>::name" = private unnamed_addr constant [10 x i8] c"core::u32\00"
-@"type_info::<core::u32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"daz5d\A6\BE\88\81=&Y\A1+\C6\1D", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"daz5d\A6\BE\88\81=&Y\A1+\C6\1D", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u64.snap
index 5dd8795c5..f640e97b9 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign(a: u64, b: u64) -> u64 {\n        a = b;\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -49,9 +50,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u64>::name" = private unnamed_addr constant [10 x i8] c"core::u64\00"
-@"type_info::<core::u64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u8.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u8.snap
index 5b75b8a34..a750559a0 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u8.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__assignment_op_u8.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn assign(a: u8, b: u8) -> u8 {\n        a = b;\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -49,9 +50,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u8>::name" = private unnamed_addr constant [9 x i8] c"core::u8\00"
-@"type_info::<core::u8>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\A0y\A7S\B6(n\F7f&H\E1\F9\AD\04>", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::u8>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 8, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u8>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\A0y\A7S\B6(n\F7f&H\E1\F9\AD\04>", i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::u8>::name", i32 0, i32 0), [48 x i8] c"\08\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u8>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_bool.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_bool.snap
index c9d342981..1d0506bca 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_bool.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_bool.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn not(a: bool) -> bool { !a }\n    pub fn bitand(a: bool
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -38,9 +39,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i128.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i128.snap
index a2d59e1e8..8ae24c7a1 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i128.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i128.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn not(a: i128) -> i128 { !a }\n    pub fn bitand(a: i128
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -38,9 +39,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i128>::name" = private unnamed_addr constant [11 x i8] c"core::i128\00"
-@"type_info::<core::i128>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\BDkp\09RRM\EBc\02\A0\DB47\A7\E3", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::i128>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i128>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\BDkp\09RRM\EBc\02\A0\DB47\A7\E3", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::i128>::name", i32 0, i32 0), [48 x i8] c"\80\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i128>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i16.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i16.snap
index 80c3c155d..bc42c7422 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i16.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i16.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn not(a: i16) -> i16 { !a }\n    pub fn bitand(a: i16, b
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -38,9 +39,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i16>::name" = private unnamed_addr constant [10 x i8] c"core::i16\00"
-@"type_info::<core::i16>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\05\CD|\F8Bv\D8\B1\E8\8B\8C\D8\8D\B5\89\B0", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i16>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 16, [0 x i64] zeroinitializer, i8 2, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i16>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\05\CD|\F8Bv\D8\B1\E8\8B\8C\D8\8D\B5\89\B0", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i16>::name", i32 0, i32 0), [48 x i8] c"\10\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i16>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i32.snap
index 1fe8a311c..054520638 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn not(a: i32) -> i32 { !a }\n    pub fn bitand(a: i32, b
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -38,9 +39,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i64.snap
index 991fc5b47..4acd21ea4 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn not(a: i64) -> i64 { !a }\n    pub fn bitand(a: i64, b
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -38,9 +39,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i64>::name" = private unnamed_addr constant [10 x i8] c"core::i64\00"
-@"type_info::<core::i64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i8.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i8.snap
index b2eeb8609..c4b9028e3 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i8.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_i8.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn not(a: i8) -> i8 { !a }\n    pub fn bitand(a: i8, b: i
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -38,9 +39,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i8>::name" = private unnamed_addr constant [9 x i8] c"core::i8\00"
-@"type_info::<core::i8>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\EF\C4\B1Z\E7\12\B1\91q\F1\0B\80U\FC\A6\0F", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::i8>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 8, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i8>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\EF\C4\B1Z\E7\12\B1\91q\F1\0B\80U\FC\A6\0F", i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::i8>::name", i32 0, i32 0), [48 x i8] c"\08\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i8>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u128.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u128.snap
index 449d34d38..6a538e4bf 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u128.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u128.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn not(a: u128) -> u128 { !a }\n    pub fn bitand(a: u128
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -38,9 +39,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u128>::name" = private unnamed_addr constant [11 x i8] c"core::u128\00"
-@"type_info::<core::u128>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\E67\1BU\E9k\95\93d\14}\1C\96S\95\F0", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::u128>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u128>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\E67\1BU\E9k\95\93d\14}\1C\96S\95\F0", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::u128>::name", i32 0, i32 0), [48 x i8] c"\80\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u128>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u16.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u16.snap
index 9c300d9cf..e67f87e2f 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u16.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u16.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn not(a: u16) -> u16 { !a }\n    pub fn bitand(a: u16, b
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -38,9 +39,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u16>::name" = private unnamed_addr constant [10 x i8] c"core::u16\00"
-@"type_info::<core::u16>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"0\01\BC\BBK\E0\F2\7F&l\01\CD|q\F2\B3", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u16>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 16, [0 x i64] zeroinitializer, i8 2, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u16>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"0\01\BC\BBK\E0\F2\7F&l\01\CD|q\F2\B3", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u16>::name", i32 0, i32 0), [48 x i8] c"\10\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u16>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u32.snap
index d5860e65d..8959581ad 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn not(a: u32) -> u32 { !a }\n    pub fn bitand(a: u32, b
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -38,9 +39,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u32>::name" = private unnamed_addr constant [10 x i8] c"core::u32\00"
-@"type_info::<core::u32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"daz5d\A6\BE\88\81=&Y\A1+\C6\1D", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"daz5d\A6\BE\88\81=&Y\A1+\C6\1D", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u64.snap
index fb0fabccd..1fc3b7a7b 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn not(a: u64) -> u64 { !a }\n    pub fn bitand(a: u64, b
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -38,9 +39,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u64>::name" = private unnamed_addr constant [10 x i8] c"core::u64\00"
-@"type_info::<core::u64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u8.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u8.snap
index 458db5cd8..82addc6ed 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u8.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__bit_op_u8.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn not(a: u8) -> u8 { !a }\n    pub fn bitand(a: u8, b: u
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -38,9 +39,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u8>::name" = private unnamed_addr constant [9 x i8] c"core::u8\00"
-@"type_info::<core::u8>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\A0y\A7S\B6(n\F7f&H\E1\F9\AD\04>", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::u8>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 8, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u8>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\A0y\A7S\B6(n\F7f&H\E1\F9\AD\04>", i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::u8>::name", i32 0, i32 0), [48 x i8] c"\08\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u8>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_bool.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_bool.snap
index 22db72fa8..025c79ce5 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_bool.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_bool.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn equals(a: bool, b: bool) -> bool { a == b }\n    pub f
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -50,9 +51,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_f32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_f32.snap
index ca5a449c7..f9154fe9f 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_f32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_f32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn equals(a: f32, b: f32) -> bool { a == b }\n    pub fn
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [2 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -50,11 +51,12 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::f32>::name" = private unnamed_addr constant [10 x i8] c"core::f32\00"
-@"type_info::<core::f32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"P\19b7\A8k\F2\81P\FB\83\F5P\B0\82!", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::f32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"P\19b7\A8k\F2\81P\FB\83\F5P\B0\82!", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f32>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_f64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_f64.snap
index 0456ee88b..6dfe986f6 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_f64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_f64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn equals(a: f64, b: f64) -> bool { a == b }\n    pub fn
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [2 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -50,11 +51,12 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::f64>::name" = private unnamed_addr constant [10 x i8] c"core::f64\00"
-@"type_info::<core::f64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::f64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f64>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i128.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i128.snap
index c7a89c5f6..95efe54ee 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i128.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i128.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn equals(a: i128, b: i128) -> bool { a == b }\n    pub f
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [2 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -50,11 +51,12 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<core::i128>::name" = private unnamed_addr constant [11 x i8] c"core::i128\00"
-@"type_info::<core::i128>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\BDkp\09RRM\EBc\02\A0\DB47\A7\E3", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::i128>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i128>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\BDkp\09RRM\EBc\02\A0\DB47\A7\E3", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::i128>::name", i32 0, i32 0), [48 x i8] c"\80\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i128>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i16.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i16.snap
index 8a26428ed..6cef06814 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i16.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i16.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn equals(a: i16, b: i16) -> bool { a == b }\n    pub fn
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [2 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -50,11 +51,12 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i16>::name" = private unnamed_addr constant [10 x i8] c"core::i16\00"
-@"type_info::<core::i16>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\05\CD|\F8Bv\D8\B1\E8\8B\8C\D8\8D\B5\89\B0", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i16>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 16, [0 x i64] zeroinitializer, i8 2, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i16>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\05\CD|\F8Bv\D8\B1\E8\8B\8C\D8\8D\B5\89\B0", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i16>::name", i32 0, i32 0), [48 x i8] c"\10\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i16>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i32.snap
index e714bd92e..3e083e23b 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn equals(a: i32, b: i32) -> bool { a == b }\n    pub fn
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [2 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -50,11 +51,12 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i64.snap
index 744a66af7..66c206165 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn equals(a: i64, b: i64) -> bool { a == b }\n    pub fn
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [2 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -50,11 +51,12 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i64>::name" = private unnamed_addr constant [10 x i8] c"core::i64\00"
-@"type_info::<core::i64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i64>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i8.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i8.snap
index 16a83c635..d86c7756f 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i8.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_i8.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn equals(a: i8, b: i8) -> bool { a == b }\n    pub fn no
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [2 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -50,11 +51,12 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<core::i8>::name" = private unnamed_addr constant [9 x i8] c"core::i8\00"
-@"type_info::<core::i8>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\EF\C4\B1Z\E7\12\B1\91q\F1\0B\80U\FC\A6\0F", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::i8>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 8, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i8>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\EF\C4\B1Z\E7\12\B1\91q\F1\0B\80U\FC\A6\0F", i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::i8>::name", i32 0, i32 0), [48 x i8] c"\08\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i8>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u128.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u128.snap
index 8e966ad33..385c1fbf5 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u128.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u128.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn equals(a: u128, b: u128) -> bool { a == b }\n    pub f
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [2 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -50,11 +51,12 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<core::u128>::name" = private unnamed_addr constant [11 x i8] c"core::u128\00"
-@"type_info::<core::u128>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\E67\1BU\E9k\95\93d\14}\1C\96S\95\F0", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::u128>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u128>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\E67\1BU\E9k\95\93d\14}\1C\96S\95\F0", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::u128>::name", i32 0, i32 0), [48 x i8] c"\80\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u128>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u16.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u16.snap
index 85293a477..0ce20c8f5 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u16.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u16.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn equals(a: u16, b: u16) -> bool { a == b }\n    pub fn
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [2 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -50,11 +51,12 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u16>::name" = private unnamed_addr constant [10 x i8] c"core::u16\00"
-@"type_info::<core::u16>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"0\01\BC\BBK\E0\F2\7F&l\01\CD|q\F2\B3", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u16>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 16, [0 x i64] zeroinitializer, i8 2, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u16>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"0\01\BC\BBK\E0\F2\7F&l\01\CD|q\F2\B3", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u16>::name", i32 0, i32 0), [48 x i8] c"\10\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u16>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u32.snap
index 6e039579b..383e3615c 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn equals(a: u32, b: u32) -> bool { a == b }\n    pub fn
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [2 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -50,11 +51,12 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u32>::name" = private unnamed_addr constant [10 x i8] c"core::u32\00"
-@"type_info::<core::u32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"daz5d\A6\BE\88\81=&Y\A1+\C6\1D", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"daz5d\A6\BE\88\81=&Y\A1+\C6\1D", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u32>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u64.snap
index 52f5dd562..be749b742 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn equals(a: u64, b: u64) -> bool { a == b }\n    pub fn
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [2 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -50,11 +51,12 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<core::u64>::name" = private unnamed_addr constant [10 x i8] c"core::u64\00"
-@"type_info::<core::u64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u8.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u8.snap
index 069878da1..d049d20c4 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u8.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__compare_op_u8.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn equals(a: u8, b: u8) -> bool { a == b }\n    pub fn no
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [2 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -50,11 +51,12 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<core::u8>::name" = private unnamed_addr constant [9 x i8] c"core::u8\00"
-@"type_info::<core::u8>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\A0y\A7S\B6(n\F7f&H\E1\F9\AD\04>", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::u8>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 8, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u8>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\A0y\A7S\B6(n\F7f&H\E1\F9\AD\04>", i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::u8>::name", i32 0, i32 0), [48 x i8] c"\08\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u8>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__conditional_return_expr.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__conditional_return_expr.snap
index 20f4a00b5..23dc8da8b 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__conditional_return_expr.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__conditional_return_expr.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn main(a:i32) -> i32 {\n        if a > 4 {\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -27,9 +28,10 @@ if_merge:                                         ; preds = %body
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__extern_fn.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__extern_fn.snap
index aa2be3fcc..3aba53f09 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__extern_fn.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__extern_fn.snap
@@ -7,7 +7,8 @@ expression: "\n    extern fn add(a:i32, b:i32) -> i32;\n    pub fn main() {\n
 source_filename = "mod"
 
 %DispatchTable = type { i32 (i32, i32)* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @dispatchTable = external global %DispatchTable
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
@@ -24,10 +25,11 @@ body:
 source_filename = "group_name"
 
 %DispatchTable = type { i32 (i32, i32)* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @dispatchTable = global %DispatchTable zeroinitializer
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__fibonacci.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__fibonacci.snap
index f38202eca..b73d578df 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__fibonacci.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__fibonacci.snap
@@ -1,12 +1,14 @@
 ---
 source: crates/mun_codegen/src/test.rs
 expression: "\n    pub fn fibonacci(n:i32) -> i32 {\n        if n <= 1 {\n            n\n        } else {\n            fibonacci(n-1) + fibonacci(n-2)\n        }\n    }\n    "
+
 ---
 ; == FILE IR (mod) =====================================
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -32,9 +34,10 @@ if_merge:                                         ; preds = %body, %else
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__fibonacci_loop.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__fibonacci_loop.snap
index ba82773c2..1f3efb842 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__fibonacci_loop.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__fibonacci_loop.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn fibonacci(n:i32) -> i32 {\n        let a = 0;\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -34,9 +35,10 @@ if_merge:                                         ; preds = %loop
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__field_crash.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__field_crash.snap
index af2a85f2b..7b4236d71 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__field_crash.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__field_crash.snap
@@ -7,7 +7,8 @@ expression: "\n    struct(gc) Foo { a: i32 };\n\n    pub fn main(c:i32) -> i32 {
 source_filename = "mod"
 
 %DispatchTable = type { i8** (i8*, i8*)* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 %Foo = type { i32 }
 
 @allocatorHandle = external global i8*
@@ -43,24 +44,24 @@ body:
 source_filename = "group_name"
 
 %DispatchTable = type { i8** (i8*, i8*)* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
-%"mun_codegen::ir::types::StructInfo" = type <{ [0 x i64], i8**, [0 x i64], %"mun_codegen::ir::types::TypeInfo"**, [0 x i64], i16*, [0 x i64], i16, [0 x i64], i8, [5 x i8] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @dispatchTable = global %DispatchTable zeroinitializer
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<Foo>::name" = private unnamed_addr constant [4 x i8] c"Foo\00"
 @"struct_info::<Foo>::field_names.0" = private unnamed_addr constant [2 x i8] c"a\00"
 @"struct_info::<Foo>::field_names" = private unnamed_addr constant [1 x i8*] [i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<Foo>::field_names.0", i32 0, i32 0)]
 @"struct_info::<Foo>::field_types" = private unnamed_addr constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 @"struct_info::<Foo>::field_offsets" = private unnamed_addr constant [1 x i16] zeroinitializer
-@"type_info::<Foo>" = private unnamed_addr constant { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" } { %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"8\AD\C9\D9Y\D2\AA<ME}\CD.\A5\A0\DB", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"type_info::<Foo>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 1, [1 x i16] zeroinitializer }>, %"mun_codegen::ir::types::StructInfo" <{ [0 x i64] zeroinitializer, i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"struct_info::<Foo>::field_names", i32 0, i32 0), [0 x i64] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([1 x %"mun_codegen::ir::types::TypeInfo"*], [1 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<Foo>::field_types", i32 0, i32 0), [0 x i64] zeroinitializer, i16* getelementptr inbounds ([1 x i16], [1 x i16]* @"struct_info::<Foo>::field_offsets", i32 0, i32 0), [0 x i64] zeroinitializer, i16 1, [0 x i64] zeroinitializer, i8 0, [5 x i8] zeroinitializer }> }
+@"type_info::<Foo>" = private unnamed_addr constant <{ [16 x i8], i8*, [16 x i8], i8**, [0 x i8], %"mun_codegen::ir::types::TypeInfo"**, [0 x i8], i16*, [8 x i8] }> <{ [16 x i8] c"8\AD\C9\D9Y\D2\AA<ME}\CD.\A5\A0\DB", i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"type_info::<Foo>::name", i32 0, i32 0), [16 x i8] c" \00\00\00\04\00\00\00\01\00\00\00\00\00\00\00", i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"struct_info::<Foo>::field_names", i32 0, i32 0), [0 x i8] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([1 x %"mun_codegen::ir::types::TypeInfo"*], [1 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<Foo>::field_types", i32 0, i32 0), [0 x i8] zeroinitializer, i16* getelementptr inbounds ([1 x i16], [1 x i16]* @"struct_info::<Foo>::field_offsets", i32 0, i32 0), [8 x i8] c"\01\00\00\00\00\00\00\00" }>
 @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00"
-@"type_info::<*const TypeInfo>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*const TypeInfo>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<*const TypeInfo>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*const TypeInfo>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00"
-@"type_info::<*const *mut core::void>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @"type_info::<*const *mut core::void>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<*const *mut core::void>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", i8* getelementptr inbounds ([23 x i8], [23 x i8]* @"type_info::<*const *mut core::void>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00"
-@"type_info::<*mut core::void>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*mut core::void>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
-@global_type_table = constant [5 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>", %"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<Foo>", i32 0, i32 0), %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const TypeInfo>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const *mut core::void>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*mut core::void>"]
+@"type_info::<*mut core::void>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*mut core::void>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
+@global_type_table = constant [5 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<Foo>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const TypeInfo>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const *mut core::void>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*mut core::void>"]
 @allocatorHandle = unnamed_addr global i8* null
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__field_expr.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__field_expr.snap
index e003a2a5b..21a9328fe 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__field_expr.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__field_expr.snap
@@ -1,13 +1,15 @@
 ---
 source: crates/mun_codegen/src/test.rs
 expression: "\n    struct(value) Bar(f64, Foo);\n    struct(value) Foo { a: i32 };\n\n    fn bar_1(bar: Bar) -> Foo {\n        bar.1\n    }\n\n    fn foo_a(foo: Foo) -> i32 {\n        foo.a\n    }\n\n    pub fn bar_1_foo_a(bar: Bar) -> i32 {\n        foo_a(bar_1(bar))\n    }\n\n    pub fn main() -> i32 {\n        let a: Foo = Foo { a: 5 };\n        let b: Bar = Bar(1.23, a);\n        let aa_lhs = a.a + 2;\n        let aa_rhs = 2 + a.a;\n        aa_lhs + aa_rhs\n    }\n    "
+
 ---
 ; == FILE IR (mod) =====================================
 ; ModuleID = 'mod'
 source_filename = "mod"
 
 %DispatchTable = type { i8** (i8*, i8*)* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 %Foo = type { i32 }
 %Bar = type { double, %Foo }
 
@@ -55,33 +57,33 @@ body:
 source_filename = "group_name"
 
 %DispatchTable = type { i8** (i8*, i8*)* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
-%"mun_codegen::ir::types::StructInfo" = type <{ [0 x i64], i8**, [0 x i64], %"mun_codegen::ir::types::TypeInfo"**, [0 x i64], i16*, [0 x i64], i16, [0 x i64], i8, [5 x i8] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @dispatchTable = global %DispatchTable zeroinitializer
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<Foo>::name" = private unnamed_addr constant [4 x i8] c"Foo\00"
 @"struct_info::<Foo>::field_names.0" = private unnamed_addr constant [2 x i8] c"a\00"
 @"struct_info::<Foo>::field_names" = private unnamed_addr constant [1 x i8*] [i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<Foo>::field_names.0", i32 0, i32 0)]
 @"struct_info::<Foo>::field_types" = private unnamed_addr constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 @"struct_info::<Foo>::field_offsets" = private unnamed_addr constant [1 x i16] zeroinitializer
-@"type_info::<Foo>" = private unnamed_addr constant { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" } { %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"8\AD\C9\D9Y\D2\AA<ME}\CD.\A5\A0\DB", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"type_info::<Foo>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 1, [1 x i16] zeroinitializer }>, %"mun_codegen::ir::types::StructInfo" <{ [0 x i64] zeroinitializer, i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"struct_info::<Foo>::field_names", i32 0, i32 0), [0 x i64] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([1 x %"mun_codegen::ir::types::TypeInfo"*], [1 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<Foo>::field_types", i32 0, i32 0), [0 x i64] zeroinitializer, i16* getelementptr inbounds ([1 x i16], [1 x i16]* @"struct_info::<Foo>::field_offsets", i32 0, i32 0), [0 x i64] zeroinitializer, i16 1, [0 x i64] zeroinitializer, i8 1, [5 x i8] zeroinitializer }> }
+@"type_info::<Foo>" = private unnamed_addr constant <{ [16 x i8], i8*, [16 x i8], i8**, [0 x i8], %"mun_codegen::ir::types::TypeInfo"**, [0 x i8], i16*, [8 x i8] }> <{ [16 x i8] c"8\AD\C9\D9Y\D2\AA<ME}\CD.\A5\A0\DB", i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"type_info::<Foo>::name", i32 0, i32 0), [16 x i8] c" \00\00\00\04\00\00\00\01\00\00\00\00\00\00\00", i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"struct_info::<Foo>::field_names", i32 0, i32 0), [0 x i8] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([1 x %"mun_codegen::ir::types::TypeInfo"*], [1 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<Foo>::field_types", i32 0, i32 0), [0 x i8] zeroinitializer, i16* getelementptr inbounds ([1 x i16], [1 x i16]* @"struct_info::<Foo>::field_offsets", i32 0, i32 0), [8 x i8] c"\01\00\01\00\00\00\00\00" }>
 @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00"
-@"type_info::<*const TypeInfo>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*const TypeInfo>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<*const TypeInfo>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*const TypeInfo>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<core::f64>::name" = private unnamed_addr constant [10 x i8] c"core::f64\00"
-@"type_info::<core::f64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::f64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00"
-@"type_info::<*const *mut core::void>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @"type_info::<*const *mut core::void>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<*const *mut core::void>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", i8* getelementptr inbounds ([23 x i8], [23 x i8]* @"type_info::<*const *mut core::void>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00"
-@"type_info::<*mut core::void>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*mut core::void>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<*mut core::void>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*mut core::void>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<Bar>::name" = private unnamed_addr constant [4 x i8] c"Bar\00"
 @"struct_info::<Bar>::field_names.0" = private unnamed_addr constant [2 x i8] c"0\00"
 @"struct_info::<Bar>::field_names.1" = private unnamed_addr constant [2 x i8] c"1\00"
 @"struct_info::<Bar>::field_names" = private unnamed_addr constant [2 x i8*] [i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<Bar>::field_names.0", i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<Bar>::field_names.1", i32 0, i32 0)]
-@"struct_info::<Bar>::field_types" = private unnamed_addr constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f64>", %"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<Foo>", i32 0, i32 0)]
+@"struct_info::<Bar>::field_types" = private unnamed_addr constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f64>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<Foo>"]
 @"struct_info::<Bar>::field_offsets" = private unnamed_addr constant [2 x i16] [i16 0, i16 8]
-@"type_info::<Bar>" = private unnamed_addr constant { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" } { %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\FC8#Lvd)F\B1Q\06\8B\02pl\10", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"type_info::<Bar>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 1, [1 x i16] zeroinitializer }>, %"mun_codegen::ir::types::StructInfo" <{ [0 x i64] zeroinitializer, i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @"struct_info::<Bar>::field_names", i32 0, i32 0), [0 x i64] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([2 x %"mun_codegen::ir::types::TypeInfo"*], [2 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<Bar>::field_types", i32 0, i32 0), [0 x i64] zeroinitializer, i16* getelementptr inbounds ([2 x i16], [2 x i16]* @"struct_info::<Bar>::field_offsets", i32 0, i32 0), [0 x i64] zeroinitializer, i16 2, [0 x i64] zeroinitializer, i8 1, [5 x i8] zeroinitializer }> }
-@global_type_table = constant [7 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>", %"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<Foo>", i32 0, i32 0), %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const TypeInfo>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f64>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const *mut core::void>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*mut core::void>", %"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<Bar>", i32 0, i32 0)]
+@"type_info::<Bar>" = private unnamed_addr constant <{ [16 x i8], i8*, [16 x i8], i8**, [0 x i8], %"mun_codegen::ir::types::TypeInfo"**, [0 x i8], i16*, [8 x i8] }> <{ [16 x i8] c"\FC8#Lvd)F\B1Q\06\8B\02pl\10", i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"type_info::<Bar>::name", i32 0, i32 0), [16 x i8] c"\80\00\00\00\08\00\00\00\01\00\00\00\00\00\00\00", i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @"struct_info::<Bar>::field_names", i32 0, i32 0), [0 x i8] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([2 x %"mun_codegen::ir::types::TypeInfo"*], [2 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<Bar>::field_types", i32 0, i32 0), [0 x i8] zeroinitializer, i16* getelementptr inbounds ([2 x i16], [2 x i16]* @"struct_info::<Bar>::field_offsets", i32 0, i32 0), [8 x i8] c"\02\00\01\00\00\00\00\00" }>
+@global_type_table = constant [7 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<Foo>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const TypeInfo>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f64>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const *mut core::void>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*mut core::void>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<Bar>"]
 @allocatorHandle = unnamed_addr global i8* null
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__function_arguments.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__function_arguments.snap
index ec6690097..9aa50493e 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__function_arguments.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__function_arguments.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn main(a:i32) -> i32 {\n      a\n    }\n    "
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -19,9 +20,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__function_calls.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__function_calls.snap
index 4fac4414a..e608fd01d 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__function_calls.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__function_calls.snap
@@ -1,12 +1,14 @@
 ---
 source: crates/mun_codegen/src/test.rs
 expression: "\n    fn add_impl(a:i32, b:i32) -> i32 {\n        a+b\n    }\n\n    fn add(a:i32, b:i32) -> i32 {\n      add_impl(a,b)\n    }\n\n    pub fn test() -> i32 {\n      add(4,5)\n      add_impl(4,5)\n      add(4,5)\n    }\n    "
+
 ---
 ; == FILE IR (mod) =====================================
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -34,9 +36,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__gc_struct.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__gc_struct.snap
index 9d61d59da..f66e6336a 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__gc_struct.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__gc_struct.snap
@@ -7,7 +7,8 @@ expression: "\n    struct(gc) Foo { a: i32, b: i32 };\n\n    pub fn foo() {\n
 source_filename = "mod"
 
 %DispatchTable = type { i8** (i8*, i8*)* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 %Foo = type { i32, i32 }
 
 @allocatorHandle = external global i8*
@@ -46,8 +47,8 @@ body:
 source_filename = "group_name"
 
 %DispatchTable = type { i8** (i8*, i8*)* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
-%"mun_codegen::ir::types::StructInfo" = type <{ [0 x i64], i8**, [0 x i64], %"mun_codegen::ir::types::TypeInfo"**, [0 x i64], i16*, [0 x i64], i16, [0 x i64], i8, [5 x i8] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @dispatchTable = global %DispatchTable zeroinitializer
 @"type_info::<Foo>::name" = private unnamed_addr constant [4 x i8] c"Foo\00"
@@ -55,16 +56,16 @@ source_filename = "group_name"
 @"struct_info::<Foo>::field_names.1" = private unnamed_addr constant [2 x i8] c"b\00"
 @"struct_info::<Foo>::field_names" = private unnamed_addr constant [2 x i8*] [i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<Foo>::field_names.0", i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<Foo>::field_names.1", i32 0, i32 0)]
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"struct_info::<Foo>::field_types" = private unnamed_addr constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 @"struct_info::<Foo>::field_offsets" = private unnamed_addr constant [2 x i16] [i16 0, i16 4]
-@"type_info::<Foo>" = private unnamed_addr constant { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" } { %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\03\FC\D1_\DB\DB\0AJ1r,\F0m\CBQ\D0", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"type_info::<Foo>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 1, [1 x i16] zeroinitializer }>, %"mun_codegen::ir::types::StructInfo" <{ [0 x i64] zeroinitializer, i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @"struct_info::<Foo>::field_names", i32 0, i32 0), [0 x i64] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([2 x %"mun_codegen::ir::types::TypeInfo"*], [2 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<Foo>::field_types", i32 0, i32 0), [0 x i64] zeroinitializer, i16* getelementptr inbounds ([2 x i16], [2 x i16]* @"struct_info::<Foo>::field_offsets", i32 0, i32 0), [0 x i64] zeroinitializer, i16 2, [0 x i64] zeroinitializer, i8 0, [5 x i8] zeroinitializer }> }
+@"type_info::<Foo>" = private unnamed_addr constant <{ [16 x i8], i8*, [16 x i8], i8**, [0 x i8], %"mun_codegen::ir::types::TypeInfo"**, [0 x i8], i16*, [8 x i8] }> <{ [16 x i8] c"\03\FC\D1_\DB\DB\0AJ1r,\F0m\CBQ\D0", i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"type_info::<Foo>::name", i32 0, i32 0), [16 x i8] c"@\00\00\00\04\00\00\00\01\00\00\00\00\00\00\00", i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @"struct_info::<Foo>::field_names", i32 0, i32 0), [0 x i8] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([2 x %"mun_codegen::ir::types::TypeInfo"*], [2 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<Foo>::field_types", i32 0, i32 0), [0 x i8] zeroinitializer, i16* getelementptr inbounds ([2 x i16], [2 x i16]* @"struct_info::<Foo>::field_offsets", i32 0, i32 0), [8 x i8] c"\02\00\00\00\00\00\00\00" }>
 @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00"
-@"type_info::<*const TypeInfo>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*const TypeInfo>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<*const TypeInfo>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*const TypeInfo>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00"
-@"type_info::<*const *mut core::void>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @"type_info::<*const *mut core::void>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<*const *mut core::void>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", i8* getelementptr inbounds ([23 x i8], [23 x i8]* @"type_info::<*const *mut core::void>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00"
-@"type_info::<*mut core::void>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*mut core::void>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
-@global_type_table = constant [5 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<Foo>", i32 0, i32 0), %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const TypeInfo>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const *mut core::void>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*mut core::void>"]
+@"type_info::<*mut core::void>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*mut core::void>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
+@global_type_table = constant [5 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<Foo>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const TypeInfo>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const *mut core::void>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*mut core::void>"]
 @allocatorHandle = unnamed_addr global i8* null
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__if_statement.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__if_statement.snap
index eef128cce..4336f88db 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__if_statement.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__if_statement.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn foo(a:i32) -> i32 {\n        let b = if a > 3 {\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -35,9 +36,10 @@ if_merge:                                         ; preds = %else, %then
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_128.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_128.snap
index d99a4e526..439444961 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_128.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_128.snap
@@ -7,7 +7,8 @@ expression: "\n    // resources/script.mun\n    extern fn thing(n: i32);\n    ex
 source_filename = "mod"
 
 %DispatchTable = type { i32 (i32)*, void (i32)* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @dispatchTable = external global %DispatchTable
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
@@ -30,10 +31,11 @@ body:
 source_filename = "group_name"
 
 %DispatchTable = type { i32 (i32)*, void (i32)* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @dispatchTable = global %DispatchTable zeroinitializer
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_133.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_133.snap
index ec7ed0703..c7b0e7ede 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_133.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_133.snap
@@ -1,6 +1,7 @@
 ---
 source: crates/mun_codegen/src/test.rs
 expression: "\n    fn do_the_things(n: i32) -> i32 {\n        n + 7\n    }\n    \n    pub fn main() {\n        do_the_things(3);\n    }\n    "
+
 ---
 ; == FILE IR (mod) =====================================
 ; ModuleID = 'mod'
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_225.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_225.snap
index 565d74422..b1f74ec38 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_225.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_225.snap
@@ -7,7 +7,8 @@ expression: "\n    struct Num {\n        value: i64,\n    }\n\n    pub fn foo(b:
 source_filename = "mod"
 
 %DispatchTable = type { i8** (i8*, i8*)* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 %Num = type { i64 }
 
 @allocatorHandle = external global i8*
@@ -51,24 +52,24 @@ body:
 source_filename = "group_name"
 
 %DispatchTable = type { i8** (i8*, i8*)* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
-%"mun_codegen::ir::types::StructInfo" = type <{ [0 x i64], i8**, [0 x i64], %"mun_codegen::ir::types::TypeInfo"**, [0 x i64], i16*, [0 x i64], i16, [0 x i64], i8, [5 x i8] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @dispatchTable = global %DispatchTable zeroinitializer
 @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00"
-@"type_info::<*const TypeInfo>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*const TypeInfo>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<*const TypeInfo>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*const TypeInfo>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<core::i64>::name" = private unnamed_addr constant [10 x i8] c"core::i64\00"
-@"type_info::<core::i64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<Num>::name" = private unnamed_addr constant [4 x i8] c"Num\00"
 @"struct_info::<Num>::field_names.0" = private unnamed_addr constant [6 x i8] c"value\00"
 @"struct_info::<Num>::field_names" = private unnamed_addr constant [1 x i8*] [i8* getelementptr inbounds ([6 x i8], [6 x i8]* @"struct_info::<Num>::field_names.0", i32 0, i32 0)]
 @"struct_info::<Num>::field_types" = private unnamed_addr constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i64>"]
 @"struct_info::<Num>::field_offsets" = private unnamed_addr constant [1 x i16] zeroinitializer
-@"type_info::<Num>" = private unnamed_addr constant { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" } { %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\A92\E2p\B0\98\B2\C4\0C\A2\F5=x\904\00", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"type_info::<Num>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 1, [1 x i16] zeroinitializer }>, %"mun_codegen::ir::types::StructInfo" <{ [0 x i64] zeroinitializer, i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"struct_info::<Num>::field_names", i32 0, i32 0), [0 x i64] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([1 x %"mun_codegen::ir::types::TypeInfo"*], [1 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<Num>::field_types", i32 0, i32 0), [0 x i64] zeroinitializer, i16* getelementptr inbounds ([1 x i16], [1 x i16]* @"struct_info::<Num>::field_offsets", i32 0, i32 0), [0 x i64] zeroinitializer, i16 1, [0 x i64] zeroinitializer, i8 0, [5 x i8] zeroinitializer }> }
+@"type_info::<Num>" = private unnamed_addr constant <{ [16 x i8], i8*, [16 x i8], i8**, [0 x i8], %"mun_codegen::ir::types::TypeInfo"**, [0 x i8], i16*, [8 x i8] }> <{ [16 x i8] c"\A92\E2p\B0\98\B2\C4\0C\A2\F5=x\904\00", i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"type_info::<Num>::name", i32 0, i32 0), [16 x i8] c"@\00\00\00\08\00\00\00\01\00\00\00\00\00\00\00", i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"struct_info::<Num>::field_names", i32 0, i32 0), [0 x i8] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([1 x %"mun_codegen::ir::types::TypeInfo"*], [1 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<Num>::field_types", i32 0, i32 0), [0 x i8] zeroinitializer, i16* getelementptr inbounds ([1 x i16], [1 x i16]* @"struct_info::<Num>::field_offsets", i32 0, i32 0), [8 x i8] c"\01\00\00\00\00\00\00\00" }>
 @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00"
-@"type_info::<*const *mut core::void>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @"type_info::<*const *mut core::void>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<*const *mut core::void>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", i8* getelementptr inbounds ([23 x i8], [23 x i8]* @"type_info::<*const *mut core::void>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00"
-@"type_info::<*mut core::void>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*mut core::void>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
-@global_type_table = constant [5 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const TypeInfo>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i64>", %"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<Num>", i32 0, i32 0), %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const *mut core::void>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*mut core::void>"]
+@"type_info::<*mut core::void>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*mut core::void>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
+@global_type_table = constant [5 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const TypeInfo>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i64>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<Num>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const *mut core::void>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*mut core::void>"]
 @allocatorHandle = unnamed_addr global i8* null
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_228.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_228.snap
index c915892f7..c3063fb9b 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_228.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_228.snap
@@ -6,7 +6,8 @@ expression: "\n    pub  fn fact(n: usize) -> usize {\n   \t    if n == 0 {return
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -23,9 +24,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u64>::name" = private unnamed_addr constant [10 x i8] c"core::u64\00"
-@"type_info::<core::u64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_228_never_if.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_228_never_if.snap
index fcc4dd4cf..3f8e44647 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_228_never_if.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__issue_228_never_if.snap
@@ -6,7 +6,8 @@ expression: "\n    pub  fn fact(n: usize) -> usize {\n   \t    if n == 0 {return
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -28,9 +29,10 @@ else:                                             ; preds = %body
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u64>::name" = private unnamed_addr constant [10 x i8] c"core::u64\00"
-@"type_info::<core::u64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__let_statement.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__let_statement.snap
index 400e1657f..6a5e4ed2a 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__let_statement.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__let_statement.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn main(a:i32) -> i32 {\n      let b = a+1\n      b\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -20,9 +21,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__literal_types.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__literal_types.snap
index 9fc34c0e0..19bd70b1d 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__literal_types.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__literal_types.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn main(){\n        let a = 123;\n        let a = 123u8;\
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -60,9 +61,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u32>::name" = private unnamed_addr constant [10 x i8] c"core::u32\00"
-@"type_info::<core::u32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"daz5d\A6\BE\88\81=&Y\A1+\C6\1D", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"daz5d\A6\BE\88\81=&Y\A1+\C6\1D", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__logic_op_bool.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__logic_op_bool.snap
index e97d4b206..cb15f266a 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__logic_op_bool.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__logic_op_bool.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn and(a: bool, b: bool) -> bool {\n        a && b\n    }
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__loop_break_expr.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__loop_break_expr.snap
index bfc88ec45..dc7194a27 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__loop_break_expr.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__loop_break_expr.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn foo(n:i32) -> i32 {\n        loop {\n            if n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -36,9 +37,10 @@ if_merge6:                                        ; preds = %if_merge
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__multi_file.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__multi_file.snap
index cb11fed7c..c2cb6e3c6 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__multi_file.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__multi_file.snap
@@ -8,7 +8,8 @@ expression: "\n    //- /mod.mun\n    pub fn main() -> i32 {\n        foo::get_va
 source_filename = "mod"
 
 %DispatchTable = type { i32 ()* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @dispatchTable = external global %DispatchTable
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
@@ -25,18 +26,20 @@ body:
 source_filename = "group_name"
 
 %DispatchTable = type { i32 ()* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @dispatchTable = global %DispatchTable zeroinitializer
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
 ; == FILE IR (foo) =====================================
 ; ModuleID = 'foo'
 source_filename = "foo"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -49,9 +52,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_f32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_f32.snap
index f6f6d4617..a284fcd91 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_f32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_f32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn negate(a: f32) -> f32 { -a }\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -20,9 +21,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::f32>::name" = private unnamed_addr constant [10 x i8] c"core::f32\00"
-@"type_info::<core::f32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"P\19b7\A8k\F2\81P\FB\83\F5P\B0\82!", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::f32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"P\19b7\A8k\F2\81P\FB\83\F5P\B0\82!", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_f64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_f64.snap
index d40f02689..53d329e27 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_f64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_f64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn negate(a: f64) -> f64 { -a }\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -20,9 +21,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::f64>::name" = private unnamed_addr constant [10 x i8] c"core::f64\00"
-@"type_info::<core::f64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::f64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i128.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i128.snap
index 8d9976ee7..72380a525 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i128.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i128.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn negate(a: i128) -> i128 { -a }\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -20,9 +21,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i128>::name" = private unnamed_addr constant [11 x i8] c"core::i128\00"
-@"type_info::<core::i128>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\BDkp\09RRM\EBc\02\A0\DB47\A7\E3", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::i128>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i128>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\BDkp\09RRM\EBc\02\A0\DB47\A7\E3", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::i128>::name", i32 0, i32 0), [48 x i8] c"\80\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i128>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i16.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i16.snap
index 0d12c5a83..43f282502 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i16.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i16.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn negate(a: i16) -> i16 { -a }\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -20,9 +21,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i16>::name" = private unnamed_addr constant [10 x i8] c"core::i16\00"
-@"type_info::<core::i16>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\05\CD|\F8Bv\D8\B1\E8\8B\8C\D8\8D\B5\89\B0", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i16>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 16, [0 x i64] zeroinitializer, i8 2, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i16>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\05\CD|\F8Bv\D8\B1\E8\8B\8C\D8\8D\B5\89\B0", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i16>::name", i32 0, i32 0), [48 x i8] c"\10\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i16>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i32.snap
index 98d08d14c..6158c61af 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn negate(a: i32) -> i32 { -a }\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -20,9 +21,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i64.snap
index 7287817f5..add3a8ee3 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn negate(a: i64) -> i64 { -a }\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -20,9 +21,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i64>::name" = private unnamed_addr constant [10 x i8] c"core::i64\00"
-@"type_info::<core::i64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i8.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i8.snap
index a917f5ac9..ebc2d0ea2 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i8.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__negate_op_i8.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn negate(a: i8) -> i8 { -a }\n                        "
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -20,9 +21,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i8>::name" = private unnamed_addr constant [9 x i8] c"core::i8\00"
-@"type_info::<core::i8>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\EF\C4\B1Z\E7\12\B1\91q\F1\0B\80U\FC\A6\0F", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::i8>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 8, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i8>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\EF\C4\B1Z\E7\12\B1\91q\F1\0B\80U\FC\A6\0F", i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::i8>::name", i32 0, i32 0), [48 x i8] c"\08\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i8>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_private_extern_fn.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_private_extern_fn.snap
index 94d9d8beb..eb7188fe9 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_private_extern_fn.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_private_extern_fn.snap
@@ -1,13 +1,15 @@
 ---
 source: crates/mun_codegen/src/test.rs
 expression: "\n    extern fn extern_fn() -> f32;\n\n    fn private_fn() -> f32 {\n        extern_fn()\n    }\n\n    pub fn main() -> f32 {\n        private_fn()\n    }\n    "
+
 ---
 ; == FILE IR (mod) =====================================
 ; ModuleID = 'mod'
 source_filename = "mod"
 
 %DispatchTable = type { float ()* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @dispatchTable = external global %DispatchTable
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
@@ -30,10 +32,11 @@ body:
 source_filename = "group_name"
 
 %DispatchTable = type { float ()* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @dispatchTable = global %DispatchTable zeroinitializer
 @"type_info::<core::f32>::name" = private unnamed_addr constant [10 x i8] c"core::f32\00"
-@"type_info::<core::f32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"P\19b7\A8k\F2\81P\FB\83\F5P\B0\82!", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::f32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"P\19b7\A8k\F2\81P\FB\83\F5P\B0\82!", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_private_fn.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_private_fn.snap
index 2efa03b5f..a02d27e7b 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_private_fn.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_private_fn.snap
@@ -1,12 +1,14 @@
 ---
 source: crates/mun_codegen/src/test.rs
 expression: "\n    fn nested_private_fn() -> i32 {\n        1\n    }\n\n    fn private_fn() -> i32 {\n        nested_private_fn()\n    }\n\n    pub fn main() -> i32 {\n        private_fn()\n    }\n    "
+
 ---
 ; == FILE IR (mod) =====================================
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -31,9 +33,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_private_recursive_fn.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_private_recursive_fn.snap
index bb137e22b..073c1a219 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_private_recursive_fn.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_private_recursive_fn.snap
@@ -1,12 +1,14 @@
 ---
 source: crates/mun_codegen/src/test.rs
 expression: "\n    fn private_fn() -> f32 {\n        private_fn()\n    }\n\n    pub fn main() -> f32 {\n        private_fn()\n    }\n    "
+
 ---
 ; == FILE IR (mod) =====================================
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +28,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::f32>::name" = private unnamed_addr constant [10 x i8] c"core::f32\00"
-@"type_info::<core::f32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"P\19b7\A8k\F2\81P\FB\83\F5P\B0\82!", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::f32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"P\19b7\A8k\F2\81P\FB\83\F5P\B0\82!", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_private_recursive_fn_with_args.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_private_recursive_fn_with_args.snap
index 575585bdd..0b49219b1 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_private_recursive_fn_with_args.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_private_recursive_fn_with_args.snap
@@ -1,13 +1,15 @@
 ---
 source: crates/mun_codegen/src/test.rs
 expression: "\n    extern fn other() -> i32;\n\n    fn private_fn(a: i32) -> f32 {\n        private_fn(a)\n    }\n\n    pub fn main() -> f32 {\n        private_fn(other())\n    }\n    "
+
 ---
 ; == FILE IR (mod) =====================================
 ; ModuleID = 'mod'
 source_filename = "mod"
 
 %DispatchTable = type { i32 ()* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @dispatchTable = external global %DispatchTable
 @global_type_table = external global [2 x %"mun_codegen::ir::types::TypeInfo"*]
@@ -31,12 +33,13 @@ body:
 source_filename = "group_name"
 
 %DispatchTable = type { i32 ()* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @dispatchTable = global %DispatchTable zeroinitializer
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<core::f32>::name" = private unnamed_addr constant [10 x i8] c"core::f32\00"
-@"type_info::<core::f32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"P\19b7\A8k\F2\81P\FB\83\F5P\B0\82!", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::f32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"P\19b7\A8k\F2\81P\FB\83\F5P\B0\82!", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_structs.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_structs.snap
index 23a4de1e5..2cacbd302 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_structs.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__nested_structs.snap
@@ -1,13 +1,15 @@
 ---
 source: crates/mun_codegen/src/test.rs
 expression: "\n    struct(gc) GcStruct(f32, f32);\n    struct(value) ValueStruct(f32, f32);\n\n    struct(gc) GcWrapper(GcStruct, ValueStruct)\n    struct(value) ValueWrapper(GcStruct, ValueStruct);\n\n    pub fn new_gc_struct(a: f32, b: f32) -> GcStruct {\n        GcStruct(a, b)\n    }\n\n    pub fn new_value_struct(a: f32, b: f32) -> ValueStruct {\n        ValueStruct(a, b)\n    }\n\n    pub fn new_gc_wrapper(a: GcStruct, b: ValueStruct) -> GcWrapper {\n        GcWrapper(a, b)\n    }\n\n    pub fn new_value_wrapper(a: GcStruct, b: ValueStruct) -> ValueWrapper {\n        ValueWrapper(a, b)\n    }\n    "
+
 ---
 ; == FILE IR (mod) =====================================
 ; ModuleID = 'mod'
 source_filename = "mod"
 
 %DispatchTable = type { i8** (i8*, i8*)* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 %GcStruct = type { float, float }
 %ValueStruct = type { float, float }
 %GcWrapper = type { %GcStruct**, %ValueStruct }
@@ -108,8 +110,8 @@ body:
 source_filename = "group_name"
 
 %DispatchTable = type { i8** (i8*, i8*)* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
-%"mun_codegen::ir::types::StructInfo" = type <{ [0 x i64], i8**, [0 x i64], %"mun_codegen::ir::types::TypeInfo"**, [0 x i64], i16*, [0 x i64], i16, [0 x i64], i8, [5 x i8] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @dispatchTable = global %DispatchTable zeroinitializer
 @"type_info::<GcWrapper>::name" = private unnamed_addr constant [10 x i8] c"GcWrapper\00"
@@ -121,33 +123,33 @@ source_filename = "group_name"
 @"struct_info::<GcStruct>::field_names.1" = private unnamed_addr constant [2 x i8] c"1\00"
 @"struct_info::<GcStruct>::field_names" = private unnamed_addr constant [2 x i8*] [i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<GcStruct>::field_names.0", i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<GcStruct>::field_names.1", i32 0, i32 0)]
 @"type_info::<core::f32>::name" = private unnamed_addr constant [10 x i8] c"core::f32\00"
-@"type_info::<core::f32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"P\19b7\A8k\F2\81P\FB\83\F5P\B0\82!", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::f32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"P\19b7\A8k\F2\81P\FB\83\F5P\B0\82!", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"struct_info::<GcStruct>::field_types" = private unnamed_addr constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f32>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f32>"]
 @"struct_info::<GcStruct>::field_offsets" = private unnamed_addr constant [2 x i16] [i16 0, i16 4]
-@"type_info::<GcStruct>" = private unnamed_addr constant { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" } { %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\B9)lg\01\95k@E\B4(\CB\CAGX\E1", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<GcStruct>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 1, [1 x i16] zeroinitializer }>, %"mun_codegen::ir::types::StructInfo" <{ [0 x i64] zeroinitializer, i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @"struct_info::<GcStruct>::field_names", i32 0, i32 0), [0 x i64] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([2 x %"mun_codegen::ir::types::TypeInfo"*], [2 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<GcStruct>::field_types", i32 0, i32 0), [0 x i64] zeroinitializer, i16* getelementptr inbounds ([2 x i16], [2 x i16]* @"struct_info::<GcStruct>::field_offsets", i32 0, i32 0), [0 x i64] zeroinitializer, i16 2, [0 x i64] zeroinitializer, i8 0, [5 x i8] zeroinitializer }> }
+@"type_info::<GcStruct>" = private unnamed_addr constant <{ [16 x i8], i8*, [16 x i8], i8**, [0 x i8], %"mun_codegen::ir::types::TypeInfo"**, [0 x i8], i16*, [8 x i8] }> <{ [16 x i8] c"\B9)lg\01\95k@E\B4(\CB\CAGX\E1", i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<GcStruct>::name", i32 0, i32 0), [16 x i8] c"@\00\00\00\04\00\00\00\01\00\00\00\00\00\00\00", i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @"struct_info::<GcStruct>::field_names", i32 0, i32 0), [0 x i8] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([2 x %"mun_codegen::ir::types::TypeInfo"*], [2 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<GcStruct>::field_types", i32 0, i32 0), [0 x i8] zeroinitializer, i16* getelementptr inbounds ([2 x i16], [2 x i16]* @"struct_info::<GcStruct>::field_offsets", i32 0, i32 0), [8 x i8] c"\02\00\00\00\00\00\00\00" }>
 @"type_info::<ValueStruct>::name" = private unnamed_addr constant [12 x i8] c"ValueStruct\00"
 @"struct_info::<ValueStruct>::field_names.0" = private unnamed_addr constant [2 x i8] c"0\00"
 @"struct_info::<ValueStruct>::field_names.1" = private unnamed_addr constant [2 x i8] c"1\00"
 @"struct_info::<ValueStruct>::field_names" = private unnamed_addr constant [2 x i8*] [i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<ValueStruct>::field_names.0", i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<ValueStruct>::field_names.1", i32 0, i32 0)]
 @"struct_info::<ValueStruct>::field_types" = private unnamed_addr constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f32>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f32>"]
 @"struct_info::<ValueStruct>::field_offsets" = private unnamed_addr constant [2 x i16] [i16 0, i16 4]
-@"type_info::<ValueStruct>" = private unnamed_addr constant { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" } { %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"U0{\87\\\04Q/\95!$\A2\F1\A9\F9W", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([12 x i8], [12 x i8]* @"type_info::<ValueStruct>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 1, [1 x i16] zeroinitializer }>, %"mun_codegen::ir::types::StructInfo" <{ [0 x i64] zeroinitializer, i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @"struct_info::<ValueStruct>::field_names", i32 0, i32 0), [0 x i64] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([2 x %"mun_codegen::ir::types::TypeInfo"*], [2 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<ValueStruct>::field_types", i32 0, i32 0), [0 x i64] zeroinitializer, i16* getelementptr inbounds ([2 x i16], [2 x i16]* @"struct_info::<ValueStruct>::field_offsets", i32 0, i32 0), [0 x i64] zeroinitializer, i16 2, [0 x i64] zeroinitializer, i8 1, [5 x i8] zeroinitializer }> }
-@"struct_info::<GcWrapper>::field_types" = private unnamed_addr constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<GcStruct>", i32 0, i32 0), %"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<ValueStruct>", i32 0, i32 0)]
+@"type_info::<ValueStruct>" = private unnamed_addr constant <{ [16 x i8], i8*, [16 x i8], i8**, [0 x i8], %"mun_codegen::ir::types::TypeInfo"**, [0 x i8], i16*, [8 x i8] }> <{ [16 x i8] c"U0{\87\\\04Q/\95!$\A2\F1\A9\F9W", i8* getelementptr inbounds ([12 x i8], [12 x i8]* @"type_info::<ValueStruct>::name", i32 0, i32 0), [16 x i8] c"@\00\00\00\04\00\00\00\01\00\00\00\00\00\00\00", i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @"struct_info::<ValueStruct>::field_names", i32 0, i32 0), [0 x i8] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([2 x %"mun_codegen::ir::types::TypeInfo"*], [2 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<ValueStruct>::field_types", i32 0, i32 0), [0 x i8] zeroinitializer, i16* getelementptr inbounds ([2 x i16], [2 x i16]* @"struct_info::<ValueStruct>::field_offsets", i32 0, i32 0), [8 x i8] c"\02\00\01\00\00\00\00\00" }>
+@"struct_info::<GcWrapper>::field_types" = private unnamed_addr constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<GcStruct>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<ValueStruct>"]
 @"struct_info::<GcWrapper>::field_offsets" = private unnamed_addr constant [2 x i16] [i16 0, i16 8]
-@"type_info::<GcWrapper>" = private unnamed_addr constant { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" } { %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"!\14\93\A7H1?90\B7\EA\DB0\82\A0\C7", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<GcWrapper>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 1, [1 x i16] zeroinitializer }>, %"mun_codegen::ir::types::StructInfo" <{ [0 x i64] zeroinitializer, i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @"struct_info::<GcWrapper>::field_names", i32 0, i32 0), [0 x i64] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([2 x %"mun_codegen::ir::types::TypeInfo"*], [2 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<GcWrapper>::field_types", i32 0, i32 0), [0 x i64] zeroinitializer, i16* getelementptr inbounds ([2 x i16], [2 x i16]* @"struct_info::<GcWrapper>::field_offsets", i32 0, i32 0), [0 x i64] zeroinitializer, i16 2, [0 x i64] zeroinitializer, i8 0, [5 x i8] zeroinitializer }> }
+@"type_info::<GcWrapper>" = private unnamed_addr constant <{ [16 x i8], i8*, [16 x i8], i8**, [0 x i8], %"mun_codegen::ir::types::TypeInfo"**, [0 x i8], i16*, [8 x i8] }> <{ [16 x i8] c"!\14\93\A7H1?90\B7\EA\DB0\82\A0\C7", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<GcWrapper>::name", i32 0, i32 0), [16 x i8] c"\80\00\00\00\08\00\00\00\01\00\00\00\00\00\00\00", i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @"struct_info::<GcWrapper>::field_names", i32 0, i32 0), [0 x i8] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([2 x %"mun_codegen::ir::types::TypeInfo"*], [2 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<GcWrapper>::field_types", i32 0, i32 0), [0 x i8] zeroinitializer, i16* getelementptr inbounds ([2 x i16], [2 x i16]* @"struct_info::<GcWrapper>::field_offsets", i32 0, i32 0), [8 x i8] c"\02\00\00\00\00\00\00\00" }>
 @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00"
-@"type_info::<*const TypeInfo>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*const TypeInfo>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<*const TypeInfo>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*const TypeInfo>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<ValueWrapper>::name" = private unnamed_addr constant [13 x i8] c"ValueWrapper\00"
 @"struct_info::<ValueWrapper>::field_names.0" = private unnamed_addr constant [2 x i8] c"0\00"
 @"struct_info::<ValueWrapper>::field_names.1" = private unnamed_addr constant [2 x i8] c"1\00"
 @"struct_info::<ValueWrapper>::field_names" = private unnamed_addr constant [2 x i8*] [i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<ValueWrapper>::field_names.0", i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<ValueWrapper>::field_names.1", i32 0, i32 0)]
-@"struct_info::<ValueWrapper>::field_types" = private unnamed_addr constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<GcStruct>", i32 0, i32 0), %"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<ValueStruct>", i32 0, i32 0)]
+@"struct_info::<ValueWrapper>::field_types" = private unnamed_addr constant [2 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<GcStruct>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<ValueStruct>"]
 @"struct_info::<ValueWrapper>::field_offsets" = private unnamed_addr constant [2 x i16] [i16 0, i16 8]
-@"type_info::<ValueWrapper>" = private unnamed_addr constant { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" } { %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"@j\D8\CD~-\12\87|A\E8\DBp\EC}\AA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([13 x i8], [13 x i8]* @"type_info::<ValueWrapper>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 1, [1 x i16] zeroinitializer }>, %"mun_codegen::ir::types::StructInfo" <{ [0 x i64] zeroinitializer, i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @"struct_info::<ValueWrapper>::field_names", i32 0, i32 0), [0 x i64] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([2 x %"mun_codegen::ir::types::TypeInfo"*], [2 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<ValueWrapper>::field_types", i32 0, i32 0), [0 x i64] zeroinitializer, i16* getelementptr inbounds ([2 x i16], [2 x i16]* @"struct_info::<ValueWrapper>::field_offsets", i32 0, i32 0), [0 x i64] zeroinitializer, i16 2, [0 x i64] zeroinitializer, i8 1, [5 x i8] zeroinitializer }> }
+@"type_info::<ValueWrapper>" = private unnamed_addr constant <{ [16 x i8], i8*, [16 x i8], i8**, [0 x i8], %"mun_codegen::ir::types::TypeInfo"**, [0 x i8], i16*, [8 x i8] }> <{ [16 x i8] c"@j\D8\CD~-\12\87|A\E8\DBp\EC}\AA", i8* getelementptr inbounds ([13 x i8], [13 x i8]* @"type_info::<ValueWrapper>::name", i32 0, i32 0), [16 x i8] c"\80\00\00\00\08\00\00\00\01\00\00\00\00\00\00\00", i8** getelementptr inbounds ([2 x i8*], [2 x i8*]* @"struct_info::<ValueWrapper>::field_names", i32 0, i32 0), [0 x i8] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([2 x %"mun_codegen::ir::types::TypeInfo"*], [2 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<ValueWrapper>::field_types", i32 0, i32 0), [0 x i8] zeroinitializer, i16* getelementptr inbounds ([2 x i16], [2 x i16]* @"struct_info::<ValueWrapper>::field_offsets", i32 0, i32 0), [8 x i8] c"\02\00\01\00\00\00\00\00" }>
 @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00"
-@"type_info::<*const *mut core::void>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @"type_info::<*const *mut core::void>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<*const *mut core::void>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", i8* getelementptr inbounds ([23 x i8], [23 x i8]* @"type_info::<*const *mut core::void>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00"
-@"type_info::<*mut core::void>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*mut core::void>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
-@global_type_table = constant [8 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<GcWrapper>", i32 0, i32 0), %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const TypeInfo>", %"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<ValueWrapper>", i32 0, i32 0), %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f32>", %"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<ValueStruct>", i32 0, i32 0), %"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<GcStruct>", i32 0, i32 0), %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const *mut core::void>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*mut core::void>"]
+@"type_info::<*mut core::void>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*mut core::void>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
+@global_type_table = constant [8 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<GcWrapper>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const TypeInfo>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<ValueWrapper>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f32>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<ValueStruct>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<GcStruct>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const *mut core::void>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*mut core::void>"]
 @allocatorHandle = unnamed_addr global i8* null
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__never_conditional_return_expr.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__never_conditional_return_expr.snap
index 5acc72f1a..c03e89913 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__never_conditional_return_expr.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__never_conditional_return_expr.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn main(a:i32) -> i32 {\n        if a > 4 {\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -27,9 +28,10 @@ else:                                             ; preds = %body
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__return_expr.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__return_expr.snap
index 999e0ab2b..e7c6e4467 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__return_expr.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__return_expr.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn main() -> i32 {\n        return 5;\n        let a = 3;
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -19,9 +20,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__return_type.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__return_type.snap
index b1d25d98d..0621bed69 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__return_type.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__return_type.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn main() -> i32 {\n      0\n    }\n    "
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -19,9 +20,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__shadowing.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__shadowing.snap
index fb1ec6983..ec9cd2fb2 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__shadowing.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__shadowing.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn foo(a:i32) -> i32 {\n        let a = a+1;\n        {\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -29,9 +30,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i128.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i128.snap
index dd225ed89..fa1e5ec29 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i128.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i128.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn leftshift(a: i128, b: i128) -> i128 { a << b }\n    pu
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i128>::name" = private unnamed_addr constant [11 x i8] c"core::i128\00"
-@"type_info::<core::i128>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\BDkp\09RRM\EBc\02\A0\DB47\A7\E3", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::i128>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i128>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\BDkp\09RRM\EBc\02\A0\DB47\A7\E3", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::i128>::name", i32 0, i32 0), [48 x i8] c"\80\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i128>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i16.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i16.snap
index b06332540..bc922489c 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i16.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i16.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn leftshift(a: i16, b: i16) -> i16 { a << b }\n    pub f
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i16>::name" = private unnamed_addr constant [10 x i8] c"core::i16\00"
-@"type_info::<core::i16>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\05\CD|\F8Bv\D8\B1\E8\8B\8C\D8\8D\B5\89\B0", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i16>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 16, [0 x i64] zeroinitializer, i8 2, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i16>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\05\CD|\F8Bv\D8\B1\E8\8B\8C\D8\8D\B5\89\B0", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i16>::name", i32 0, i32 0), [48 x i8] c"\10\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i16>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i32.snap
index 766de9182..58a5323e1 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn leftshift(a: i32, b: i32) -> i32 { a << b }\n    pub f
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i64.snap
index a92a1d2e0..57415b293 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn leftshift(a: i64, b: i64) -> i64 { a << b }\n    pub f
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i64>::name" = private unnamed_addr constant [10 x i8] c"core::i64\00"
-@"type_info::<core::i64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i8.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i8.snap
index c087a1c78..1073f4c15 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i8.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_i8.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn leftshift(a: i8, b: i8) -> i8 { a << b }\n    pub fn r
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i8>::name" = private unnamed_addr constant [9 x i8] c"core::i8\00"
-@"type_info::<core::i8>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\EF\C4\B1Z\E7\12\B1\91q\F1\0B\80U\FC\A6\0F", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::i8>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 8, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i8>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\EF\C4\B1Z\E7\12\B1\91q\F1\0B\80U\FC\A6\0F", i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::i8>::name", i32 0, i32 0), [48 x i8] c"\08\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i8>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u128.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u128.snap
index bd75cae2e..b82bb8b03 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u128.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u128.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn leftshift(a: u128, b: u128) -> u128 { a << b }\n    pu
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u128>::name" = private unnamed_addr constant [11 x i8] c"core::u128\00"
-@"type_info::<core::u128>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\E67\1BU\E9k\95\93d\14}\1C\96S\95\F0", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::u128>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 128, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u128>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\E67\1BU\E9k\95\93d\14}\1C\96S\95\F0", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::u128>::name", i32 0, i32 0), [48 x i8] c"\80\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u128>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u16.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u16.snap
index 93458c06b..74679a7cc 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u16.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u16.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn leftshift(a: u16, b: u16) -> u16 { a << b }\n    pub f
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u16>::name" = private unnamed_addr constant [10 x i8] c"core::u16\00"
-@"type_info::<core::u16>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"0\01\BC\BBK\E0\F2\7F&l\01\CD|q\F2\B3", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u16>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 16, [0 x i64] zeroinitializer, i8 2, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u16>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"0\01\BC\BBK\E0\F2\7F&l\01\CD|q\F2\B3", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u16>::name", i32 0, i32 0), [48 x i8] c"\10\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u16>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u32.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u32.snap
index f796c1e8f..38a1e1f57 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u32.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u32.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn leftshift(a: u32, b: u32) -> u32 { a << b }\n    pub f
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u32>::name" = private unnamed_addr constant [10 x i8] c"core::u32\00"
-@"type_info::<core::u32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"daz5d\A6\BE\88\81=&Y\A1+\C6\1D", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"daz5d\A6\BE\88\81=&Y\A1+\C6\1D", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u64.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u64.snap
index 4a64ea29c..f467d0d2d 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u64.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u64.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn leftshift(a: u64, b: u64) -> u64 { a << b }\n    pub f
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u64>::name" = private unnamed_addr constant [10 x i8] c"core::u64\00"
-@"type_info::<core::u64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::u64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u64>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u8.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u8.snap
index 124c417eb..896412e40 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u8.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__shift_op_u8.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn leftshift(a: u8, b: u8) -> u8 { a << b }\n    pub fn r
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -26,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::u8>::name" = private unnamed_addr constant [9 x i8] c"core::u8\00"
-@"type_info::<core::u8>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\A0y\A7S\B6(n\F7f&H\E1\F9\AD\04>", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::u8>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 8, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::u8>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\A0y\A7S\B6(n\F7f&H\E1\F9\AD\04>", i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"type_info::<core::u8>::name", i32 0, i32 0), [48 x i8] c"\08\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::u8>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__struct_test.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__struct_test.snap
index bbcaced33..8af7d4d36 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__struct_test.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__struct_test.snap
@@ -7,7 +7,8 @@ expression: "\n    struct(value) Bar(f64, i32, bool, Foo);\n    struct(value) Fo
 source_filename = "mod"
 
 %DispatchTable = type { i8** (i8*, i8*)* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 %Baz = type {}
 %Bar = type { double, i32, i1, %Foo }
 %Foo = type { i32 }
@@ -38,39 +39,39 @@ body:
 source_filename = "group_name"
 
 %DispatchTable = type { i8** (i8*, i8*)* }
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
-%"mun_codegen::ir::types::StructInfo" = type <{ [0 x i64], i8**, [0 x i64], %"mun_codegen::ir::types::TypeInfo"**, [0 x i64], i16*, [0 x i64], i16, [0 x i64], i8, [5 x i8] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @dispatchTable = global %DispatchTable zeroinitializer
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<Foo>::name" = private unnamed_addr constant [4 x i8] c"Foo\00"
 @"struct_info::<Foo>::field_names.0" = private unnamed_addr constant [2 x i8] c"a\00"
 @"struct_info::<Foo>::field_names" = private unnamed_addr constant [1 x i8*] [i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<Foo>::field_names.0", i32 0, i32 0)]
 @"struct_info::<Foo>::field_types" = private unnamed_addr constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 @"struct_info::<Foo>::field_offsets" = private unnamed_addr constant [1 x i16] zeroinitializer
-@"type_info::<Foo>" = private unnamed_addr constant { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" } { %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"8\AD\C9\D9Y\D2\AA<ME}\CD.\A5\A0\DB", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"type_info::<Foo>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 1, [1 x i16] zeroinitializer }>, %"mun_codegen::ir::types::StructInfo" <{ [0 x i64] zeroinitializer, i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"struct_info::<Foo>::field_names", i32 0, i32 0), [0 x i64] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([1 x %"mun_codegen::ir::types::TypeInfo"*], [1 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<Foo>::field_types", i32 0, i32 0), [0 x i64] zeroinitializer, i16* getelementptr inbounds ([1 x i16], [1 x i16]* @"struct_info::<Foo>::field_offsets", i32 0, i32 0), [0 x i64] zeroinitializer, i16 1, [0 x i64] zeroinitializer, i8 1, [5 x i8] zeroinitializer }> }
+@"type_info::<Foo>" = private unnamed_addr constant <{ [16 x i8], i8*, [16 x i8], i8**, [0 x i8], %"mun_codegen::ir::types::TypeInfo"**, [0 x i8], i16*, [8 x i8] }> <{ [16 x i8] c"8\AD\C9\D9Y\D2\AA<ME}\CD.\A5\A0\DB", i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"type_info::<Foo>::name", i32 0, i32 0), [16 x i8] c" \00\00\00\04\00\00\00\01\00\00\00\00\00\00\00", i8** getelementptr inbounds ([1 x i8*], [1 x i8*]* @"struct_info::<Foo>::field_names", i32 0, i32 0), [0 x i8] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([1 x %"mun_codegen::ir::types::TypeInfo"*], [1 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<Foo>::field_types", i32 0, i32 0), [0 x i8] zeroinitializer, i16* getelementptr inbounds ([1 x i16], [1 x i16]* @"struct_info::<Foo>::field_offsets", i32 0, i32 0), [8 x i8] c"\01\00\01\00\00\00\00\00" }>
 @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00"
-@"type_info::<*const TypeInfo>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*const TypeInfo>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<*const TypeInfo>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*const TypeInfo>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<Baz>::name" = private unnamed_addr constant [4 x i8] c"Baz\00"
-@"type_info::<Baz>" = private unnamed_addr constant { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" } { %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c">\1A\BC\E5\C9\D3n\D8\8C?\86\22\FA\0DtV", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"type_info::<Baz>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 0, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 1, [1 x i16] zeroinitializer }>, %"mun_codegen::ir::types::StructInfo" <{ [0 x i64] zeroinitializer, i8** null, [0 x i64] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** null, [0 x i64] zeroinitializer, i16* null, [0 x i64] zeroinitializer, i16 0, [0 x i64] zeroinitializer, i8 1, [5 x i8] zeroinitializer }> }
+@"type_info::<Baz>" = private unnamed_addr constant <{ [16 x i8], i8*, [16 x i8], i8**, [0 x i8], %"mun_codegen::ir::types::TypeInfo"**, [0 x i8], i16*, [8 x i8] }> <{ [16 x i8] c">\1A\BC\E5\C9\D3n\D8\8C?\86\22\FA\0DtV", i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"type_info::<Baz>::name", i32 0, i32 0), [16 x i8] c"\00\00\00\00\01\00\00\00\01\00\00\00\00\00\00\00", i8** null, [0 x i8] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** null, [0 x i8] zeroinitializer, i16* null, [8 x i8] c"\00\00\01\00\00\00\00\00" }>
 @"type_info::<core::f64>::name" = private unnamed_addr constant [10 x i8] c"core::f64\00"
-@"type_info::<core::f64>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f64>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::f64>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::f64>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00"
-@"type_info::<*const *mut core::void>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @"type_info::<*const *mut core::void>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<*const *mut core::void>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", i8* getelementptr inbounds ([23 x i8], [23 x i8]* @"type_info::<*const *mut core::void>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @"type_info::<Bar>::name" = private unnamed_addr constant [4 x i8] c"Bar\00"
 @"struct_info::<Bar>::field_names.0" = private unnamed_addr constant [2 x i8] c"0\00"
 @"struct_info::<Bar>::field_names.1" = private unnamed_addr constant [2 x i8] c"1\00"
 @"struct_info::<Bar>::field_names.2" = private unnamed_addr constant [2 x i8] c"2\00"
 @"struct_info::<Bar>::field_names.3" = private unnamed_addr constant [2 x i8] c"3\00"
 @"struct_info::<Bar>::field_names" = private unnamed_addr constant [4 x i8*] [i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<Bar>::field_names.0", i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<Bar>::field_names.1", i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<Bar>::field_names.2", i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @"struct_info::<Bar>::field_names.3", i32 0, i32 0)]
-@"struct_info::<Bar>::field_types" = private unnamed_addr constant [4 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f64>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>", %"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<Foo>", i32 0, i32 0)]
+@"struct_info::<Bar>::field_types" = private unnamed_addr constant [4 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f64>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<Foo>"]
 @"struct_info::<Bar>::field_offsets" = private unnamed_addr constant [4 x i16] [i16 0, i16 8, i16 12, i16 16]
-@"type_info::<Bar>" = private unnamed_addr constant { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" } { %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\D6\CA\E2\C3Ht\09\EA\AEh\E50L\F7\EE\B5", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"type_info::<Bar>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 192, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 1, [1 x i16] zeroinitializer }>, %"mun_codegen::ir::types::StructInfo" <{ [0 x i64] zeroinitializer, i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @"struct_info::<Bar>::field_names", i32 0, i32 0), [0 x i64] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([4 x %"mun_codegen::ir::types::TypeInfo"*], [4 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<Bar>::field_types", i32 0, i32 0), [0 x i64] zeroinitializer, i16* getelementptr inbounds ([4 x i16], [4 x i16]* @"struct_info::<Bar>::field_offsets", i32 0, i32 0), [0 x i64] zeroinitializer, i16 4, [0 x i64] zeroinitializer, i8 1, [5 x i8] zeroinitializer }> }
+@"type_info::<Bar>" = private unnamed_addr constant <{ [16 x i8], i8*, [16 x i8], i8**, [0 x i8], %"mun_codegen::ir::types::TypeInfo"**, [0 x i8], i16*, [8 x i8] }> <{ [16 x i8] c"\D6\CA\E2\C3Ht\09\EA\AEh\E50L\F7\EE\B5", i8* getelementptr inbounds ([4 x i8], [4 x i8]* @"type_info::<Bar>::name", i32 0, i32 0), [16 x i8] c"\C0\00\00\00\08\00\00\00\01\00\00\00\00\00\00\00", i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @"struct_info::<Bar>::field_names", i32 0, i32 0), [0 x i8] zeroinitializer, %"mun_codegen::ir::types::TypeInfo"** getelementptr inbounds ([4 x %"mun_codegen::ir::types::TypeInfo"*], [4 x %"mun_codegen::ir::types::TypeInfo"*]* @"struct_info::<Bar>::field_types", i32 0, i32 0), [0 x i8] zeroinitializer, i16* getelementptr inbounds ([4 x i16], [4 x i16]* @"struct_info::<Bar>::field_offsets", i32 0, i32 0), [8 x i8] c"\04\00\01\00\00\00\00\00" }>
 @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00"
-@"type_info::<*mut core::void>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*mut core::void>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 64, [0 x i64] zeroinitializer, i8 8, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
-@global_type_table = constant [9 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>", %"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<Foo>", i32 0, i32 0), %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const TypeInfo>", %"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<Baz>", i32 0, i32 0), %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f64>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const *mut core::void>", %"mun_codegen::ir::types::TypeInfo"* getelementptr inbounds ({ %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }, { %"mun_codegen::ir::types::TypeInfo", %"mun_codegen::ir::types::StructInfo" }* @"type_info::<Bar>", i32 0, i32 0), %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*mut core::void>"]
+@"type_info::<*mut core::void>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", i8* getelementptr inbounds ([16 x i8], [16 x i8]* @"type_info::<*mut core::void>::name", i32 0, i32 0), [48 x i8] c"@\00\00\00\08\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
+@global_type_table = constant [9 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<Foo>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const TypeInfo>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<Baz>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::f64>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*const *mut core::void>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<Bar>", %"mun_codegen::ir::types::TypeInfo"* @"type_info::<*mut core::void>"]
 @allocatorHandle = unnamed_addr global i8* null
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__true_is_true.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__true_is_true.snap
index d482aefea..89559fb21 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__true_is_true.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__true_is_true.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn test_true() -> bool {\n        true\n    }\n\n    pub
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -24,9 +25,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::bool>::name" = private unnamed_addr constant [11 x i8] c"core::bool\00"
-@"type_info::<core::bool>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 1, [0 x i64] zeroinitializer, i8 1, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::bool>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", i8* getelementptr inbounds ([11 x i8], [11 x i8]* @"type_info::<core::bool>::name", i32 0, i32 0), [48 x i8] c"\01\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::bool>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__update_operators.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__update_operators.snap
index d9f3efcc6..68cba90fa 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__update_operators.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__update_operators.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn add(a:i32, b:i32) -> i32 {\n      let result = a\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -44,9 +45,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__update_parameter.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__update_parameter.snap
index df9dbd3a3..5d9fea0b8 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__update_parameter.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__update_parameter.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn add_three(a:i32) -> i32 {\n      a += 3;\n      a\n
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -20,9 +21,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__void_return.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__void_return.snap
index 5b7de9b56..bfaa5d6a9 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__void_return.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__void_return.snap
@@ -1,12 +1,14 @@
 ---
 source: crates/mun_codegen/src/test.rs
 expression: "\n    fn bar() {\n        let a = 3;\n    }\n    pub fn foo(a:i32) {\n        let c = bar()\n    }\n    "
+
 ---
 ; == FILE IR (mod) =====================================
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -25,9 +27,10 @@ body:
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/src/snapshots/mun_codegen__test__while_expr.snap b/crates/mun_codegen/src/snapshots/mun_codegen__test__while_expr.snap
index 8a7661da8..a8c942ed9 100644
--- a/crates/mun_codegen/src/snapshots/mun_codegen__test__while_expr.snap
+++ b/crates/mun_codegen/src/snapshots/mun_codegen__test__while_expr.snap
@@ -6,7 +6,8 @@ expression: "\n    pub fn foo(n:i32) {\n        while n<3 {\n            n += 1;
 ; ModuleID = 'mod'
 source_filename = "mod"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @global_type_table = external global [1 x %"mun_codegen::ir::types::TypeInfo"*]
 
@@ -31,9 +32,10 @@ whilecond3:                                       ; preds = %whilecond
 ; ModuleID = 'group_name'
 source_filename = "group_name"
 
-%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [0 x i64], i8, [1 x i16] }>
+%"mun_codegen::ir::types::TypeInfo" = type <{ [0 x i64], [16 x i8], [0 x i64], i8*, [0 x i64], i32, [0 x i64], i8, [3 x i8], %"mun_codegen::ir::types::TypeInfoData", [0 x i64] }>
+%"mun_codegen::ir::types::TypeInfoData" = type <{ [0 x i8], i8, [39 x i8] }>
 
 @"type_info::<core::i32>::name" = private unnamed_addr constant [10 x i8] c"core::i32\00"
-@"type_info::<core::i32>" = private unnamed_addr constant %"mun_codegen::ir::types::TypeInfo" <{ [0 x i64] zeroinitializer, [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [0 x i64] zeroinitializer, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [0 x i64] zeroinitializer, i32 32, [0 x i64] zeroinitializer, i8 4, [0 x i64] zeroinitializer, i8 0, [1 x i16] zeroinitializer }>
+@"type_info::<core::i32>" = private unnamed_addr constant <{ [16 x i8], i8*, [48 x i8] }> <{ [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", i8* getelementptr inbounds ([10 x i8], [10 x i8]* @"type_info::<core::i32>::name", i32 0, i32 0), [48 x i8] c" \00\00\00\04\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" }>
 @global_type_table = constant [1 x %"mun_codegen::ir::types::TypeInfo"*] [%"mun_codegen::ir::types::TypeInfo"* @"type_info::<core::i32>"]
 
diff --git a/crates/mun_codegen/tests/abi.rs b/crates/mun_codegen/tests/abi.rs
index 04780b2c3..cfaec3f5d 100644
--- a/crates/mun_codegen/tests/abi.rs
+++ b/crates/mun_codegen/tests/abi.rs
@@ -1,4 +1,4 @@
-use abi::{StructMemoryKind, TypeGroup, ABI_VERSION};
+use abi::{StructMemoryKind, TypeInfoData, ABI_VERSION};
 use libloader::MunLibrary;
 use mun_test::CompileTestDriver;
 use runtime::ReturnTypeReflection;
@@ -142,9 +142,14 @@ fn test_abi_compatibility() {
         assert_eq!(type_info.size_in_bits(), 8 * mem::size_of::<T>());
         assert_eq!(type_info.size_in_bytes(), mem::size_of::<T>());
         assert_eq!(type_info.alignment(), mem::align_of::<T>());
-        assert_eq!(type_info.group, TypeGroup::StructTypes);
+        assert!(type_info.data.is_struct());
+
+        let struct_info = if let TypeInfoData::Struct(s) = &type_info.data {
+            s
+        } else {
+            panic!("Expected a struct");
+        };
 
-        let struct_info = type_info.as_struct().expect("Expected a struct");
         assert_eq!(struct_info.num_fields(), field_names.len());
         for (lhs, rhs) in struct_info.field_names().zip(field_names) {
             assert_eq!(lhs, *rhs);
diff --git a/crates/mun_memory/tests/diff/structs.rs b/crates/mun_memory/tests/diff/structs.rs
index 3f2774c2a..75d587f3b 100644
--- a/crates/mun_memory/tests/diff/structs.rs
+++ b/crates/mun_memory/tests/diff/structs.rs
@@ -6,9 +6,8 @@ use mun_memory::diff::{diff, Diff, FieldDiff, FieldEditKind};
 fn assert_eq_struct(result: &[TypeInfo], expected: &[TypeInfo]) {
     assert_eq!(result.len(), expected.len());
     for (lhs, rhs) in result.into_iter().zip(expected.into_iter()) {
-        assert_eq!(lhs.group, rhs.group);
         assert_eq!(lhs.layout, rhs.layout);
-        assert_eq!(lhs.tail, rhs.tail);
+        assert_eq!(lhs.data, rhs.data);
     }
 }
 
diff --git a/crates/mun_memory/tests/diff/util.rs b/crates/mun_memory/tests/diff/util.rs
index 495855585..77308fe89 100644
--- a/crates/mun_memory/tests/diff/util.rs
+++ b/crates/mun_memory/tests/diff/util.rs
@@ -1,7 +1,7 @@
 #![allow(dead_code)]
 use mun_memory::{
     diff::{myers, Diff, FieldDiff, FieldEditKind},
-    TypeDesc, TypeFields, TypeMemory,
+    TypeDesc, TypeFields, TypeGroup, TypeMemory,
 };
 use std::alloc::Layout;
 
@@ -42,19 +42,18 @@ impl StructInfo {
     }
 }
 
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub enum TypeInfoTail {
-    Empty,
-    Struct(StructInfo),
-}
-
 #[derive(Clone, Debug)]
 pub struct TypeInfo {
     pub name: String,
     pub guid: abi::Guid,
-    pub group: abi::TypeGroup,
     pub layout: Layout,
-    pub tail: TypeInfoTail,
+    pub data: TypeInfoData,
+}
+
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub enum TypeInfoData {
+    Primitive,
+    Struct(StructInfo),
 }
 
 impl TypeInfo {
@@ -63,9 +62,8 @@ impl TypeInfo {
         Self {
             name: type_info.name().to_string(),
             guid: type_info.guid,
-            group: abi::TypeGroup::FundamentalTypes,
             layout: Layout::new::<T>(),
-            tail: TypeInfoTail::Empty,
+            data: TypeInfoData::Primitive,
         }
     }
 
@@ -73,9 +71,8 @@ impl TypeInfo {
         Self {
             name: name.to_string(),
             guid,
-            group: abi::TypeGroup::StructTypes,
             layout: struct_info.layout(),
-            tail: TypeInfoTail::Struct(struct_info),
+            data: TypeInfoData::Struct(struct_info),
         }
     }
 }
@@ -97,8 +94,11 @@ impl TypeDesc for &TypeInfo {
     fn guid(&self) -> &abi::Guid {
         &self.guid
     }
-    fn group(&self) -> abi::TypeGroup {
-        self.group
+    fn group(&self) -> TypeGroup {
+        match self.data {
+            TypeInfoData::Primitive => TypeGroup::Primitive,
+            TypeInfoData::Struct(_) => TypeGroup::Struct,
+        }
     }
 }
 
@@ -115,9 +115,9 @@ impl TypeMemory for &TypeInfo {
 
 impl<'t> TypeFields<&'t TypeInfo> for &'t TypeInfo {
     fn fields(&self) -> Vec<(&str, Self)> {
-        match &self.tail {
-            TypeInfoTail::Empty => Vec::new(),
-            TypeInfoTail::Struct(s) => s
+        match &self.data {
+            TypeInfoData::Primitive => Vec::new(),
+            TypeInfoData::Struct(s) => s
                 .fields
                 .iter()
                 .map(|(name, ty)| (name.as_str(), ty))
@@ -193,8 +193,8 @@ pub(crate) fn apply_diff<'t>(
 }
 
 fn apply_mapping<'t>(old: &mut TypeInfo, new: &TypeInfo, mapping: &[FieldDiff]) {
-    if let TypeInfoTail::Struct(old_struct) = &mut old.tail {
-        if let TypeInfoTail::Struct(new_struct) = &new.tail {
+    if let TypeInfoData::Struct(old_struct) = &mut old.data {
+        if let TypeInfoData::Struct(new_struct) = &new.data {
             let mut combined: Vec<_> = old_struct.fields.iter().cloned().collect();
             for diff in mapping.iter().rev() {
                 match diff {