diff --git a/src/ast.rs b/src/ast.rs
index 76b10cd..7bb7ba4 100644
--- a/src/ast.rs
+++ b/src/ast.rs
@@ -1,9 +1,6 @@
 use std::num::NonZero;
 
-use crate::{
-    ast2::intern,
-    string_table::{self, ImmOrIndex},
-};
+use crate::ast2::intern;
 
 pub type Node = NonZero<u32>;
 
@@ -298,21 +295,14 @@ impl core::fmt::Display for Type {
             Type::Integer(t) => t.fmt(f),
             Type::Floating(t) => t.fmt(f),
             Type::Pointer { constness, pointee } => {
-                write!(
-                    f,
-                    "*{}{}",
-                    if *constness { "const " } else { "" },
-                    pointee
-                )
+                write!(f, "*{}{}", if *constness { "const " } else { "" }, pointee)
             }
             Type::Fn {
                 parameter_types,
                 return_type,
             } => {
                 write!(f, "fn (")?;
-                for param in
-                    parameter_types.iter().map(|p| Some(p)).intersperse(None)
-                {
+                for param in parameter_types.iter().map(|p| Some(p)).intersperse(None) {
                     match param {
                         Some(param) => param.fmt(f)?,
                         None => write!(f, ", ")?,
@@ -351,13 +341,8 @@ impl Type {
                     parameter_types: r_parameter_types,
                     return_type: r_return_type,
                 },
-            ) => {
-                l_parameter_types == r_parameter_types
-                    && l_return_type == r_return_type
-            }
-            _ => {
-                core::mem::discriminant(self) == core::mem::discriminant(other)
-            }
+            ) => l_parameter_types == r_parameter_types && l_return_type == r_return_type,
+            _ => core::mem::discriminant(self) == core::mem::discriminant(other),
         }
     }
     pub fn as_primitive_type(&self) -> Option<PrimitiveType> {
@@ -476,10 +461,9 @@ impl Type {
 
     pub fn can_add_sub(&self) -> bool {
         match self {
-            Type::ComptimeNumber
-            | Type::Pointer { .. }
-            | Type::Floating(_)
-            | Type::Integer(_) => true,
+            Type::ComptimeNumber | Type::Pointer { .. } | Type::Floating(_) | Type::Integer(_) => {
+                true
+            }
             _ => false,
         }
     }
@@ -501,10 +485,9 @@ impl Type {
     }
     pub fn can_cmp(&self) -> bool {
         match self {
-            Type::ComptimeNumber
-            | Type::Pointer { .. }
-            | Type::Floating(_)
-            | Type::Integer(_) => true,
+            Type::ComptimeNumber | Type::Pointer { .. } | Type::Floating(_) | Type::Integer(_) => {
+                true
+            }
             _ => false,
         }
     }
@@ -613,12 +596,7 @@ pub mod tree_visitor {
         pub fn new_range(start: Node, end: Node, pre: F1, post: F2) -> Self {
             Self::new_inner(start, End::Exclusive(end), pre, post)
         }
-        pub fn new_range_inclusive(
-            start: Node,
-            end: Node,
-            pre: F1,
-            post: F2,
-        ) -> Self {
+        pub fn new_range_inclusive(start: Node, end: Node, pre: F1, post: F2) -> Self {
             Self::new_inner(start, End::Inclusive(end), pre, post)
         }
         pub fn new_seek(tree: &Tree, start: Node, pre: F1, post: F2) -> Self {
@@ -717,10 +695,7 @@ pub mod tree_visitor {
         }
 
         /// short-circuits on the first E
-        pub fn visit_ok<T, E>(
-            mut self,
-            tree: &Tree,
-        ) -> core::result::Result<T, E>
+        pub fn visit_ok<T, E>(mut self, tree: &Tree) -> core::result::Result<T, E>
         where
             F1: FnMut(&Tree, Node) -> core::result::Result<T, E>,
             F2: FnMut(&Tree, Node) -> core::result::Result<T, E>,
diff --git a/src/ast2/intern.rs b/src/ast2/intern.rs
index 8b116e3..1795b9a 100644
--- a/src/ast2/intern.rs
+++ b/src/ast2/intern.rs
@@ -180,19 +180,14 @@ impl Display for KeyDisplay<'_> {
                 pointee,
                 flags,
                 length,
-            } => write!(
-                f,
-                "[{flags}{}; {length}]",
-                self.ip.display_key(pointee)
-            )?,
+            } => write!(f, "[{flags}{}; {length}]", self.ip.display_key(pointee))?,
             Key::FunctionType {
                 return_type,
                 ref parameters,
             } => {
                 write!(f, "fn (")?;
 
-                let mut iter =
-                    parameters.iter().map(|&ty| self.ip.display_key(ty));
+                let mut iter = parameters.iter().map(|&ty| self.ip.display_key(ty));
                 let Some(next) = iter.next() else {
                     return Ok(());
                 };
@@ -209,7 +204,10 @@ impl Display for KeyDisplay<'_> {
                 packed,
                 c_like,
                 ref fields,
-            } => todo!(),
+            } => {
+                _ = (decl, name, packed, c_like, fields);
+                todo!()
+            }
             Key::TrueValue => write!(f, "true")?,
             Key::FalseValue => write!(f, "false")?,
         }
@@ -293,9 +291,7 @@ impl PointerFlags {
     }
 
     pub fn pack(self) -> u8 {
-        (self.volatile as u8) << 0
-            | (self.is_const as u8) << 1
-            | (self.noalias as u8) << 2
+        (self.volatile as u8) << 0 | (self.is_const as u8) << 1 | (self.noalias as u8) << 2
     }
     pub fn unpack(packed: u8) -> Self {
         Self {
@@ -325,9 +321,7 @@ impl StructFlags {
     }
     pub fn pack(self) -> u32 {
         assert!(self.num_fields < (1 << 30));
-        (self.packed as u32) << 31
-            | (self.c_like as u32) << 30
-            | self.num_fields & Self::MASK
+        (self.packed as u32) << 31 | (self.c_like as u32) << 30 | self.num_fields & Self::MASK
     }
     pub fn unpack(packed: u32) -> Self {
         Self {
@@ -648,11 +642,7 @@ impl InternPool {
         }
     }
 
-    pub fn to_mir_type(
-        &self,
-        index: Index,
-        _ptr_size: TypeInfo,
-    ) -> crate::mir::Type {
+    pub fn to_mir_type(&self, index: Index, _ptr_size: TypeInfo) -> crate::mir::Type {
         use crate::mir::Type;
         match self.get_key(index) {
             Key::UIntType { bit_width: bits } => {
@@ -765,19 +755,18 @@ impl InternPool {
             Key::FunctionType { .. } => ptr_size,
             Key::StructType { packed, fields, .. } => {
                 // TODO: c-like layout
-                let (size, align) =
-                    fields.iter().fold((0, 0), |(size, align), (_name, ty)| {
-                        let field_size = self.size_of_type(*ty, ptr_size);
-                        let size = size + field_size.bitsize;
+                let (size, align) = fields.iter().fold((0, 0), |(size, align), (_name, ty)| {
+                    let field_size = self.size_of_type(*ty, ptr_size);
+                    let size = size + field_size.bitsize;
 
-                        let size = if packed {
-                            size.next_multiple_of(field_size.bitalign)
-                        } else {
-                            size
-                        };
-                        let align = align.max(field_size.bitalign);
-                        (size, align)
-                    });
+                    let size = if packed {
+                        size.next_multiple_of(field_size.bitalign)
+                    } else {
+                        size
+                    };
+                    let align = align.max(field_size.bitalign);
+                    (size, align)
+                });
 
                 TypeInfo {
                     bitsize: size,
@@ -791,11 +780,7 @@ impl InternPool {
         }
     }
 
-    pub fn insert_ast1_type(
-        &mut self,
-        pointer_bits: u16,
-        ty: &crate::ast::Type,
-    ) -> Index {
+    pub fn insert_ast1_type(&mut self, pointer_bits: u16, ty: &crate::ast::Type) -> Index {
         match ty {
             crate::ast::Type::Bool => self.get_bool_type(),
             crate::ast::Type::ComptimeNumber => self.get_comptime_int_type(),
@@ -806,12 +791,8 @@ impl InternPool {
                     Key::UIntType { bit_width: i.bits }
                 }
             }),
-            crate::ast::Type::Floating(crate::ast::FloatingType::Binary32) => {
-                self.get_f32_type()
-            }
-            crate::ast::Type::Floating(crate::ast::FloatingType::Binary64) => {
-                self.get_f64_type()
-            }
+            crate::ast::Type::Floating(crate::ast::FloatingType::Binary32) => self.get_f32_type(),
+            crate::ast::Type::Floating(crate::ast::FloatingType::Binary64) => self.get_f64_type(),
             crate::ast::Type::Pointer { constness, pointee } => {
                 let pointee = self.insert_ast1_type(pointer_bits, &pointee);
                 self.get_or_insert(Key::PointerType {
@@ -827,8 +808,7 @@ impl InternPool {
                     .iter()
                     .map(|ty| self.insert_ast1_type(pointer_bits, ty))
                     .collect::<Vec<_>>();
-                let return_type =
-                    self.from_ast1_type(pointer_bits, &return_type);
+                let return_type = self.from_ast1_type(pointer_bits, &return_type);
                 self.get_or_insert(Key::FunctionType {
                     return_type,
                     parameters,
@@ -841,11 +821,7 @@ impl InternPool {
         }
     }
 
-    pub fn from_ast1_type(
-        &self,
-        pointer_bits: u16,
-        ty: &crate::ast::Type,
-    ) -> Index {
+    pub fn from_ast1_type(&self, pointer_bits: u16, ty: &crate::ast::Type) -> Index {
         match ty {
             crate::ast::Type::Bool => self.get_bool_type(),
             crate::ast::Type::ComptimeNumber => self.get_comptime_int_type(),
@@ -856,12 +832,8 @@ impl InternPool {
                     Key::UIntType { bit_width: i.bits }
                 }
             }),
-            crate::ast::Type::Floating(crate::ast::FloatingType::Binary32) => {
-                self.get_f32_type()
-            }
-            crate::ast::Type::Floating(crate::ast::FloatingType::Binary64) => {
-                self.get_f64_type()
-            }
+            crate::ast::Type::Floating(crate::ast::FloatingType::Binary32) => self.get_f32_type(),
+            crate::ast::Type::Floating(crate::ast::FloatingType::Binary64) => self.get_f64_type(),
             crate::ast::Type::Pointer { constness, pointee } => {
                 let pointee = self.from_ast1_type(pointer_bits, &pointee);
                 self.get_assume_present(&Key::PointerType {
@@ -877,8 +849,7 @@ impl InternPool {
                     .iter()
                     .map(|ty| self.from_ast1_type(pointer_bits, ty))
                     .collect::<Vec<_>>();
-                let return_type =
-                    self.from_ast1_type(pointer_bits, &return_type);
+                let return_type = self.from_ast1_type(pointer_bits, &return_type);
                 self.get_assume_present(&Key::FunctionType {
                     return_type,
                     parameters,
@@ -891,34 +862,18 @@ impl InternPool {
         }
     }
 
-    pub fn as_ast1_type(
-        &self,
-        pointer_bits: u16,
-        index: Index,
-    ) -> crate::ast::Type {
+    pub fn as_ast1_type(&self, pointer_bits: u16, index: Index) -> crate::ast::Type {
         use crate::ast::Type;
         match self.get_key(index) {
-            Key::UIntType { bit_width: bits } => {
-                Type::Integer(IntegralType::new(false, bits))
-            }
-            Key::SIntType { bit_width: bits } => {
-                Type::Integer(IntegralType::new(true, bits))
-            }
+            Key::UIntType { bit_width: bits } => Type::Integer(IntegralType::new(false, bits)),
+            Key::SIntType { bit_width: bits } => Type::Integer(IntegralType::new(true, bits)),
             Key::SimpleType { ty } => match ty {
-                SimpleType::F32 => {
-                    Type::Floating(crate::ast::FloatingType::Binary32)
-                }
-                SimpleType::F64 => {
-                    Type::Floating(crate::ast::FloatingType::Binary64)
-                }
+                SimpleType::F32 => Type::Floating(crate::ast::FloatingType::Binary32),
+                SimpleType::F64 => Type::Floating(crate::ast::FloatingType::Binary64),
                 SimpleType::Bool => Type::Bool,
                 SimpleType::Void => Type::Void,
-                SimpleType::USize => {
-                    Type::Integer(IntegralType::new(false, pointer_bits))
-                }
-                SimpleType::ISize => {
-                    Type::Integer(IntegralType::new(true, pointer_bits))
-                }
+                SimpleType::USize => Type::Integer(IntegralType::new(false, pointer_bits)),
+                SimpleType::ISize => Type::Integer(IntegralType::new(true, pointer_bits)),
                 SimpleType::ComptimeInt => Type::comptime_number(),
             },
             Key::PointerType { pointee, flags } => Type::Pointer {
@@ -933,9 +888,7 @@ impl InternPool {
                     .into_iter()
                     .map(|i| self.as_ast1_type(pointer_bits, i))
                     .collect(),
-                return_type: Box::new(
-                    self.as_ast1_type(pointer_bits, return_type),
-                ),
+                return_type: Box::new(self.as_ast1_type(pointer_bits, return_type)),
             },
             _ => unimplemented!(),
         }
@@ -1008,12 +961,8 @@ impl InternPool {
                 let words_idx = self.extend_words([start, len]);
                 self.create_item(Tag::String, words_idx)
             }
-            Key::SIntSmall { bits } => {
-                self.create_item(Tag::SIntSmall, bits as u32)
-            }
-            Key::UIntSmall { bits } => {
-                self.create_item(Tag::UIntSmall, bits as u32)
-            }
+            Key::SIntSmall { bits } => self.create_item(Tag::SIntSmall, bits as u32),
+            Key::UIntSmall { bits } => self.create_item(Tag::UIntSmall, bits as u32),
             Key::F32 { bits } => self.create_item(Tag::F32, bits as u32),
             Key::F64 { bits } => {
                 let (lo, hi) = into_lo_hi_dwords(bits as u64);
@@ -1043,19 +992,12 @@ impl InternPool {
                 self.create_item(Tag::NegativeInt, i)
             }
 
-            Key::UIntType { bit_width: bits } => {
-                self.create_item(Tag::UIntType, bits as u32)
-            }
-            Key::SIntType { bit_width: bits } => {
-                self.create_item(Tag::SIntType, bits as u32)
-            }
-            Key::SimpleType { ty } => {
-                self.create_item(Tag::SimpleType, ty as u8 as u32)
-            }
+            Key::UIntType { bit_width: bits } => self.create_item(Tag::UIntType, bits as u32),
+            Key::SIntType { bit_width: bits } => self.create_item(Tag::SIntType, bits as u32),
+            Key::SimpleType { ty } => self.create_item(Tag::SimpleType, ty as u8 as u32),
             Key::PointerType { pointee, flags } => {
                 let flags = flags.pack();
-                let i =
-                    self.extend_words([pointee.index() as u32, flags as u32]);
+                let i = self.extend_words([pointee.index() as u32, flags as u32]);
                 self.create_item(Tag::PointerType, i)
             }
             Key::ArrayType {
@@ -1064,11 +1006,7 @@ impl InternPool {
                 length,
             } => {
                 let flags = flags.pack();
-                let i = self.extend_words([
-                    pointee.index() as u32,
-                    flags as u32,
-                    length,
-                ]);
+                let i = self.extend_words([pointee.index() as u32, flags as u32, length]);
                 self.create_item(Tag::ArrayType, i)
             }
             Key::StructType {
@@ -1078,15 +1016,8 @@ impl InternPool {
                 c_like,
                 fields,
             } => {
-                let flags =
-                    StructFlags::new(packed, c_like, fields.len() as u32)
-                        .pack();
-                let i = self.extend_words([
-                    name.into_u32(),
-                    decl.into_u32(),
-                    flags,
-                    u32::MAX,
-                ]);
+                let flags = StructFlags::new(packed, c_like, fields.len() as u32).pack();
+                let i = self.extend_words([name.into_u32(), decl.into_u32(), flags, u32::MAX]);
                 if !fields.is_empty() {
                     let fields_offset = self.extend_words(
                         fields
@@ -1109,9 +1040,7 @@ impl InternPool {
 
                 let start = self.push_word(info.pack());
                 self.extend_words([return_type.into_u32()]);
-                _ = self.extend_words(
-                    parameters.into_iter().map(|i| i.index() as u32),
-                );
+                _ = self.extend_words(parameters.into_iter().map(|i| i.index() as u32));
 
                 self.create_item(Tag::FunctionType, start)
             }
@@ -1150,9 +1079,7 @@ impl InternPool {
                 let start = self.words[item.idx()];
                 let len = self.words[item.idx() + 1];
                 let str = unsafe {
-                    core::str::from_utf8_unchecked(
-                        &self.strings[start as usize..][..len as usize],
-                    )
+                    core::str::from_utf8_unchecked(&self.strings[start as usize..][..len as usize])
                 };
                 Key::String { str }
             }
@@ -1167,24 +1094,18 @@ impl InternPool {
             },
             Tag::F64 => {
                 let idx = item.idx();
-                let bits =
-                    from_lo_hi_dwords(self.words[idx], self.words[idx + 1]);
+                let bits = from_lo_hi_dwords(self.words[idx], self.words[idx + 1]);
                 Key::F64 {
                     bits: f64::from_le_bytes(bits.to_le_bytes()),
                 }
             }
             Tag::SInt64 => {
-                let bits = from_lo_hi_dwords(
-                    self.words[item.idx()],
-                    self.words[item.idx() + 1],
-                ) as i64;
+                let bits =
+                    from_lo_hi_dwords(self.words[item.idx()], self.words[item.idx() + 1]) as i64;
                 Key::SInt64 { bits }
             }
             Tag::UInt64 => {
-                let bits = from_lo_hi_dwords(
-                    self.words[item.idx()],
-                    self.words[item.idx() + 1],
-                );
+                let bits = from_lo_hi_dwords(self.words[item.idx()], self.words[item.idx() + 1]);
                 Key::UInt64 { bits }
             }
             Tag::NegativeInt => {
@@ -1218,15 +1139,13 @@ impl InternPool {
             }
             Tag::PointerType => {
                 let pointee = Index::new(self.words[item.idx()]);
-                let flags =
-                    PointerFlags::unpack(self.words[item.idx() + 1] as u8);
+                let flags = PointerFlags::unpack(self.words[item.idx() + 1] as u8);
 
                 Key::PointerType { pointee, flags }
             }
             Tag::ArrayType => {
                 let pointee = Index::new(self.words[item.idx()]);
-                let flags =
-                    PointerFlags::unpack(self.words[item.idx() + 1] as u8);
+                let flags = PointerFlags::unpack(self.words[item.idx() + 1] as u8);
                 let length = self.words[item.idx() + 2];
 
                 Key::ArrayType {
@@ -1237,12 +1156,11 @@ impl InternPool {
             }
             Tag::StructType => {
                 let name = Index::new(self.words[item.idx()]);
-                let decl = super::Index::new(self.words[item.idx() + 1]);
+                let decl = super::Index::from_u32(self.words[item.idx() + 1]).unwrap();
                 let flags = StructFlags::unpack(self.words[item.idx() + 2]);
                 let fields = if flags.num_fields != 0 {
                     let fields_offset = self.words[item.idx() + 3] as usize;
-                    let fields_end =
-                        fields_offset + flags.num_fields as usize * 2;
+                    let fields_end = fields_offset + flags.num_fields as usize * 2;
 
                     self.words[fields_offset..fields_end]
                         .iter()
@@ -1322,9 +1240,7 @@ impl InternPool {
 
     pub fn get_unsigned_integer(&mut self, value: u64) -> Index {
         let key = match value {
-            _ if value <= u32::MAX as u64 => {
-                Key::UIntSmall { bits: value as u32 }
-            }
+            _ if value <= u32::MAX as u64 => Key::UIntSmall { bits: value as u32 },
             _ => Key::UInt64 { bits: value as u64 },
         };
 
@@ -1381,11 +1297,7 @@ impl InternPool {
         })
     }
 
-    pub fn get_pointer_type(
-        &mut self,
-        pointee: Index,
-        flags: Option<PointerFlags>,
-    ) -> Index {
+    pub fn get_pointer_type(&mut self, pointee: Index, flags: Option<PointerFlags>) -> Index {
         let key = Key::PointerType {
             pointee,
             flags: flags.unwrap_or_default(),
@@ -1405,9 +1317,7 @@ impl InternPool {
         )
     }
 
-    pub fn insert_or_replace_struct_type<
-        I: IntoIterator<Item = (Index, Index)>,
-    >(
+    pub fn insert_or_replace_struct_type<I: IntoIterator<Item = (Index, Index)>>(
         &mut self,
         name: Index,
         decl: super::Index,
@@ -1422,8 +1332,7 @@ impl InternPool {
             c_like,
             fields: vec![],
         };
-        if let Some(i) = self.try_get_index(&key).and_then(|i| self.get_item(i))
-        {
+        if let Some(i) = self.try_get_index(&key).and_then(|i| self.get_item(i)) {
             let fields_offset = self.extend_words(
                 fields
                     .into_iter()
@@ -1439,11 +1348,7 @@ impl InternPool {
         self.get_or_insert(key)
     }
 
-    pub fn get_struct_type(
-        &mut self,
-        name: Index,
-        decl: super::Index,
-    ) -> Index {
+    pub fn get_struct_type(&mut self, name: Index, decl: super::Index) -> Index {
         let key = Key::StructType {
             name,
             decl,
@@ -1453,11 +1358,7 @@ impl InternPool {
         };
         self.get_or_insert(key)
     }
-    pub fn try_get_struct_type(
-        &self,
-        name: Index,
-        decl: super::Index,
-    ) -> Option<Index> {
+    pub fn try_get_struct_type(&self, name: Index, decl: super::Index) -> Option<Index> {
         self.try_get_index(&Key::StructType {
             name,
             decl,
diff --git a/src/ast2/mod.rs b/src/ast2/mod.rs
index 7fb873e..02690a1 100644
--- a/src/ast2/mod.rs
+++ b/src/ast2/mod.rs
@@ -3,21 +3,20 @@
 use std::{
     collections::BTreeMap,
     fmt::{Debug, Display},
-    num::NonZero,
 };
 
 use intern::{InternPool, PointerFlags, StructFlags, AMD64_POINTER_TYPE_INFO};
 use num_bigint::BigInt;
 
 use crate::{
-    ast::FloatingType, comptime::ComptimeNumber, lexer::SourceLocation,
-    tokens::Token, writeln_indented,
+    ast::FloatingType, comptime::ComptimeNumber, lexer::SourceLocation, tokens::Token,
+    writeln_indented,
 };
 
 pub mod intern;
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-enum Tag {
+pub enum Tag {
     /// pseudo tag, contains a range from a..b into extra of all files.
     Root,
     /// `data` is a range from a..b into extra of all global nodes.
@@ -217,31 +216,6 @@ enum ParseError {
     ErrorNode(Index),
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[repr(transparent)]
-pub struct Index(NonZero<u32>);
-
-impl Display for Index {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "%{}", self.0.get())
-    }
-}
-
-impl Index {
-    pub fn new(i: u32) -> Index {
-        Self(NonZero::<u32>::new(i).unwrap())
-    }
-    pub fn as_u32(&self) -> &u32 {
-        unsafe { core::mem::transmute(self) }
-    }
-    pub fn into_u32(self) -> u32 {
-        unsafe { core::mem::transmute(self) }
-    }
-    fn index(self) -> usize {
-        self.0.get() as usize
-    }
-}
-
 #[repr(packed)]
 #[derive(Clone, Copy)]
 struct Node {
@@ -251,7 +225,7 @@ struct Node {
 }
 
 #[derive(Clone, Copy)]
-union Data {
+pub union Data {
     none: (),
     error: ParseError,
     index: Index,
@@ -266,6 +240,23 @@ union Data {
     index_and_opaque: (Index, u32),
 }
 
+impl Default for Tag {
+    fn default() -> Self {
+        Tag::Undefined
+    }
+}
+impl Default for SourceLocation {
+    fn default() -> Self {
+        Self::invalid()
+    }
+}
+
+impl Default for Data {
+    fn default() -> Self {
+        Self::none()
+    }
+}
+
 #[derive(Debug)]
 #[allow(dead_code)]
 enum ExpandedData {
@@ -346,9 +337,7 @@ impl From<(Tag, Data)> for ExpandedData {
             | Tag::MutVarDeclAssignment
             | Tag::BlockTrailingExpr
             | Tag::Block => Self::from_extra_range(data),
-            Tag::FieldDecl | Tag::Constant | Tag::Parameter => {
-                Self::from_index_intern(data)
-            }
+            Tag::FieldDecl | Tag::Constant | Tag::Parameter => Self::from_index_intern(data),
             Tag::Or
             | Tag::And
             | Tag::BitOr
@@ -389,9 +378,7 @@ impl From<(Tag, Data)> for ExpandedData {
             | Tag::ExplicitCast => Self::from_index_intern(data),
             Tag::GlobalDecl => Self::from_intern_and_extra_offset(data),
             Tag::InternedType | Tag::StructDecl => Self::from_intern(data),
-            Tag::PointerType | Tag::IfElseExpr => {
-                Self::from_index_and_extra_offset(data)
-            }
+            Tag::PointerType | Tag::IfElseExpr => Self::from_index_and_extra_offset(data),
             Tag::Error => Self::from_error(data),
             Tag::ReturnStmt | Tag::Undefined => Self::from_none(),
         }
@@ -493,11 +480,203 @@ impl Data {
     }
 }
 
+mod index {
+    use std::num::NonZero;
+
+    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
+    #[repr(u8)]
+    pub enum Kind {
+        Other = 0,
+        Function,
+        GlobalDecl,
+        Error,
+        File,
+    }
+
+    impl TryFrom<u8> for Kind {
+        type Error = ();
+
+        fn try_from(value: u8) -> Result<Self, ()> {
+            match value {
+                0 => Ok(Self::Other),
+                1 => Ok(Self::Function),
+                2 => Ok(Self::GlobalDecl),
+                3 => Ok(Self::Error),
+                4 => Ok(Self::File),
+                _ => Err(()),
+            }
+        }
+    }
+
+    /// Index type that has 28 bits of index and 4 bits of kind.
+    #[repr(transparent)]
+    #[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
+    pub struct Index(NonZero<u32>);
+
+    impl core::fmt::Debug for Index {
+        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+            f.debug_struct("Index")
+                .field("kind", &self.kind())
+                .field("index", &self.index_u32())
+                .finish()
+        }
+    }
+
+    impl core::fmt::Display for Index {
+        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+            let label = match self.kind() {
+                Kind::Other => "",
+                Kind::Function => "funcs.",
+                Kind::GlobalDecl => "gdecls.",
+                Kind::Error => "errors.",
+                Kind::File => "files.",
+            };
+
+            write!(f, "%{label}{}", self.index_u32())
+        }
+    }
+
+    impl Index {
+        pub fn new(kind: Kind, idx: u32) -> Option<Self> {
+            let inner = NonZero::new((kind as u32) << 28 | idx & ((1 << 28) - 1));
+
+            inner.map(Self)
+        }
+        pub fn kind(&self) -> Kind {
+            Kind::try_from(((self.0.get() >> 28) & 0b1111) as u8).unwrap()
+        }
+        pub fn index_u32(&self) -> u32 {
+            self.0.get() & ((1 << 28) - 1)
+        }
+        pub fn index_usize(&self) -> usize {
+            self.index_u32() as usize
+        }
+        pub fn from_u32(inner: u32) -> Option<Self> {
+            NonZero::new(inner).map(Self)
+        }
+        pub unsafe fn from_u32_unchecked(inner: u32) -> Self {
+            Self(NonZero::new_unchecked(inner))
+        }
+        pub fn as_u32(self) -> u32 {
+            self.0.get()
+        }
+        pub fn into_u32(self) -> u32 {
+            self.0.get()
+        }
+    }
+}
+
+pub use index::{Index, Kind};
+
+#[derive(Debug, Clone)]
+struct AstTables<T> {
+    functions: Vec<T>,
+    global_decls: Vec<T>,
+    errors: Vec<T>,
+    files: Vec<T>,
+    other: Vec<T>,
+}
+
+impl<T> core::ops::Index<index::Index> for AstTables<T> {
+    type Output = T;
+
+    fn index(&self, index: index::Index) -> &Self::Output {
+        &self.table_ref(index.kind())[index.index_usize()]
+    }
+}
+
+impl<T> core::ops::IndexMut<index::Index> for AstTables<T> {
+    fn index_mut(&mut self, index: index::Index) -> &mut Self::Output {
+        &mut self.table_mut(index.kind())[index.index_usize()]
+    }
+}
+
+impl<T> AstTables<T> {
+    fn new() -> Self {
+        Self {
+            functions: Vec::new(),
+            global_decls: Vec::new(),
+            errors: Vec::new(),
+            files: Vec::new(),
+            other: Vec::new(),
+        }
+    }
+
+    fn get(&self, index: index::Index) -> Option<&T> {
+        self.table_ref(index.kind()).get(index.index_usize())
+    }
+    unsafe fn get_unchecked(&self, index: index::Index) -> &T {
+        self.table_ref(index.kind())
+            .get_unchecked(index.index_usize())
+    }
+
+    fn init() -> Self
+    where
+        T: Default,
+    {
+        Self {
+            functions: Vec::new(),
+            global_decls: Vec::new(),
+            errors: Vec::new(),
+            files: Vec::new(),
+            other: vec![T::default()],
+        }
+    }
+
+    fn push(&mut self, kind: index::Kind, t: T) -> index::Index {
+        let table = self.table_mut(kind);
+        let i = table.len();
+        table.push(t);
+
+        index::Index::new(kind, i as u32).unwrap()
+    }
+
+    fn reserve(&mut self, kind: index::Kind) -> index::Index
+    where
+        T: Default,
+    {
+        self.push(kind, T::default())
+    }
+
+    fn table_mut(&mut self, kind: index::Kind) -> &mut Vec<T> {
+        match kind {
+            index::Kind::Other => &mut self.other,
+            index::Kind::Function => &mut self.functions,
+            index::Kind::GlobalDecl => &mut self.global_decls,
+            index::Kind::Error => &mut self.errors,
+            index::Kind::File => &mut self.files,
+        }
+    }
+
+    fn table_ref(&self, kind: index::Kind) -> &Vec<T> {
+        match kind {
+            index::Kind::Other => &self.other,
+            index::Kind::Function => &self.functions,
+            index::Kind::GlobalDecl => &self.global_decls,
+            index::Kind::Error => &self.errors,
+            index::Kind::File => &self.files,
+        }
+    }
+
+    fn table_len(&self, kind: index::Kind) -> usize {
+        self.table_ref(kind).len()
+    }
+
+    fn iter(&self) -> impl Iterator<Item = &T> {
+        self.errors
+            .iter()
+            .chain(self.files.iter())
+            .chain(self.functions.iter())
+            .chain(self.global_decls.iter())
+            .chain(self.other.iter())
+    }
+}
+
 pub struct Ast {
-    tags: Vec<Tag>,
-    datas: Vec<Data>,
+    tags: AstTables<Tag>,
+    datas: AstTables<Data>,
+    source_locs: AstTables<SourceLocation>,
     extra: Vec<u32>,
-    source_locs: Vec<SourceLocation>,
 }
 
 impl Debug for Ast {
@@ -507,10 +686,7 @@ impl Debug for Ast {
                 let mut list = f.debug_list();
                 struct LocDisplay(SourceLocation);
                 impl Debug for LocDisplay {
-                    fn fmt(
-                        &self,
-                        f: &mut std::fmt::Formatter<'_>,
-                    ) -> std::fmt::Result {
+                    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                         write!(f, "({})", self.0)
                     }
                 }
@@ -522,12 +698,7 @@ impl Debug for Ast {
                     .zip(self.source_locs.iter().cloned())
                     .enumerate()
                     .map(|(i, ((tag, data), loc))| {
-                        (
-                            i,
-                            tag,
-                            ExpandedData::from((tag, data)),
-                            LocDisplay(loc),
-                        )
+                        (i, tag, ExpandedData::from((tag, data)), LocDisplay(loc))
                     });
                 list.entries(entries).finish()
             })
@@ -538,69 +709,68 @@ impl Debug for Ast {
 
 impl Ast {
     fn new() -> Ast {
+        let mut tags = AstTables::new();
+        let mut datas = AstTables::new();
+        let mut source_locs = AstTables::new();
+
+        tags.other.push(Tag::Root);
+        datas.other.push(Data::extra_range(0, 0));
+        source_locs.other.push(SourceLocation::new(0, 0));
+
         Self {
-            tags: vec![Tag::Root],
-            datas: vec![Data::extra_range(0, 0)],
+            tags,
+            datas,
             extra: vec![],
-            source_locs: vec![SourceLocation::new(0, 0)],
+            source_locs,
         }
     }
 
-    fn reserve_node(&mut self) -> Index {
-        let i =
-            unsafe { Index(NonZero::new_unchecked(self.tags.len() as u32)) };
-        self.tags.push(Tag::Undefined);
-        self.datas.push(Data::none());
-        self.source_locs.push(SourceLocation::invalid());
+    fn reserve_node_other(&mut self) -> Index {
+        self.reserve_node(Kind::Other)
+    }
+
+    fn reserve_node(&mut self, kind: index::Kind) -> Index {
+        let i = self.tags.reserve(kind);
+        self.datas.reserve(kind);
+        self.source_locs.reserve(kind);
 
         i
     }
 
     fn get_loc(&self, index: Index) -> SourceLocation {
-        self.source_locs[index.index()]
+        self.source_locs[index]
     }
 
     fn push_error(&mut self, error: ParseError, loc: SourceLocation) -> Index {
-        let i = self.reserve_node();
+        let i = self.reserve_node(Kind::Error);
         self.set_tag_data_source_loc(i, Tag::Error, Data::error(error), loc);
 
         i
     }
 
-    fn set_file<I: IntoIterator<Item = Index>>(
-        &mut self,
-        i: Index,
-        decls: I,
-        loc: SourceLocation,
-    ) {
+    fn set_file<I: IntoIterator<Item = Index>>(&mut self, i: Index, decls: I, loc: SourceLocation) {
         let (extra_start, extra_end) = self.extend_extra_by_indices(decls);
-        self.set_tag_data_source_loc(
-            i,
-            Tag::File,
-            Data::extra_range(extra_start, extra_end),
-            loc,
-        );
+        self.set_tag_data_source_loc(i, Tag::File, Data::extra_range(extra_start, extra_end), loc);
     }
 
-    fn push_file<I: IntoIterator<Item = Index>>(
-        &mut self,
-        decls: I,
-        loc: SourceLocation,
-    ) -> Index {
-        let i = self.reserve_node();
+    fn push_file<I: IntoIterator<Item = Index>>(&mut self, decls: I, loc: SourceLocation) -> Index {
+        let i = self.reserve_node(Kind::File);
         self.set_file(i, decls, loc);
         i
     }
 
     fn set_root<I: IntoIterator<Item = Index>>(&mut self, decls: I) {
         let (extra_start, extra_end) = self.extend_extra_by_indices(decls);
-        self.tags[0] = Tag::Root;
-        self.datas[0] = Data::extra_range(extra_start, extra_end);
+        self.tags.other[0] = Tag::Root;
+        self.datas.other[0] = Data::extra_range(extra_start, extra_end);
     }
 
     fn get_root_file_indices<'a>(&'a self) -> impl Iterator<Item = Index> + 'a {
-        let (a, b) = self.datas[0].as_extra_range();
-        self.extra[a..b].iter().cloned().map(|i| Index::new(i))
+        let (a, b) = self.datas.other[0].as_extra_range();
+        self.extra[a..b]
+            .iter()
+            .cloned()
+            .map(|i| Index::from_u32(i).unwrap())
     }
 
     fn push_global_decl(
@@ -610,9 +780,8 @@ impl Ast {
         expr: Index,
         loc: SourceLocation,
     ) -> Index {
-        let i = self.reserve_node();
-        let (extra_start, _) =
-            self.extend_extra([ty.into_u32(), expr.into_u32()]);
+        let i = self.reserve_node(Kind::GlobalDecl);
+        let (extra_start, _) = self.extend_extra([ty.into_u32(), expr.into_u32()]);
         self.set_tag_data_source_loc(
             i,
             Tag::GlobalDecl,
@@ -623,47 +792,23 @@ impl Ast {
         i
     }
 
-    fn set_fn_decl(
-        &mut self,
-        i: Index,
-        proto: Index,
-        body: Index,
-        loc: SourceLocation,
-    ) {
-        self.set_tag_data_source_loc(
-            i,
-            Tag::FunctionDecl,
-            Data::two_indices(proto, body),
-            loc,
-        );
+    fn set_fn_decl(&mut self, i: Index, proto: Index, body: Index, loc: SourceLocation) {
+        self.set_tag_data_source_loc(i, Tag::FunctionDecl, Data::two_indices(proto, body), loc);
     }
 
-    fn push_fn_decl(
-        &mut self,
-        proto: Index,
-        body: Index,
-        loc: SourceLocation,
-    ) -> Index {
-        let i = self.reserve_node();
+    fn push_fn_decl(&mut self, proto: Index, body: Index, loc: SourceLocation) -> Index {
+        let i = self.reserve_node(Kind::Function);
         self.set_fn_decl(i, proto, body, loc);
         i
     }
 
     fn push_ret(&mut self, expr: Option<Index>, loc: SourceLocation) -> Index {
-        let i = self.reserve_node();
+        let i = self.reserve_node(Kind::Other);
         match expr {
-            Some(expr) => self.set_tag_data_source_loc(
-                i,
-                Tag::ReturnExprStmt,
-                Data::index(expr),
-                loc,
-            ),
-            None => self.set_tag_data_source_loc(
-                i,
-                Tag::ReturnStmt,
-                Data::none(),
-                loc,
-            ),
+            Some(expr) => {
+                self.set_tag_data_source_loc(i, Tag::ReturnExprStmt, Data::index(expr), loc)
+            }
+            None => self.set_tag_data_source_loc(i, Tag::ReturnStmt, Data::none(), loc),
         }
 
         i
@@ -677,7 +822,7 @@ impl Ast {
         assignment: Option<Index>,
         loc: SourceLocation,
     ) -> Index {
-        let i = self.reserve_node();
+        let i = self.reserve_node_other();
 
         let start = self.extra.len() as u32;
         self.extra.push(name.into_u32());
@@ -692,12 +837,7 @@ impl Ast {
             (false, true) => Tag::MutVarDeclAssignment,
         };
 
-        self.set_tag_data_source_loc(
-            i,
-            tag,
-            Data::extra_range(start, end),
-            loc,
-        );
+        self.set_tag_data_source_loc(i, tag, Data::extra_range(start, end), loc);
 
         i
     }
@@ -709,9 +849,9 @@ impl Ast {
         parameter_list: Index,
         loc: SourceLocation,
     ) -> Index {
-        let i = self.reserve_node();
-        let (extra_start, _) = self
-            .extend_extra([return_type.into_u32(), parameter_list.into_u32()]);
+        let i = self.reserve_node_other();
+        let (extra_start, _) =
+            self.extend_extra([return_type.into_u32(), parameter_list.into_u32()]);
         self.set_tag_data_source_loc(
             i,
             Tag::FunctionProto,
@@ -729,9 +869,8 @@ impl Ast {
         trailing: Option<Index>,
         loc: SourceLocation,
     ) {
-        let (extra_start, extra_end) = self.extend_extra_by_indices(
-            statements.into_iter().chain(trailing.into_iter()),
-        );
+        let (extra_start, extra_end) =
+            self.extend_extra_by_indices(statements.into_iter().chain(trailing.into_iter()));
         if trailing.is_some() {
             self.set_tag_data_source_loc(
                 i,
@@ -755,7 +894,7 @@ impl Ast {
         trailing: Option<Index>,
         loc: SourceLocation,
     ) -> Index {
-        let i = self.reserve_node();
+        let i = self.reserve_node_other();
         self.set_block(i, statements, trailing, loc);
         i
     }
@@ -765,7 +904,7 @@ impl Ast {
         parameters: I,
         loc: SourceLocation,
     ) -> Index {
-        let i = self.reserve_node();
+        let i = self.reserve_node_other();
         let (extra_start, extra_end) = self.extend_extra_by_indices(parameters);
         self.set_tag_data_source_loc(
             i,
@@ -778,7 +917,7 @@ impl Ast {
     }
 
     fn push_argument(&mut self, expr: Index, loc: SourceLocation) -> Index {
-        let i = self.reserve_node();
+        let i = self.reserve_node_other();
         self.set_tag_data_source_loc(i, Tag::Argument, Data::index(expr), loc);
 
         i
@@ -790,7 +929,7 @@ impl Ast {
         expr: Index,
         loc: SourceLocation,
     ) -> Index {
-        let i = self.reserve_node();
+        let i = self.reserve_node_other();
         self.set_tag_data_source_loc(
             i,
             Tag::NamedArgument,
@@ -801,19 +940,9 @@ impl Ast {
         i
     }
 
-    fn push_parameter(
-        &mut self,
-        name: intern::Index,
-        ty: Index,
-        loc: SourceLocation,
-    ) -> Index {
-        let i = self.reserve_node();
-        self.set_tag_data_source_loc(
-            i,
-            Tag::Parameter,
-            Data::index_and_intern(ty, name),
-            loc,
-        );
+    fn push_parameter(&mut self, name: intern::Index, ty: Index, loc: SourceLocation) -> Index {
+        let i = self.reserve_node_other();
+        self.set_tag_data_source_loc(i, Tag::Parameter, Data::index_and_intern(ty, name), loc);
 
         i
     }
@@ -823,7 +952,7 @@ impl Ast {
         args: I,
         loc: SourceLocation,
     ) -> Index {
-        let i = self.reserve_node();
+        let i = self.reserve_node_other();
         let (extra_start, extra_end) = self.extend_extra_by_indices(args);
         self.set_tag_data_source_loc(
             i,
@@ -835,78 +964,37 @@ impl Ast {
         i
     }
 
-    fn push_unary(
-        &mut self,
-        tag: Tag,
-        lhs: Index,
-        loc: SourceLocation,
-    ) -> Index {
-        let i = self.reserve_node();
+    fn push_unary(&mut self, tag: Tag, lhs: Index, loc: SourceLocation) -> Index {
+        let i = self.reserve_node_other();
         self.set_tag_data_source_loc(i, tag, Data::index(lhs), loc);
 
         i
     }
 
-    fn push_binary(
-        &mut self,
-        tag: Tag,
-        lhs: Index,
-        rhs: Index,
-        loc: SourceLocation,
-    ) -> Index {
-        let i = self.reserve_node();
+    fn push_binary(&mut self, tag: Tag, lhs: Index, rhs: Index, loc: SourceLocation) -> Index {
+        let i = self.reserve_node_other();
         self.set_tag_data_source_loc(i, tag, Data::two_indices(lhs, rhs), loc);
 
         i
     }
 
-    fn push_assign(
-        &mut self,
-        lhs: Index,
-        rhs: Index,
-        loc: SourceLocation,
-    ) -> Index {
-        let i = self.reserve_node();
-        self.set_tag_data_source_loc(
-            i,
-            Tag::Assign,
-            Data::two_indices(lhs, rhs),
-            loc,
-        );
+    fn push_assign(&mut self, lhs: Index, rhs: Index, loc: SourceLocation) -> Index {
+        let i = self.reserve_node_other();
+        self.set_tag_data_source_loc(i, Tag::Assign, Data::two_indices(lhs, rhs), loc);
 
         i
     }
 
-    fn push_cast(
-        &mut self,
-        lhs: Index,
-        ty: Index,
-        loc: SourceLocation,
-    ) -> Index {
-        let i = self.reserve_node();
-        self.set_tag_data_source_loc(
-            i,
-            Tag::ExplicitCast,
-            Data::two_indices(lhs, ty),
-            loc,
-        );
+    fn push_cast(&mut self, lhs: Index, ty: Index, loc: SourceLocation) -> Index {
+        let i = self.reserve_node_other();
+        self.set_tag_data_source_loc(i, Tag::ExplicitCast, Data::two_indices(lhs, ty), loc);
 
         i
     }
 
-    fn push_if(
-        &mut self,
-        cond: Index,
-        body: Index,
-        loc: SourceLocation,
-    ) -> Index {
-        let i = self.reserve_node();
-        self.set_tag_data_source_loc(
-            i,
-            Tag::IfExpr,
-            Data::two_indices(cond, body),
-            loc,
-        );
+    fn push_if(&mut self, cond: Index, body: Index, loc: SourceLocation) -> Index {
+        let i = self.reserve_node_other();
+        self.set_tag_data_source_loc(i, Tag::IfExpr, Data::two_indices(cond, body), loc);
 
         i
     }
@@ -918,7 +1006,7 @@ impl Ast {
         other: Index,
         loc: SourceLocation,
     ) -> Index {
-        let i = self.reserve_node();
+        let i = self.reserve_node_other();
         let (extra_start, _) = self.extend_extra_by_indices([body, other]);
         self.set_tag_data_source_loc(
             i,
@@ -930,19 +1018,9 @@ impl Ast {
         i
     }
 
-    fn push_call_expr(
-        &mut self,
-        lhs: Index,
-        args: Index,
-        loc: SourceLocation,
-    ) -> Index {
-        let i = self.reserve_node();
-        self.set_tag_data_source_loc(
-            i,
-            Tag::CallExpr,
-            Data::two_indices(lhs, args),
-            loc,
-        );
+    fn push_call_expr(&mut self, lhs: Index, args: Index, loc: SourceLocation) -> Index {
+        let i = self.reserve_node_other();
+        self.set_tag_data_source_loc(i, Tag::CallExpr, Data::two_indices(lhs, args), loc);
 
         i
     }
@@ -953,7 +1031,7 @@ impl Ast {
         ident: intern::Index,
         loc: SourceLocation,
     ) -> Index {
-        let i = self.reserve_node();
+        let i = self.reserve_node_other();
         self.set_tag_data_source_loc(
             i,
             Tag::DeclRefUnresolved,
@@ -965,8 +1043,8 @@ impl Ast {
     }
 
     fn resolve_decl_ref(&mut self, i: Index, decl: Index) {
-        self.tags[i.index()] = Tag::DeclRef;
-        self.datas[i.index()] = Data::index(decl);
+        self.tags[i] = Tag::DeclRef;
+        self.datas[i] = Data::index(decl);
     }
 
     fn push_struct_decl<I: IntoIterator<Item = (intern::Index, Index)>>(
@@ -976,7 +1054,7 @@ impl Ast {
         fields: I,
         loc: SourceLocation,
     ) -> Index {
-        let i = self.reserve_node();
+        let i = self.reserve_node(Kind::GlobalDecl);
         self.set_struct_decl(i, name, flags, fields, loc)
     }
 
@@ -1004,19 +1082,9 @@ impl Ast {
         i
     }
 
-    fn push_field_decl(
-        &mut self,
-        name: intern::Index,
-        ty: Index,
-        loc: SourceLocation,
-    ) -> Index {
-        let i = self.reserve_node();
-        self.set_tag_data_source_loc(
-            i,
-            Tag::FieldDecl,
-            Data::index_and_intern(ty, name),
-            loc,
-        );
+    fn push_field_decl(&mut self, name: intern::Index, ty: Index, loc: SourceLocation) -> Index {
+        let i = self.reserve_node_other();
+        self.set_tag_data_source_loc(i, Tag::FieldDecl, Data::index_and_intern(ty, name), loc);
 
         i
     }
@@ -1027,29 +1095,15 @@ impl Ast {
         name: intern::Index,
         loc: SourceLocation,
     ) -> Index {
-        let i = self.reserve_node();
-        self.set_tag_data_source_loc(
-            i,
-            Tag::FieldAccess,
-            Data::index_and_intern(expr, name),
-            loc,
-        );
+        let i = self.reserve_node_other();
+        self.set_tag_data_source_loc(i, Tag::FieldAccess, Data::index_and_intern(expr, name), loc);
 
         i
     }
 
-    fn push_interend_type(
-        &mut self,
-        ty: intern::Index,
-        loc: SourceLocation,
-    ) -> Index {
-        let i = self.reserve_node();
-        self.set_tag_data_source_loc(
-            i,
-            Tag::InternedType,
-            Data::intern(ty),
-            loc,
-        );
+    fn push_interend_type(&mut self, ty: intern::Index, loc: SourceLocation) -> Index {
+        let i = self.reserve_node_other();
+        self.set_tag_data_source_loc(i, Tag::InternedType, Data::intern(ty), loc);
 
         i
     }
@@ -1060,7 +1114,7 @@ impl Ast {
         pointer_ty: Index,
         loc: SourceLocation,
     ) -> Index {
-        let i = self.reserve_node();
+        let i = self.reserve_node_other();
         self.set_tag_data_source_loc(
             i,
             Tag::ArrayType,
@@ -1071,13 +1125,8 @@ impl Ast {
         i
     }
 
-    fn push_pointer_type(
-        &mut self,
-        ty: Index,
-        flags: PointerFlags,
-        loc: SourceLocation,
-    ) -> Index {
-        let i = self.reserve_node();
+    fn push_pointer_type(&mut self, ty: Index, flags: PointerFlags, loc: SourceLocation) -> Index {
+        let i = self.reserve_node_other();
         self.set_tag_data_source_loc(
             i,
             Tag::PointerType,
@@ -1094,7 +1143,7 @@ impl Ast {
         ident: intern::Index,
         loc: SourceLocation,
     ) -> Index {
-        let i = self.reserve_node();
+        let i = self.reserve_node_other();
         self.set_tag_data_source_loc(
             i,
             Tag::TypeDeclRefUnresolved,
@@ -1106,60 +1155,38 @@ impl Ast {
     }
 
     fn resolve_type_ref(&mut self, i: Index, decl: Index) {
-        self.tags[i.index()] = Tag::TypeDeclRef;
-        self.datas[i.index()] = Data::index(decl);
+        self.tags[i] = Tag::TypeDeclRef;
+        self.datas[i] = Data::index(decl);
     }
 
     fn push_expr_stmt(&mut self, expr: Index) -> Index {
-        let i = self.reserve_node();
+        let i = self.reserve_node_other();
         let loc = self.get_loc(expr);
         self.set_tag_data_source_loc(i, Tag::ExprStmt, Data::index(expr), loc);
 
         i
     }
 
-    fn push_constant(
-        &mut self,
-        value: intern::Index,
-        ty: Index,
-        loc: SourceLocation,
-    ) -> Index {
-        let i = self.reserve_node();
-        self.set_tag_data_source_loc(
-            i,
-            Tag::Constant,
-            Data::index_and_intern(ty, value),
-            loc,
-        );
+    fn push_constant(&mut self, value: intern::Index, ty: Index, loc: SourceLocation) -> Index {
+        let i = self.reserve_node_other();
+        self.set_tag_data_source_loc(i, Tag::Constant, Data::index_and_intern(ty, value), loc);
 
         i
     }
 
-    fn extend_extra_by_indices<I: IntoIterator<Item = Index>>(
-        &mut self,
-        indices: I,
-    ) -> (u32, u32) {
-        self.extend_extra(indices.into_iter().map(|i| i.0.get()))
+    fn extend_extra_by_indices<I: IntoIterator<Item = Index>>(&mut self, indices: I) -> (u32, u32) {
+        self.extend_extra(indices.into_iter().map(|i| i.as_u32()))
     }
-    fn extend_extra<I: IntoIterator<Item = u32>>(
-        &mut self,
-        words: I,
-    ) -> (u32, u32) {
+    fn extend_extra<I: IntoIterator<Item = u32>>(&mut self, words: I) -> (u32, u32) {
         let i = self.extra.len() as u32;
         self.extra.extend(words);
 
         (i, self.extra.len() as u32)
     }
-    fn set_tag_data_source_loc(
-        &mut self,
-        index: Index,
-        tag: Tag,
-        data: Data,
-        loc: SourceLocation,
-    ) {
-        self.tags[index.index()] = tag;
-        self.datas[index.index()] = data;
-        self.source_locs[index.index()] = loc;
+    fn set_tag_data_source_loc(&mut self, index: Index, tag: Tag, data: Data, loc: SourceLocation) {
+        self.tags[index] = tag;
+        self.datas[index] = data;
+        self.source_locs[index] = loc;
     }
 }
 
@@ -1223,8 +1250,8 @@ impl Ast {
         }
 
         let void = ip.get_void_type();
-        let tag = self.tags[index.index()];
-        let data = self.datas[index.index()];
+        let tag = self.tags[index];
+        let data = self.datas[index];
 
         let ty = match tag {
             Tag::ArgumentList
@@ -1235,45 +1262,46 @@ impl Ast {
             | Tag::File => void,
             Tag::VarDeclAssignment | Tag::MutVarDeclAssignment => {
                 let (_, b) = data.as_extra_range();
-                self.get_type_of_node(ip, cache, Index::new(self.extra[b - 1]))
+                self.get_type_of_node(ip, cache, Index::from_u32(self.extra[b - 1]).unwrap())
             }
             Tag::VarDecl | Tag::MutVarDecl => {
-                let (a, b) = data.as_extra_range();
-                self.get_type_of_node(ip, cache, Index::new(self.extra[a + 1]))
+                let (a, _b) = data.as_extra_range();
+                self.get_type_of_node(ip, cache, Index::from_u32(self.extra[a + 1]).unwrap())
             }
             Tag::GlobalDecl => {
                 let (_, a) = data.as_intern_and_extra_offset();
-                self.get_type_of_node(ip, cache, Index::new(self.extra[a]))
-            }
-            Tag::FunctionDecl => {
-                self.get_type_of_node(ip, cache, data.as_two_indices().0)
+                self.get_type_of_node(ip, cache, Index::from_u32(self.extra[a]).unwrap())
             }
+            Tag::FunctionDecl => self.get_type_of_node(ip, cache, data.as_two_indices().0),
             Tag::FunctionProto => {
                 let (_, i) = data.as_intern_and_extra_offset();
-                let return_type =
-                    { self.datas[self.extra[i] as usize].as_intern() };
+                let (return_type, parameter_list) = (
+                    Index::from_u32(self.extra[i]).unwrap(),
+                    Index::from_u32(self.extra[i + 1]).unwrap(),
+                );
+                let return_type = self.datas[return_type].as_intern();
                 let parameters = {
-                    let (a, b) =
-                        self.datas[self.extra[i + 1] as usize].as_extra_range();
-                    self.extra[a..b].iter().map(|&i| {
-                        // i is index to a parameter, a parameter is (index, intern)
-                        let ty = self.datas[i as usize].as_index_intern().0;
-                        self.datas[ty.index()].as_intern()
-                    })
+                    let (a, b) = self.datas[parameter_list].as_extra_range();
+                    self.extra[a..b]
+                        .iter()
+                        .map(|&i| Index::from_u32(i).unwrap())
+                        .map(|i| {
+                            // i is index to a parameter, a parameter is (index, intern)
+                            let ty = self.datas[i].as_index_intern().0;
+                            self.datas[ty].as_intern()
+                        })
                 };
 
                 ip.try_get_function_type(return_type, parameters).unwrap()
             }
             Tag::BlockTrailingExpr => {
-                let (a, b) = data.as_extra_range();
-                self.get_type_of_node(ip, cache, Index::new(self.extra[b - 1]))
+                let (_a, b) = data.as_extra_range();
+                self.get_type_of_node(ip, cache, Index::from_u32(self.extra[b - 1]).unwrap())
             }
             Tag::CallExpr => {
                 let (expr, _args) = data.as_two_indices();
                 let fn_ty = self.get_type_of_node(ip, cache, expr);
-                if let intern::Key::FunctionType { return_type, .. } =
-                    ip.get_key(fn_ty)
-                {
+                if let intern::Key::FunctionType { return_type, .. } = ip.get_key(fn_ty) {
                     return_type
                 } else {
                     eprintln!(
@@ -1297,8 +1325,7 @@ impl Ast {
                 let ty = self.get_type_of_node(ip, cache, ty_expr);
                 match ip.get_key(ty) {
                     intern::Key::PointerType { pointee, .. }
-                        if let intern::Key::StructType { fields, .. } =
-                            ip.get_key(pointee) =>
+                        if let intern::Key::StructType { fields, .. } = ip.get_key(pointee) =>
                     {
                         fields
                             .iter()
@@ -1320,8 +1347,7 @@ impl Ast {
             }
             Tag::Deref => {
                 let ty = self.get_type_of_node(ip, cache, data.as_index());
-                if let intern::Key::PointerType { pointee, .. } = ip.get_key(ty)
-                {
+                if let intern::Key::PointerType { pointee, .. } = ip.get_key(ty) {
                     pointee
                 } else {
                     eprintln!("lhs of deref is not a pointer!");
@@ -1329,15 +1355,12 @@ impl Ast {
                 }
             }
             Tag::SubscriptExpr => {
-                let ty =
-                    self.get_type_of_node(ip, cache, data.as_two_indices().0);
+                let ty = self.get_type_of_node(ip, cache, data.as_two_indices().0);
                 match ip.get_key(ty) {
                     intern::Key::PointerType { pointee, .. }
                     | intern::Key::ArrayType { pointee, .. } => pointee,
                     _ => {
-                        eprintln!(
-                            "lhs of subscript is not an array or pointer!"
-                        );
+                        eprintln!("lhs of subscript is not an array or pointer!");
                         void
                     }
                 }
@@ -1347,9 +1370,7 @@ impl Ast {
                 // TODO: find out of the expression is const, volatile for flags
                 ip.try_get_pointer_type(ty, None).unwrap()
             }
-            Tag::Not | Tag::Negate => {
-                self.get_type_of_node(ip, cache, data.as_index())
-            }
+            Tag::Not | Tag::Negate => self.get_type_of_node(ip, cache, data.as_index()),
             Tag::Or
             | Tag::And
             | Tag::BitOr
@@ -1367,13 +1388,11 @@ impl Ast {
             | Tag::Sub
             | Tag::Mul
             | Tag::Div
-            | Tag::Rem => {
-                self.get_type_of_node(ip, cache, data.as_two_indices().0)
-            }
+            | Tag::Rem => self.get_type_of_node(ip, cache, data.as_two_indices().0),
             Tag::IfExpr => ip.get_bool_type(), // really?
             Tag::IfElseExpr => {
                 let (_, b) = data.as_index_and_extra_offset();
-                let if_ = Index::new(self.extra[b]);
+                let if_ = Index::from_u32(self.extra[b]).unwrap();
                 self.get_type_of_node(ip, cache, if_)
             }
             Tag::Constant | Tag::Parameter => {
@@ -1390,14 +1409,11 @@ impl Ast {
             | Tag::Error
             | Tag::Undefined
             | Tag::ReturnStmt => void,
-            Tag::FieldDecl => {
-                self.get_type_of_node(ip, cache, data.as_index_intern().0)
-            }
+            Tag::FieldDecl => self.get_type_of_node(ip, cache, data.as_index_intern().0),
             Tag::InternedType => data.as_intern(),
-            Tag::TypeDeclRef
-            | Tag::TypeDeclRefUnresolved
-            | Tag::PointerType
-            | Tag::ArrayType => ip.get_void_type(),
+            Tag::TypeDeclRef | Tag::TypeDeclRefUnresolved | Tag::PointerType | Tag::ArrayType => {
+                ip.get_void_type()
+            }
         };
 
         cache.insert(index, ty);
@@ -1405,19 +1421,22 @@ impl Ast {
     }
 
     fn get_node_children(&self, index: Index) -> Vec<Index> {
-        let tag = self.tags[index.index()];
-        let data = self.datas[index.index()];
+        let tag = self.tags[index];
+        let data = self.datas[index];
 
         match tag {
             Tag::File => {
                 let (a, b) = data.as_extra_range();
-                self.extra[a..b].iter().map(|&i| Index::new(i)).collect()
+                self.extra[a..b]
+                    .iter()
+                    .map(|&i| Index::from_u32(i).unwrap())
+                    .collect()
             }
             Tag::FunctionProto => {
                 let (_, i) = data.as_intern_and_extra_offset();
                 self.extra[i..=i + 1]
                     .iter()
-                    .map(|&i| Index::new(i))
+                    .map(|&i| Index::from_u32(i).unwrap())
                     .collect()
             }
             Tag::FunctionDecl => {
@@ -1426,11 +1445,17 @@ impl Ast {
             }
             Tag::ParameterList => {
                 let (a, b) = data.as_extra_range();
-                self.extra[a..b].iter().map(|&i| Index::new(i)).collect()
+                self.extra[a..b]
+                    .iter()
+                    .map(|&i| Index::from_u32(i).unwrap())
+                    .collect()
             }
             Tag::Block | Tag::BlockTrailingExpr => {
                 let (a, b) = data.as_extra_range();
-                self.extra[a..b].iter().map(|&i| Index::new(i)).collect()
+                self.extra[a..b]
+                    .iter()
+                    .map(|&i| Index::from_u32(i).unwrap())
+                    .collect()
             }
             Tag::ExprStmt | Tag::ReturnExprStmt => {
                 let a = data.as_index();
@@ -1440,14 +1465,14 @@ impl Ast {
                 let (a, b) = data.as_extra_range();
                 self.extra[a + 1..b]
                     .iter()
-                    .map(|&i| Index::new(i))
+                    .map(|&i| Index::from_u32(i).unwrap())
                     .collect()
             }
             Tag::GlobalDecl => {
                 let (_, offset) = data.as_intern_and_extra_offset();
                 self.extra[offset..=offset + 1]
                     .iter()
-                    .map(|&i| Index::new(i))
+                    .map(|&i| Index::from_u32(i).unwrap())
                     .collect()
             }
             Tag::CallExpr | Tag::ExplicitCast => {
@@ -1456,7 +1481,10 @@ impl Ast {
             }
             Tag::ArgumentList => {
                 let (a, b) = data.as_extra_range();
-                self.extra[a..b].iter().map(|&i| Index::new(i)).collect()
+                self.extra[a..b]
+                    .iter()
+                    .map(|&i| Index::from_u32(i).unwrap())
+                    .collect()
             }
             Tag::Argument => {
                 let a = data.as_index();
@@ -1497,8 +1525,8 @@ impl Ast {
             }
             Tag::IfElseExpr => {
                 let (a, b) = data.as_index_and_extra_offset();
-                let if_ = Index::new(self.extra[b]);
-                let else_ = Index::new(self.extra[b + 1]);
+                let if_ = Index::from_u32(self.extra[b]).unwrap();
+                let else_ = Index::from_u32(self.extra[b + 1]).unwrap();
                 vec![a, if_, else_]
             }
             Tag::PointerType => {
@@ -1506,11 +1534,11 @@ impl Ast {
                 vec![a]
             }
             Tag::StructDecl => {
-                let (a, offset) = data.as_intern_and_extra_offset();
+                let (_a, offset) = data.as_intern_and_extra_offset();
                 let flags = StructFlags::unpack(self.extra[offset]);
                 self.extra[offset + 1..(offset + 1 + flags.num_fields as usize)]
                     .iter()
-                    .map(|&i| Index::new(i))
+                    .map(|&i| Index::from_u32(i).unwrap())
                     .collect()
             }
             Tag::InternedType
@@ -1529,30 +1557,25 @@ impl Ast {
             Tag::VarDecl | Tag::MutVarDecl => {
                 let (a, _) = data.as_extra_range();
 
-                vec![Index::new(self.extra[a + 1])]
+                vec![Index::from_u32(self.extra[a + 1]).unwrap()]
             }
         }
     }
 
-    fn is_node_comptime_evaluable(
-        &self,
-        cache: &mut ComptimeCache,
-        index: Index,
-    ) -> bool {
+    fn is_node_comptime_evaluable(&self, cache: &mut ComptimeCache, index: Index) -> bool {
         if let Some(a) = cache.get(&index) {
             a
         } else {
-            let tag = self.tags[index.index()];
-            let data = self.datas[index.index()];
+            let tag = self.tags[index];
+            let data = self.datas[index];
 
             let children = self.get_node_children(index);
 
-            let are_children_comptime =
-                |this: &Self, cache: &mut ComptimeCache| {
-                    children
-                        .iter()
-                        .all(|&i| this.is_node_comptime_evaluable(cache, i))
-                };
+            let are_children_comptime = |this: &Self, cache: &mut ComptimeCache| {
+                children
+                    .iter()
+                    .all(|&i| this.is_node_comptime_evaluable(cache, i))
+            };
 
             let is_comptime = match tag {
                 Tag::Parameter => false,
@@ -1569,13 +1592,8 @@ impl Ast {
                 Tag::GlobalDecl => true,
                 Tag::StructDecl => true,
                 Tag::FieldDecl => true,
-                Tag::DeclRef => {
-                    self.tags[data.as_index().index()] == Tag::GlobalDecl
-                }
-                Tag::InternedType
-                | Tag::PointerType
-                | Tag::ArrayType
-                | Tag::TypeDeclRef => true,
+                Tag::DeclRef => self.tags[data.as_index()] == Tag::GlobalDecl,
+                Tag::InternedType | Tag::PointerType | Tag::ArrayType | Tag::TypeDeclRef => true,
                 // Tag::CallExpr => are_children_comptime(self, cache),
                 // Tag::FieldAccess => {
                 //     let parent = data.as_index_intern().0;
@@ -1583,15 +1601,13 @@ impl Ast {
                 //     self.is_node_comptime_evaluable(cache, parent)
                 // }
                 Tag::ArgumentList => are_children_comptime(self, cache),
-                Tag::Argument => {
-                    self.is_node_comptime_evaluable(cache, data.as_index())
+                Tag::Argument => self.is_node_comptime_evaluable(cache, data.as_index()),
+                Tag::NamedArgument => {
+                    self.is_node_comptime_evaluable(cache, data.as_index_intern().0)
+                }
+                Tag::ExplicitCast => {
+                    self.is_node_comptime_evaluable(cache, data.as_two_indices().0)
                 }
-                Tag::NamedArgument => self.is_node_comptime_evaluable(
-                    cache,
-                    data.as_index_intern().0,
-                ),
-                Tag::ExplicitCast => self
-                    .is_node_comptime_evaluable(cache, data.as_two_indices().0),
                 Tag::Deref | Tag::AddressOf => false,
                 Tag::Not
                 | Tag::Negate
@@ -1644,8 +1660,8 @@ impl Ast {
         cache: &mut TypeCache,
         index: Index,
     ) -> Option<crate::comptime::ComptimeNumber> {
-        let tag = self.tags[index.index()];
-        let data = self.datas[index.index()];
+        let tag = self.tags[index];
+        let data = self.datas[index];
 
         match tag {
             Tag::Constant => {
@@ -1664,7 +1680,7 @@ impl Ast {
                     ip,
                     pointer_bits,
                     cache,
-                    Index::new(self.extra[offset + 1]),
+                    Index::from_u32(self.extra[offset + 1]).unwrap(),
                 )
             }
             Tag::VarDeclAssignment => {
@@ -1673,23 +1689,14 @@ impl Ast {
                     ip,
                     pointer_bits,
                     cache,
-                    Index::new(self.extra[a + 1]),
+                    Index::from_u32(self.extra[a + 1]).unwrap(),
                 )
             }
-            Tag::DeclRef => self.comptime_value_of_node(
-                ip,
-                pointer_bits,
-                cache,
-                data.as_index(),
-            ),
+            Tag::DeclRef => self.comptime_value_of_node(ip, pointer_bits, cache, data.as_index()),
             Tag::ExplicitCast => {
                 let (expr, ty) = data.as_two_indices();
-                let ty = ip.as_ast1_type(
-                    intern::AMD64_POINTER_BITS,
-                    self.datas[ty.index()].as_intern(),
-                );
-                let val =
-                    self.comptime_value_of_node(ip, pointer_bits, cache, expr);
+                let ty = ip.as_ast1_type(intern::AMD64_POINTER_BITS, self.datas[ty].as_intern());
+                let val = self.comptime_value_of_node(ip, pointer_bits, cache, expr);
                 val.and_then(|i| i.explicit_cast(ty).ok())
             }
             Tag::Add => {
@@ -1939,45 +1946,30 @@ pub fn interned_type_and_value_to_comptime_number(
     let ty_key = ip.get_key(ty);
     let signed = ip.is_type_signed(ty, AMD64_POINTER_TYPE_INFO);
     match ty_key {
-        intern::Key::SIntType { bit_width: bits }
-        | intern::Key::UIntType { bit_width: bits } => {
+        intern::Key::SIntType { bit_width: bits } | intern::Key::UIntType { bit_width: bits } => {
             let ty = IntegralType::new(signed, bits);
             match ip.get_key(val) {
-                intern::Key::SIntSmall { bits } => {
-                    ComptimeNumber::Integral(ComptimeInt::Native {
-                        bits: bits as _,
-                        ty,
-                    })
-                }
-                intern::Key::UIntSmall { bits } => {
-                    ComptimeNumber::Integral(ComptimeInt::Native {
-                        bits: bits as _,
-                        ty,
-                    })
-                }
-                intern::Key::SInt64 { bits } => {
-                    ComptimeNumber::Integral(ComptimeInt::Native {
-                        bits: bits as _,
-                        ty,
-                    })
-                }
-                intern::Key::UInt64 { bits } => {
-                    ComptimeNumber::Integral(ComptimeInt::Native {
-                        bits: bits as _,
-                        ty,
-                    })
-                }
+                intern::Key::SIntSmall { bits } => ComptimeNumber::Integral(ComptimeInt::Native {
+                    bits: bits as _,
+                    ty,
+                }),
+                intern::Key::UIntSmall { bits } => ComptimeNumber::Integral(ComptimeInt::Native {
+                    bits: bits as _,
+                    ty,
+                }),
+                intern::Key::SInt64 { bits } => ComptimeNumber::Integral(ComptimeInt::Native {
+                    bits: bits as _,
+                    ty,
+                }),
+                intern::Key::UInt64 { bits } => ComptimeNumber::Integral(ComptimeInt::Native {
+                    bits: bits as _,
+                    ty,
+                }),
                 intern::Key::PositiveInt { bigint } => {
-                    ComptimeNumber::Integral(ComptimeInt::BigInt {
-                        bits: bigint,
-                        ty,
-                    })
+                    ComptimeNumber::Integral(ComptimeInt::BigInt { bits: bigint, ty })
                 }
                 intern::Key::NegativeInt { bigint } => {
-                    ComptimeNumber::Integral(ComptimeInt::BigInt {
-                        bits: bigint,
-                        ty,
-                    })
+                    ComptimeNumber::Integral(ComptimeInt::BigInt { bits: bigint, ty })
                 }
                 _ => {
                     unreachable!()
@@ -2031,29 +2023,19 @@ pub fn interned_type_and_value_to_comptime_number(
                             ty,
                         })
                     }
-                    intern::Key::SInt64 { bits } => {
-                        ComptimeNumber::Integral(ComptimeInt::Native {
-                            bits: bits as _,
-                            ty,
-                        })
-                    }
-                    intern::Key::UInt64 { bits } => {
-                        ComptimeNumber::Integral(ComptimeInt::Native {
-                            bits: bits as _,
-                            ty,
-                        })
-                    }
+                    intern::Key::SInt64 { bits } => ComptimeNumber::Integral(ComptimeInt::Native {
+                        bits: bits as _,
+                        ty,
+                    }),
+                    intern::Key::UInt64 { bits } => ComptimeNumber::Integral(ComptimeInt::Native {
+                        bits: bits as _,
+                        ty,
+                    }),
                     intern::Key::PositiveInt { bigint } => {
-                        ComptimeNumber::Integral(ComptimeInt::BigInt {
-                            bits: bigint,
-                            ty,
-                        })
+                        ComptimeNumber::Integral(ComptimeInt::BigInt { bits: bigint, ty })
                     }
                     intern::Key::NegativeInt { bigint } => {
-                        ComptimeNumber::Integral(ComptimeInt::BigInt {
-                            bits: bigint,
-                            ty,
-                        })
+                        ComptimeNumber::Integral(ComptimeInt::BigInt { bits: bigint, ty })
                     }
                     _ => {
                         unreachable!()
@@ -2074,8 +2056,9 @@ pub fn interned_type_and_value_to_comptime_number(
                     intern::Key::UInt64 { bits } => {
                         BigInt::from_signed_bytes_le(&bits.to_le_bytes())
                     }
-                    intern::Key::PositiveInt { bigint }
-                    | intern::Key::NegativeInt { bigint } => bigint,
+                    intern::Key::PositiveInt { bigint } | intern::Key::NegativeInt { bigint } => {
+                        bigint
+                    }
                     _ => {
                         unreachable!()
                     }
@@ -2141,7 +2124,7 @@ pub mod visitor {
         }
 
         fn get_node_tag_and_data(&self, node: Index) -> (Tag, Data) {
-            (self.tags[node.index()], self.datas[node.index()])
+            (self.tags[node], self.datas[node])
         }
     }
     impl AstExt for &mut Ast {
@@ -2150,7 +2133,7 @@ pub mod visitor {
         }
 
         fn get_node_tag_and_data(&self, node: Index) -> (Tag, Data) {
-            (self.tags[node.index()], self.datas[node.index()])
+            (self.tags[node], self.datas[node])
         }
     }
 
@@ -2224,10 +2207,7 @@ pub mod visitor {
                 }
             }
         }
-        pub fn visit_pre<F: FnMut(&mut AstT, &[Index], Index, Tag, Data)>(
-            &mut self,
-            mut cb: F,
-        ) {
+        pub fn visit_pre<F: FnMut(&mut AstT, &[Index], Index, Tag, Data)>(&mut self, mut cb: F) {
             while let Some(node) = self.nodes.pop() {
                 match node {
                     A::PushChildren(i) => {
@@ -2277,10 +2257,7 @@ pub mod visitor {
                 }
             }
         }
-        pub fn visit_post<F: FnMut(&mut AstT, &[Index], Index, Tag, Data)>(
-            &mut self,
-            mut cb: F,
-        ) {
+        pub fn visit_post<F: FnMut(&mut AstT, &[Index], Index, Tag, Data)>(&mut self, mut cb: F) {
             while let Some(node) = self.nodes.pop() {
                 match node {
                     A::PushChildren(i) => {
@@ -2354,13 +2331,13 @@ pub struct NodeDisplay<'a> {
 impl<'a> Display for NodeDisplay<'a> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         let node = self.node;
-        let tag = self.ast.tags[node.index()];
-        let loc = self.ast.source_locs[node.index()];
+        let tag = self.ast.tags[node];
+        let loc = self.ast.source_locs[node];
 
         let children = Children(self.ast.get_node_children(node));
-        let ty =
-            self.ast
-                .get_type_of_node(self.ip, &mut TypeCache::new(), node);
+        let ty = self
+            .ast
+            .get_type_of_node(self.ip, &mut TypeCache::new(), node);
 
         let is_comptime = self
             .ast
@@ -2392,12 +2369,11 @@ impl<'a> AstRenderer<'a> {
 
     fn render<W: core::fmt::Write>(&mut self, w: &mut W) -> core::fmt::Result {
         self.ast.visitor().visit_pre(|ast, scopes, node, tag, _| {
-            let loc = ast.source_locs[node.index()];
+            let loc = ast.source_locs[node];
 
             let children = Children(ast.get_node_children(node));
             let ty = self.ast.get_type_of_node(self.ip, &mut self.cache, node);
-            let is_comptime =
-                ast.is_node_comptime_evaluable(&mut self.comptime_cache, node);
+            let is_comptime = ast.is_node_comptime_evaluable(&mut self.comptime_cache, node);
             _ = writeln_indented!(
                 scopes.len() as u32 * 2,
                 w,
@@ -2476,8 +2452,7 @@ pub mod ast_gen {
         pub fn create_comptime_folding_graph(&mut self, pointer_bits: u16) {
             let mut type_cache = TypeCache::new();
             let mut cache = ComptimeCache::default();
-            let mut nodes =
-                self.ast.get_root_file_indices().collect::<Vec<_>>();
+            let mut nodes = self.ast.get_root_file_indices().collect::<Vec<_>>();
             while let Some(node) = nodes.pop() {
                 if !self.ast.is_node_comptime_evaluable(&mut cache, node) {
                     nodes.extend(self.ast.get_node_children(node));
@@ -2489,25 +2464,19 @@ pub mod ast_gen {
                 .inner
                 .iter()
                 .filter(|(_, b)| **b)
-                .map(|(e, _)| {
-                    self.ast.get_node_children(*e).into_iter().map(|d| (*e, d))
-                })
+                .map(|(e, _)| self.ast.get_node_children(*e).into_iter().map(|d| (*e, d)))
                 .flatten()
                 // .map(|(a, b)| (a.into_u32(), b.into_u32()))
                 .map(|(a, b)| {
                     (
-                        node_map.iter().position(|&i| i == a).unwrap_or_else(
-                            || {
-                                node_map.push(a);
-                                node_map.len() - 1
-                            },
-                        ) as u32,
-                        node_map.iter().position(|&i| i == b).unwrap_or_else(
-                            || {
-                                node_map.push(b);
-                                node_map.len() - 1
-                            },
-                        ) as u32,
+                        node_map.iter().position(|&i| i == a).unwrap_or_else(|| {
+                            node_map.push(a);
+                            node_map.len() - 1
+                        }) as u32,
+                        node_map.iter().position(|&i| i == b).unwrap_or_else(|| {
+                            node_map.push(b);
+                            node_map.len() - 1
+                        }) as u32,
                     )
                 })
                 .collect::<Vec<_>>();
@@ -2516,19 +2485,14 @@ pub mod ast_gen {
                 .inner
                 .iter()
                 .filter(|(_, b)| **b)
-                .filter_map(|(i, _)| {
-                    (!node_map.contains(i)).then(|| node_map.push(*i))
-                })
+                .filter_map(|(i, _)| (!node_map.contains(i)).then(|| node_map.push(*i)))
                 .count();
 
             eprintln!("cache: {cache:?}");
             eprintln!("node_map: {node_map:?}");
             eprintln!("edges: {edges:?}");
 
-            let mut graph =
-                petgraph::stable_graph::StableDiGraph::<(), ()>::from_edges(
-                    edges,
-                );
+            let mut graph = petgraph::stable_graph::StableDiGraph::<(), ()>::from_edges(edges);
             for _ in 0..extra_nodes {
                 graph.add_node(());
             }
@@ -2539,44 +2503,31 @@ pub mod ast_gen {
                     petgraph::dot::Dot::with_attr_getters(
                         &graph,
                         &[],
-                        &|graph, edgeref| { "".to_string() },
-                        &|graph, noderef| {
-                            format!(
-                                "label = \"{}\"",
-                                node_map[noderef.0.index()]
-                            )
+                        &|_graph, _edgeref| { "".to_string() },
+                        &|_graph, noderef| {
+                            format!("label = \"{}\"", node_map[noderef.0.index()])
                         }
                     )
                 ),
             )
             .expect("writing comptime graph repr");
 
-            while let Some(external) =
-                graph.externals(petgraph::Direction::Outgoing).next()
-            {
+            while let Some(external) = graph.externals(petgraph::Direction::Outgoing).next() {
                 let node = node_map[external.index()];
-                if !(self.ast.tags[node.index()] == Tag::Constant
-                    || self.ast.tags[node.index()].is_type())
-                    && self.ast.tags[node.index()].is_expr()
+                if !(self.ast.tags[node] == Tag::Constant || self.ast.tags[node].is_type())
+                    && self.ast.tags[node].is_expr()
                 {
                     eprintln!("folding {node}:\n{}", self.node_display(node));
                     let value = self
                         .ast
-                        .comptime_value_of_node(
-                            &self.intern,
-                            pointer_bits,
-                            &mut type_cache,
-                            node,
-                        )
+                        .comptime_value_of_node(&self.intern, pointer_bits, &mut type_cache, node)
                         .expect(&format!("{node} has value of None?"));
-                    let (value, ty) =
-                        comptime_number_to_interned_type_and_value(
-                            &mut self.intern,
-                            pointer_bits,
-                            value,
-                        );
-                    let ty =
-                        self.ast.push_interend_type(ty, self.ast.get_loc(node));
+                    let (value, ty) = comptime_number_to_interned_type_and_value(
+                        &mut self.intern,
+                        pointer_bits,
+                        value,
+                    );
+                    let ty = self.ast.push_interend_type(ty, self.ast.get_loc(node));
                     self.ast.set_tag_data_source_loc(
                         node,
                         Tag::Constant,
@@ -2594,23 +2545,22 @@ pub mod ast_gen {
         /// folds more AST-patterns into structures that are easier to build the IR with
         pub fn fold_more_patterns(&mut self) {
             use visitor::AstExt;
-            self.ast.visitor_mut().visit_post(|ast, _, i, tag, data| {
+            self.ast.visitor_mut().visit_post(|ast, _, _i, tag, data| {
                 match tag {
                     // normalise functions with block-with-trailing-expr into block
                     Tag::FunctionDecl => {
                         let (_, block) = data.as_two_indices();
 
-                        let (block_tag, block_data) =
-                            ast.get_node_tag_and_data(block);
+                        let (block_tag, block_data) = ast.get_node_tag_and_data(block);
                         if block_tag == Tag::BlockTrailingExpr {
                             let (_, end) = block_data.as_extra_range();
                             let end = end - 1;
-                            let expr = Index::new(ast.extra[end]);
+                            let expr = Index::from_u32(ast.extra[end]).unwrap();
                             let loc = ast.get_loc(expr);
                             let ret = ast.push_ret(Some(expr), loc);
                             // modify last element in place to be a return instruction
-                            ast.extra[end] = *ret.as_u32();
-                            ast.tags[block.index()] = Tag::Block;
+                            ast.extra[end] = ret.as_u32();
+                            ast.tags[block] = Tag::Block;
                             eprintln!("folding ({block}): {block_tag:?} into Tag::Block");
                             eprintln!("expr: {expr:?}");
                         }
@@ -2626,12 +2576,12 @@ pub mod ast_gen {
                             Tag::ArrayType => {
                                 let (length, pointee) = data.as_two_indices();
                                 let pointee =
-                                    ast.datas[pointee.index()].as_intern();
+                                    ast.datas[pointee].as_intern();
                                 variant!( self.intern.get_key(pointee) => intern::Key::PointerType { pointee, flags });
 
                                 // get interened value from constant node
                                 let length = {
-                                    let value = ast.datas[length.index()]
+                                    let value = ast.datas[length]
                                         .as_index_intern()
                                         .1;
 
@@ -2664,48 +2614,54 @@ pub mod ast_gen {
                                     Some(flags),
                                     length,
                                 );
-                                ast.tags[i.index()] = Tag::InternedType;
-                                ast.datas[i.index()] = Data::intern(ty);
+                                ast.tags[i] = Tag::InternedType;
+                                ast.datas[i] = Data::intern(ty);
                             }
                             Tag::PointerType => {
                                 let (pointee, flags) =
                                     data.as_index_and_extra_offset();
                                 let pointee =
-                                    ast.datas[pointee.index()].as_intern();
+                                    ast.datas[pointee].as_intern();
                                 let ty = self.intern.get_pointer_type(
                                     pointee,
                                     Some(PointerFlags::unpack(flags as u8)),
                                 );
-                                ast.tags[i.index()] = Tag::InternedType;
-                                ast.datas[i.index()] = Data::intern(ty);
+                                ast.tags[i] = Tag::InternedType;
+                                ast.datas[i] = Data::intern(ty);
                             }
                             Tag::TypeDeclRef => {
                                 let decl = data.as_index();
-                                let (name, _) = ast.datas[decl.index()]
+                                let (name, _) = ast.datas[decl]
                                     .as_intern_and_extra_offset();
 
                                 let ty =
                                     self.intern.get_struct_type(name, decl);
-                                ast.tags[i.index()] = Tag::InternedType;
-                                ast.datas[i.index()] = Data::intern(ty);
+                                ast.tags[i] = Tag::InternedType;
+                                ast.datas[i] = Data::intern(ty);
                             }
                             Tag::FunctionProto => {
                                 let (_, i) = data.as_intern_and_extra_offset();
+                                let (return_type, parameter_list) = (
+                                    Index::from_u32(ast.extra[i]).unwrap(),
+                                    Index::from_u32(ast.extra[i + 1]).unwrap(),
+                                );
                                 let return_type = ast.get_type_of_node(
                                     &self.intern,
                                     &mut TypeCache::new(),
-                                    Index::new(ast.extra[i]),
+                                    return_type
                                 );
                                 let parameters = {
                                     let (a, b) = ast.datas
-                                        [ast.extra[i + 1] as usize]
+                                        [parameter_list]
                                         .as_extra_range();
-                                    ast.extra[a..b].iter().map(|&i| {
+                                    ast.extra[a..b].iter()
+                                        .map(|&i| Index::from_u32(i).unwrap())
+                                        .map(|i| {
                                         // i is index to a parameter, a parameter is (index, intern)
-                                        let ty = ast.datas[i as usize]
+                                        let ty = ast.datas[i]
                                             .as_index_intern()
                                             .0;
-                                        ast.datas[ty.index()].as_intern()
+                                        ast.datas[ty].as_intern()
                                     })
                                 };
 
@@ -2728,9 +2684,9 @@ pub mod ast_gen {
 
                                 let types = ast.extra[types]
                                     .iter()
-                                    .map(|&i| Index::new(i))
+                                    .map(|&i| Index::from_u32(i).unwrap())
                                     .map(|i| {
-                                        ast.datas[i.index()].as_intern()
+                                        ast.datas[i].as_intern()
                                     });
                                 let names = ast.extra[names]
                                     .iter()
@@ -2755,27 +2711,22 @@ pub mod ast_gen {
                 .visit_post(|ast, _, node, tag, _| {
                     match tag {
                         Tag::TypeDeclRefUnresolved => {
-                            let (scope, name) =
-                                ast.datas[node.index()].as_index_intern();
+                            let (scope, name) = ast.datas[node].as_index_intern();
                             // look in my_scope
-                            if let Some(decl) = self.syms.find_type_symbol(
-                                scope,
-                                name,
-                                ast.source_locs[node.index()],
-                            ) {
+                            if let Some(decl) =
+                                self.syms
+                                    .find_type_symbol(scope, name, ast.source_locs[node])
+                            {
                                 ast.resolve_type_ref(node, decl)
                             };
                         }
                         Tag::DeclRefUnresolved => {
-                            let (scope, name) =
-                                ast.datas[node.index()].as_index_intern();
+                            let (scope, name) = ast.datas[node].as_index_intern();
 
                             // look in my_scope
-                            if let Some(decl) = self.syms.find_symbol(
-                                scope,
-                                name,
-                                ast.source_locs[node.index()],
-                            ) {
+                            if let Some(decl) =
+                                self.syms.find_symbol(scope, name, ast.source_locs[node])
+                            {
                                 ast.resolve_decl_ref(node, decl)
                             };
                         }
@@ -2788,15 +2739,11 @@ pub mod ast_gen {
             self.scopes.last().cloned().unwrap()
         }
 
-        fn parse_ident(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> Result<intern::Index, ErrorInfo> {
-            let ident =
-                tokens.expect_token(Token::Ident).map_err(|_| ErrorInfo {
-                    error: ParseError::ExpectedIdent,
-                    loc: tokens.current_source_location(),
-                })?;
+        fn parse_ident(&mut self, tokens: &mut TokenIterator) -> Result<intern::Index, ErrorInfo> {
+            let ident = tokens.expect_token(Token::Ident).map_err(|_| ErrorInfo {
+                error: ParseError::ExpectedIdent,
+                loc: tokens.current_source_location(),
+            })?;
 
             let name = self.intern.get_or_insert(intern::Key::String {
                 str: ident.lexeme(),
@@ -2805,110 +2752,83 @@ pub mod ast_gen {
             Ok(name)
         }
 
-        fn parse_pointer(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_pointer(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             let loc = tokens.current_source_location();
             tokens.eat_token(Token::Star).ok_or(ErrorInfo {
                 error: ParseError::ExpectedToken(Token::Star),
                 loc: tokens.current_source_location(),
             })?;
 
-            let &[cnst, vol, noalias] = &tokens.eat_all_zero_or_once(&[
-                Token::Const,
-                Token::Volatile,
-                Token::Noalias,
-            ])[..3] else {
+            let &[cnst, vol, noalias] =
+                &tokens.eat_all_zero_or_once(&[Token::Const, Token::Volatile, Token::Noalias])[..3]
+            else {
                 unreachable!()
             };
             let pointee = self.parse_type(tokens)?;
 
-            Ok(self.ast.push_pointer_type(
-                pointee,
-                PointerFlags::new(cnst, vol, noalias),
-                loc,
-            ))
+            Ok(self
+                .ast
+                .push_pointer_type(pointee, PointerFlags::new(cnst, vol, noalias), loc))
         }
 
         /// [LENGTH]const? volatile? noalias? TYPE
-        fn parse_array_type(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_array_type(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             let loc = tokens.current_source_location();
-            let length_expr =
-                self.parse_bracketed(tokens, |this, tokens| {
-                    this.parse_expr(tokens)
-                    // let next = tokens.peek_token().ok_or(ErrorInfo {
-                    //     error: ParseError::UnexpectedEndOfTokens,
-                    //     loc: tokens.current_source_location(),
-                    // })?;
-                    // match next.token() {
-                    //     Token::IntegerBinConstant
-                    //     | Token::IntegerHexConstant
-                    //     | Token::IntegerOctConstant
-                    //     | Token::IntegerConstant => {
-                    //         _ = tokens.next();
-                    //         Ok(this.parse_integral_constant(&next, next.source_location()))
-                    //     }
-                    //     _ => Err(ErrorInfo {
-                    //         error: ParseError::ExpectedConstantLiteral,
-                    //         loc: tokens.current_source_location(),
-                    //     }),
-                    // }
-                })?;
+            let length_expr = self.parse_bracketed(tokens, |this, tokens| {
+                this.parse_expr(tokens)
+                // let next = tokens.peek_token().ok_or(ErrorInfo {
+                //     error: ParseError::UnexpectedEndOfTokens,
+                //     loc: tokens.current_source_location(),
+                // })?;
+                // match next.token() {
+                //     Token::IntegerBinConstant
+                //     | Token::IntegerHexConstant
+                //     | Token::IntegerOctConstant
+                //     | Token::IntegerConstant => {
+                //         _ = tokens.next();
+                //         Ok(this.parse_integral_constant(&next, next.source_location()))
+                //     }
+                //     _ => Err(ErrorInfo {
+                //         error: ParseError::ExpectedConstantLiteral,
+                //         loc: tokens.current_source_location(),
+                //     }),
+                // }
+            })?;
 
-            let &[cnst, vol, noalias] = &tokens.eat_all_zero_or_once(&[
-                Token::Const,
-                Token::Volatile,
-                Token::Noalias,
-            ])[..3] else {
+            let &[cnst, vol, noalias] =
+                &tokens.eat_all_zero_or_once(&[Token::Const, Token::Volatile, Token::Noalias])[..3]
+            else {
                 unreachable!()
             };
 
             let pointee = self.parse_type(tokens)?;
-            let pointer = self.ast.push_pointer_type(
-                pointee,
-                PointerFlags::new(cnst, vol, noalias),
-                loc,
-            );
+            let pointer =
+                self.ast
+                    .push_pointer_type(pointee, PointerFlags::new(cnst, vol, noalias), loc);
 
             Ok(self.ast.push_array_type(length_expr, pointer, loc))
         }
 
         fn parse_simple_type(&mut self, token: Token) -> Option<intern::Index> {
             match token {
-                Token::Void => Some(self.intern.get_assume_present(
-                    &intern::Key::SimpleType {
-                        ty: SimpleType::Void,
-                    },
-                )),
-                Token::Bool => Some(self.intern.get_assume_present(
-                    &intern::Key::SimpleType {
-                        ty: SimpleType::Bool,
-                    },
-                )),
-                Token::F32 => Some(self.intern.get_assume_present(
-                    &intern::Key::SimpleType {
-                        ty: SimpleType::F32,
-                    },
-                )),
-                Token::F64 => Some(self.intern.get_assume_present(
-                    &intern::Key::SimpleType {
-                        ty: SimpleType::F64,
-                    },
-                )),
-                Token::USize => Some(self.intern.get_assume_present(
-                    &intern::Key::SimpleType {
-                        ty: SimpleType::USize,
-                    },
-                )),
-                Token::ISize => Some(self.intern.get_assume_present(
-                    &intern::Key::SimpleType {
-                        ty: SimpleType::ISize,
-                    },
-                )),
+                Token::Void => Some(self.intern.get_assume_present(&intern::Key::SimpleType {
+                    ty: SimpleType::Void,
+                })),
+                Token::Bool => Some(self.intern.get_assume_present(&intern::Key::SimpleType {
+                    ty: SimpleType::Bool,
+                })),
+                Token::F32 => Some(self.intern.get_assume_present(&intern::Key::SimpleType {
+                    ty: SimpleType::F32,
+                })),
+                Token::F64 => Some(self.intern.get_assume_present(&intern::Key::SimpleType {
+                    ty: SimpleType::F64,
+                })),
+                Token::USize => Some(self.intern.get_assume_present(&intern::Key::SimpleType {
+                    ty: SimpleType::USize,
+                })),
+                Token::ISize => Some(self.intern.get_assume_present(&intern::Key::SimpleType {
+                    ty: SimpleType::ISize,
+                })),
                 _ => None,
             }
         }
@@ -2984,8 +2904,7 @@ pub mod ast_gen {
                 .map(|(_, c)| c)
                 .collect::<Vec<_>>();
 
-            let value =
-                comptime::bigint::parse_bigint(digits.into_iter(), radix);
+            let value = comptime::bigint::parse_bigint(digits.into_iter(), radix);
 
             let ty = match chars.clone().next() {
                 Some((i, 'u')) | Some((i, 'i')) => self
@@ -3006,10 +2925,7 @@ pub mod ast_gen {
                     self.intern.get_or_insert(intern::Key::UInt64 { bits })
                 }
                 _ => {
-                    let bigint = BigInt::from_biguint(
-                        num_bigint::Sign::Plus,
-                        BigUint::new(value),
-                    );
+                    let bigint = BigInt::from_biguint(num_bigint::Sign::Plus, BigUint::new(value));
                     self.intern
                         .get_or_insert(intern::Key::PositiveInt { bigint })
                 }
@@ -3019,21 +2935,13 @@ pub mod ast_gen {
             (interned, ty)
         }
 
-        fn parse_integral_constant(
-            &mut self,
-            item: &TokenItem,
-            loc: SourceLocation,
-        ) -> Index {
+        fn parse_integral_constant(&mut self, item: &TokenItem, loc: SourceLocation) -> Index {
             let (interned, ty) = self.parse_integral_constant_inner(item);
             let ty = self.ast.push_interend_type(ty, loc);
             return self.ast.push_constant(interned, ty, loc);
         }
 
-        fn parse_floating_constant(
-            &mut self,
-            item: &TokenItem,
-            loc: SourceLocation,
-        ) -> Index {
+        fn parse_floating_constant(&mut self, item: &TokenItem, loc: SourceLocation) -> Index {
             let lexeme = item.lexeme();
             let lexeme = lexeme
                 .strip_suffix("f32")
@@ -3065,10 +2973,7 @@ pub mod ast_gen {
         ///     SIMPLE_TYPE
         ///     [ TYPE ; CONSTANT_EXPR ]
         ///     INTEGRAL_TYPE // u[0..65535] | i[0..65535]
-        fn parse_type(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_type(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             let loc = tokens.current_source_location();
             match tokens
                 .peek_token()
@@ -3082,35 +2987,30 @@ pub mod ast_gen {
                 Token::OpenSquareBracket => self.parse_array_type(tokens),
                 Token::Ident => {
                     let token = tokens.next().unwrap();
-                    match self.try_parse_integral_type(token.lexeme()).map_err(
-                        |error| ErrorInfo {
+                    match self
+                        .try_parse_integral_type(token.lexeme())
+                        .map_err(|error| ErrorInfo {
                             error,
                             loc: token.source_location(),
-                        },
-                    )? {
+                        })? {
                         Some(int) => Ok(self.ast.push_interend_type(int, loc)),
                         None => {
-                            let name = self.intern.get_or_insert(
-                                intern::Key::String {
-                                    str: token.lexeme(),
-                                },
-                            );
+                            let name = self.intern.get_or_insert(intern::Key::String {
+                                str: token.lexeme(),
+                            });
                             // TODO: this will cause issues with redefinitions of types with the same name
                             // and actually, make type into a proper node of the ast
-                            Ok(self.ast.push_type_ref_unresolved(
-                                self.current_scope(),
-                                name,
-                                loc,
-                            ))
+                            Ok(self
+                                .ast
+                                .push_type_ref_unresolved(self.current_scope(), name, loc))
                         }
                     }
                 }
                 token => {
-                    let ty =
-                        self.parse_simple_type(token).ok_or(ErrorInfo {
-                            error: ParseError::ExpectedTypeName,
-                            loc: tokens.current_source_location(),
-                        })?;
+                    let ty = self.parse_simple_type(token).ok_or(ErrorInfo {
+                        error: ParseError::ExpectedTypeName,
+                        loc: tokens.current_source_location(),
+                    })?;
                     _ = tokens.next();
 
                     Ok(self.ast.push_interend_type(ty, loc))
@@ -3120,10 +3020,7 @@ pub mod ast_gen {
 
         /// GLOBAL_DECL <-
         ///     const IDENTIFIER: TYPENAME = EXPR;
-        fn parse_const_decl(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_const_decl(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             let err = 'blk: {
                 let loc = tokens.current_source_location();
                 let Some(_) = tokens.eat_token(Token::Const) else {
@@ -3175,14 +3072,9 @@ pub mod ast_gen {
                     };
                 };
 
-                let decl =
-                    self.ast.push_global_decl(ident, typename, expr, loc);
-                self.syms.insert_symbol(
-                    self.current_scope(),
-                    ident,
-                    SymbolKind::Const,
-                    decl,
-                );
+                let decl = self.ast.push_global_decl(ident, typename, expr, loc);
+                self.syms
+                    .insert_symbol(self.current_scope(), ident, SymbolKind::Const, decl);
 
                 return Ok(decl);
             };
@@ -3212,37 +3104,31 @@ pub mod ast_gen {
 
             let ident = self.parse_ident(tokens)?;
 
-            let parameters =
-                self.parse_parenthesised(tokens, |this, tokens| {
-                    if tokens.is_next_token(Token::CloseParens) {
-                        Ok(this.ast.push_parameter_list([], loc))
-                    } else {
-                        this.parse_parameter_list(tokens)
-                    }
-                })?;
-
-            let return_type =
-                if let Some(_) = tokens.eat_token(Token::MinusGreater) {
-                    self.parse_type(tokens)?
+            let parameters = self.parse_parenthesised(tokens, |this, tokens| {
+                if tokens.is_next_token(Token::CloseParens) {
+                    Ok(this.ast.push_parameter_list([], loc))
                 } else {
-                    self.ast.push_interend_type(
-                        self.intern.get_void_type(),
-                        tokens.current_source_location(),
-                    )
-                };
+                    this.parse_parameter_list(tokens)
+                }
+            })?;
 
-            let decl =
-                self.ast.push_fn_proto(ident, return_type, parameters, loc);
+            let return_type = if let Some(_) = tokens.eat_token(Token::MinusGreater) {
+                self.parse_type(tokens)?
+            } else {
+                self.ast.push_interend_type(
+                    self.intern.get_void_type(),
+                    tokens.current_source_location(),
+                )
+            };
+
+            let decl = self.ast.push_fn_proto(ident, return_type, parameters, loc);
 
             Ok((decl, ident))
         }
 
-        fn parse_fn_inner(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_fn_inner(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             let loc = tokens.current_source_location();
-            let func = self.ast.reserve_node();
+            let func = self.ast.reserve_node(Kind::Function);
 
             self.push_scope(func, intern::Index::invalid());
 
@@ -3259,12 +3145,8 @@ pub mod ast_gen {
 
             self.ast.set_fn_decl(func, proto, body, loc);
 
-            self.syms.insert_symbol(
-                self.current_scope(),
-                ident,
-                SymbolKind::Function,
-                func,
-            );
+            self.syms
+                .insert_symbol(self.current_scope(), ident, SymbolKind::Function, func);
 
             Ok(func)
         }
@@ -3283,10 +3165,7 @@ pub mod ast_gen {
 
         /// RETURN_STATEMENT <-
         ///     return EXPRESSION? ;
-        fn parse_return_stmt(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_return_stmt(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             // SAFETY: function invariance
             let ret = tokens.next().unwrap();
             let loc = ret.source_location();
@@ -3318,10 +3197,7 @@ pub mod ast_gen {
         /// VAR_DECL <-
         ///     (let | var) IDENTIFIER (: TYPENAME)? ;
         ///     (let | var) IDENTIFIER (: TYPENAME)? = EXPRESSION ;
-        fn parse_var_decl(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_var_decl(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             match self.parse_var_decl_inner(tokens) {
                 Ok(i) => {
                     _ = tokens.eat_token(Token::Semi).ok_or(ErrorInfo {
@@ -3340,10 +3216,7 @@ pub mod ast_gen {
             }
         }
 
-        fn parse_var_decl_inner(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_var_decl_inner(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             // SAFETY: function invariance
             let let_or_var = tokens.next().unwrap();
             let loc = let_or_var.source_location();
@@ -3364,8 +3237,7 @@ pub mod ast_gen {
                 None
             };
 
-            let decl =
-                self.ast.push_var_decl(is_let, name, ty, assignment, loc);
+            let decl = self.ast.push_var_decl(is_let, name, ty, assignment, loc);
             self.syms.insert_symbol(
                 self.current_scope(),
                 name,
@@ -3406,10 +3278,10 @@ pub mod ast_gen {
                         _ => {
                             if self.is_statement(tokens) {
                                 // expr -> statements
-                                let expr = self.parse_with_trailing_semi(
-                                    tokens,
-                                    |this, tokens| this.parse_expr(tokens),
-                                )?;
+                                let expr = self
+                                    .parse_with_trailing_semi(tokens, |this, tokens| {
+                                        this.parse_expr(tokens)
+                                    })?;
 
                                 statements.push(expr);
                             } else {
@@ -3435,12 +3307,9 @@ pub mod ast_gen {
 
         /// BLOCK <-
         ///     { STATEMENT* EXPRESSION? }
-        fn parse_block(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_block(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             let block = self.parse_braced(tokens, |this, tokens| {
-                let block = this.ast.reserve_node();
+                let block = this.ast.reserve_node_other();
                 this.push_scope(block, intern::Index::invalid());
                 let block_result = this.parse_block_inner(block, tokens);
                 this.pop_scope();
@@ -3454,10 +3323,7 @@ pub mod ast_gen {
         /// PARAMETER_LIST <-
         ///     PARAMETER
         ///     PARAMETER_LIST , ARGUMENT
-        fn parse_parameter_list(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_parameter_list(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             let loc = tokens.current_source_location();
 
             let mut params = Vec::new();
@@ -3479,10 +3345,7 @@ pub mod ast_gen {
 
         /// PARAMETER <-
         ///    IDENT : TYPENAME
-        fn parse_parameter(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_parameter(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             let loc = tokens.current_source_location();
             let name = self.parse_ident(tokens)?;
             let Some(_) = tokens.eat_token(Token::Colon) else {
@@ -3494,12 +3357,8 @@ pub mod ast_gen {
             let ty = self.parse_type(tokens)?;
 
             let param = self.ast.push_parameter(name, ty, loc);
-            self.syms.insert_symbol(
-                self.current_scope(),
-                name,
-                SymbolKind::Local(loc),
-                param,
-            );
+            self.syms
+                .insert_symbol(self.current_scope(), name, SymbolKind::Local(loc), param);
 
             return Ok(param);
         }
@@ -3507,13 +3366,9 @@ pub mod ast_gen {
         /// ARGUMENT <-
         ///    IDENT : EXPR
         ///    EXPR
-        fn parse_argument(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_argument(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             let loc = tokens.current_source_location();
-            let name = if tokens.is_next_token2(Token::Colon)
-                && tokens.is_next_token(Token::Ident)
+            let name = if tokens.is_next_token2(Token::Colon) && tokens.is_next_token(Token::Ident)
             {
                 let name = self.parse_ident(tokens)?;
                 // we checked `is_next_token2`
@@ -3535,10 +3390,7 @@ pub mod ast_gen {
         /// ARGUMENT_LIST <-
         ///     ARGUMENT
         ///     ARGUMENT_LIST , ARGUMENT
-        fn parse_argument_list(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_argument_list(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             let loc = tokens.current_source_location();
             let mut args = Vec::new();
             loop {
@@ -3562,10 +3414,7 @@ pub mod ast_gen {
         ///     FLOATING_CONSTANT
         ///     ( EXPRESSION )
         ///     BLOCK
-        fn parse_primary_expr(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_primary_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             let loc = tokens.current_source_location();
 
             let Some(next) = tokens.peek_token() else {
@@ -3581,27 +3430,19 @@ pub mod ast_gen {
                 | Token::IntegerOctConstant
                 | Token::IntegerConstant => {
                     _ = tokens.next();
-                    return Ok(self.parse_integral_constant(
-                        &next,
-                        next.source_location(),
-                    ));
+                    return Ok(self.parse_integral_constant(&next, next.source_location()));
                 }
                 Token::FloatingConstant
                 | Token::FloatingExpConstant
                 | Token::DotFloatingConstant
                 | Token::DotFloatingExpConstant => {
                     _ = tokens.next();
-                    return Ok(self.parse_floating_constant(
-                        &next,
-                        next.source_location(),
-                    ));
+                    return Ok(self.parse_floating_constant(&next, next.source_location()));
                 }
 
                 Token::OpenParens => {
-                    let expr = self
-                        .parse_parenthesised(tokens, |this, tokens| {
-                            this.parse_expr(tokens)
-                        })?;
+                    let expr =
+                        self.parse_parenthesised(tokens, |this, tokens| this.parse_expr(tokens))?;
 
                     return Ok(expr);
                 }
@@ -3614,11 +3455,9 @@ pub mod ast_gen {
                     let ident = self
                         .intern
                         .get_or_insert(intern::Key::String { str: ident });
-                    return Ok(self.ast.push_decl_ref_unresolved(
-                        self.current_scope(),
-                        ident,
-                        loc,
-                    ));
+                    return Ok(self
+                        .ast
+                        .push_decl_ref_unresolved(self.current_scope(), ident, loc));
                 }
                 // TODO: eventually handle paths
                 _ => {
@@ -3636,14 +3475,9 @@ pub mod ast_gen {
         ///     PRIMARY_EXPR ( ARGUMENT_LIST )
         ///     PRIMARY_EXPR [ EXPR ]
         ///     POSTFIX_EXPR . IDENTIFIER
-        fn parse_postfix_expr(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_postfix_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             let mut lhs = self.parse_primary_expr(tokens)?;
-            while let Some(postfix) =
-                self.try_parse_postfix_expr_inner(tokens, lhs)?
-            {
+            while let Some(postfix) = self.try_parse_postfix_expr_inner(tokens, lhs)? {
                 lhs = postfix;
             }
 
@@ -3659,31 +3493,24 @@ pub mod ast_gen {
                 let loc = next.source_location();
                 match next.token() {
                     Token::OpenParens => {
-                        let arguments = self.parse_parenthesised(
-                            tokens,
-                            |this, tokens| {
-                                if tokens.is_next_token(Token::CloseParens) {
-                                    Ok(this.ast.push_argument_list([], loc))
-                                } else {
-                                    this.parse_argument_list(tokens)
-                                }
-                            },
-                        )?;
+                        let arguments = self.parse_parenthesised(tokens, |this, tokens| {
+                            if tokens.is_next_token(Token::CloseParens) {
+                                Ok(this.ast.push_argument_list([], loc))
+                            } else {
+                                this.parse_argument_list(tokens)
+                            }
+                        })?;
 
                         Some(self.ast.push_call_expr(lhs, arguments, loc))
                     }
                     Token::OpenSquareBracket => {
-                        let subscript = self
-                            .parse_bracketed(tokens, |this, tokens| {
-                                this.parse_expr(tokens)
-                            })?;
+                        let subscript =
+                            self.parse_bracketed(tokens, |this, tokens| this.parse_expr(tokens))?;
 
-                        Some(self.ast.push_binary(
-                            Tag::SubscriptExpr,
-                            lhs,
-                            subscript,
-                            loc,
-                        ))
+                        Some(
+                            self.ast
+                                .push_binary(Tag::SubscriptExpr, lhs, subscript, loc),
+                        )
                     }
                     Token::Dot if tokens.is_next_token2(Token::Ident) => {
                         _ = tokens.next();
@@ -3701,11 +3528,7 @@ pub mod ast_gen {
             Ok(lhs)
         }
 
-        fn push_error(
-            &mut self,
-            error: ParseError,
-            loc: SourceLocation,
-        ) -> Index {
+        fn push_error(&mut self, error: ParseError, loc: SourceLocation) -> Index {
             self.errors.push(ErrorInfo { error, loc });
             self.ast.push_error(error, loc)
         }
@@ -3716,10 +3539,7 @@ pub mod ast_gen {
         ///     - POSTFIX_EXPR
         ///     & POSTFIX_EXPR
         ///     * POSTFIX_EXPR
-        fn parse_prefix_expr(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_prefix_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             let next = tokens.peek_token().ok_or(ErrorInfo {
                 error: ParseError::ExpectedPrefixExpression,
                 loc: tokens.current_source_location(),
@@ -3757,10 +3577,7 @@ pub mod ast_gen {
         /// AS_EXPR <-
         ///     PREFIX_EXPR
         ///     PREFIX_EXPR as TYPENAME
-        fn parse_as_expr(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_as_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             let loc = tokens.current_source_location();
             let expr = self.parse_prefix_expr(tokens)?;
 
@@ -3805,8 +3622,7 @@ pub mod ast_gen {
                     break;
                 };
                 let loc = tok.source_location();
-                let Some(prec) = PRECEDENCE_MAP.get(&tok.token()).cloned()
-                else {
+                let Some(prec) = PRECEDENCE_MAP.get(&tok.token()).cloned() else {
                     break;
                 };
 
@@ -3853,10 +3669,7 @@ pub mod ast_gen {
         ///     BINARY_EXPRESSION ASSIGNMENT_OP EXPRESSION
         /// ASSIGNMENT_OP <-
         ///     = += -= *= /= %= ...
-        fn parse_assignment_expr(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_assignment_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             let lhs = self.parse_binary_expr(tokens, 0)?;
 
             if tokens
@@ -3898,10 +3711,7 @@ pub mod ast_gen {
 
         /// ELSE_EXPR <-
         ///     'else' (IF_EXPR | EXPR_OR_STATEMENT_OR_BLOCK)
-        fn parse_else_expr(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_else_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             // SAFETY: function invariance
             let _else_ = tokens.eat_token(Token::Else).unwrap();
 
@@ -3914,17 +3724,12 @@ pub mod ast_gen {
 
         /// IF_EXPR <-
         ///     'if' ( EXPR ) EXPR_OR_STATEMENT_OR_BLOCK ELSE_EXPR?
-        fn parse_if_expr(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_if_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             // SAFETY: function invariance
             let iff = tokens.eat_token(Token::If).unwrap();
             let loc = iff.source_location();
 
-            let cond = self.parse_parenthesised(tokens, |this, tokens| {
-                this.parse_expr(tokens)
-            })?;
+            let cond = self.parse_parenthesised(tokens, |this, tokens| this.parse_expr(tokens))?;
 
             let body = self.parse_expr_or_block_as_block(tokens)?;
 
@@ -3957,10 +3762,7 @@ pub mod ast_gen {
             }
         }
 
-        fn parse_expr(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             let loc = tokens.current_source_location();
             let Some(next) = tokens.peek_token() else {
                 return Err(ErrorInfo {
@@ -3981,10 +3783,7 @@ pub mod ast_gen {
         ///     type IDENTIFIER = extern? union { (IDENTIFIER: TYPE,)* }
         ///     type IDENTIFIER = extern? packed? enum { (IDENTIFIER (= EXPRESSION),)* }
         ///     type IDENTIFIER = extern? packed? struct { (IDENTIFIER: TYPE,)* }
-        fn parse_type_decl(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_type_decl(&mut self, tokens: &mut TokenIterator) -> ParseResult<Index> {
             _ = tokens.eat_token(Token::Type).ok_or(ErrorInfo {
                 error: ParseError::ExpectedToken(Token::Type),
                 loc: tokens.current_source_location(),
@@ -3999,8 +3798,7 @@ pub mod ast_gen {
             });
 
             let (has_attributes, c_like, packed) = {
-                let vec = tokens
-                    .eat_all_zero_or_once(&[Token::Extern, Token::Packed]);
+                let vec = tokens.eat_all_zero_or_once(&[Token::Extern, Token::Packed]);
                 (vec[0] || vec[1], vec[0], vec[1])
             };
 
@@ -4012,9 +3810,7 @@ pub mod ast_gen {
             };
 
             let decl = match next.token() {
-                Token::Struct => {
-                    self.parse_struct_decl(tokens, name, c_like, packed, loc)
-                }
+                Token::Struct => self.parse_struct_decl(tokens, name, c_like, packed, loc),
                 Token::Union => {
                     unimplemented!()
                 }
@@ -4047,12 +3843,8 @@ pub mod ast_gen {
                 }
             }?;
 
-            self.syms.insert_symbol(
-                self.current_scope(),
-                name,
-                SymbolKind::Type,
-                decl,
-            );
+            self.syms
+                .insert_symbol(self.current_scope(), name, SymbolKind::Type, decl);
 
             Ok(decl)
         }
@@ -4062,37 +3854,25 @@ pub mod ast_gen {
         /// TYPE_UNION <-
         ///     TYPE (| TYPE_UNION)?
         ///     IDENTIFIER: TYPE (| TYPE_UNION)?
-        fn parse_sumtype_decl(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_sumtype_decl(&mut self, _tokens: &mut TokenIterator) -> ParseResult<Index> {
             todo!()
         }
 
         /// TUPLE_DECL <-
         ///     type IDENTIFIER = (TYPE,* )
-        fn parse_tuple_decl(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_tuple_decl(&mut self, _tokens: &mut TokenIterator) -> ParseResult<Index> {
             todo!()
         }
 
         /// UNION_DECL <-
         ///     type IDENTIFIER = union { IDENTIFIER: TYPE,* }
-        fn parse_union_decl(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_union_decl(&mut self, _tokens: &mut TokenIterator) -> ParseResult<Index> {
             todo!()
         }
 
         /// ENUM_DECL <-
         ///     type IDENTIFIER = packed? enum { IDENTIFIER (= EXPRESSION),* }
-        fn parse_enum_decl(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> ParseResult<Index> {
+        fn parse_enum_decl(&mut self, _tokens: &mut TokenIterator) -> ParseResult<Index> {
             todo!()
         }
 
@@ -4113,12 +3893,11 @@ pub mod ast_gen {
                 loc: tokens.current_source_location(),
             })?;
 
-            let decl = self.ast.reserve_node();
+            let decl = self.ast.reserve_node(Kind::GlobalDecl);
             let decl = self.parse_braced(tokens, |this, tokens| {
                 this.parse_struct_fields(tokens).map(|fields| {
                     _ = tokens.eat_token(Token::Comma);
-                    let flags =
-                        StructFlags::new(packed, c_like, fields.len() as u32);
+                    let flags = StructFlags::new(packed, c_like, fields.len() as u32);
 
                     this.intern.insert_or_replace_struct_type(
                         name,
@@ -4172,12 +3951,7 @@ pub mod ast_gen {
         ) -> ParseResult<Index>
         where
             F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<Index>,
-            E: FnOnce(
-                &mut Self,
-                &mut TokenIterator,
-                ErrorInfo,
-                TokenItem,
-            ) -> ParseResult<Index>,
+            E: FnOnce(&mut Self, &mut TokenIterator, ErrorInfo, TokenItem) -> ParseResult<Index>,
         {
             let Some(start) = tokens.eat_token(open) else {
                 return Err(ErrorInfo {
@@ -4190,20 +3964,14 @@ pub mod ast_gen {
                 Ok(i) => {
                     _ = tokens.eat_token(close).ok_or(ErrorInfo {
                         error: match open {
-                            Token::OpenBrace => ParseError::UnmatchedBrace(
-                                start.token_pos().start,
-                            ),
-                            Token::OpenParens => ParseError::UnmatchedParens(
-                                start.token_pos().start,
-                            ),
-                            Token::OpenSquareBracket => {
-                                ParseError::UnmatchedSquareBracket(
-                                    start.token_pos().start,
-                                )
+                            Token::OpenBrace => ParseError::UnmatchedBrace(start.token_pos().start),
+                            Token::OpenParens => {
+                                ParseError::UnmatchedParens(start.token_pos().start)
                             }
-                            _ => ParseError::UnmatchedDelimiter(
-                                start.token_pos().start,
-                            ),
+                            Token::OpenSquareBracket => {
+                                ParseError::UnmatchedSquareBracket(start.token_pos().start)
+                            }
+                            _ => ParseError::UnmatchedDelimiter(start.token_pos().start),
                         },
                         loc: tokens.current_source_location(),
                     })?;
@@ -4224,61 +3992,39 @@ pub mod ast_gen {
         where
             F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<Index>,
         {
-            self.parse_inner(
-                tokens,
-                open,
-                close,
-                parse,
-                |this, tokens, err, start| {
-                    match close {
-                        Token::CloseBrace => {
-                            tokens.advance_past_end_of_braced().ok_or(
-                                ErrorInfo {
-                                    error: ParseError::UnmatchedBrace(
-                                        start.token_pos().start,
-                                    ),
-                                    loc: tokens.current_source_location(),
-                                },
-                            )?;
-                        }
-                        Token::CloseParens => {
-                            tokens.advance_past_end_of_parens().ok_or(
-                                ErrorInfo {
-                                    error: ParseError::UnmatchedParens(
-                                        start.token_pos().start,
-                                    ),
-                                    loc: tokens.current_source_location(),
-                                },
-                            )?;
-                        }
-                        Token::CloseSquareBracket => {
-                            tokens.advance_past_end_of_bracketed().ok_or(
-                                ErrorInfo {
-                                    error: ParseError::UnmatchedSquareBracket(
-                                        start.token_pos().start,
-                                    ),
-                                    loc: tokens.current_source_location(),
-                                },
-                            )?;
-                        }
-                        Token::Semi => {
-                            tokens.advance_past_semi().ok_or(ErrorInfo {
-                                error: ParseError::ExpectedToken(Token::Semi),
-                                loc: tokens.current_source_location(),
-                            })?;
-                        }
-                        _ => unimplemented!(),
+            self.parse_inner(tokens, open, close, parse, |this, tokens, err, start| {
+                match close {
+                    Token::CloseBrace => {
+                        tokens.advance_past_end_of_braced().ok_or(ErrorInfo {
+                            error: ParseError::UnmatchedBrace(start.token_pos().start),
+                            loc: tokens.current_source_location(),
+                        })?;
                     }
-                    Ok(this.push_error(err.error, err.loc))
-                },
-            )
+                    Token::CloseParens => {
+                        tokens.advance_past_end_of_parens().ok_or(ErrorInfo {
+                            error: ParseError::UnmatchedParens(start.token_pos().start),
+                            loc: tokens.current_source_location(),
+                        })?;
+                    }
+                    Token::CloseSquareBracket => {
+                        tokens.advance_past_end_of_bracketed().ok_or(ErrorInfo {
+                            error: ParseError::UnmatchedSquareBracket(start.token_pos().start),
+                            loc: tokens.current_source_location(),
+                        })?;
+                    }
+                    Token::Semi => {
+                        tokens.advance_past_semi().ok_or(ErrorInfo {
+                            error: ParseError::ExpectedToken(Token::Semi),
+                            loc: tokens.current_source_location(),
+                        })?;
+                    }
+                    _ => unimplemented!(),
+                }
+                Ok(this.push_error(err.error, err.loc))
+            })
         }
 
-        fn parse_bracketed<F>(
-            &mut self,
-            tokens: &mut TokenIterator,
-            parse: F,
-        ) -> ParseResult<Index>
+        fn parse_bracketed<F>(&mut self, tokens: &mut TokenIterator, parse: F) -> ParseResult<Index>
         where
             F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<Index>,
         {
@@ -4290,20 +4036,11 @@ pub mod ast_gen {
             )
         }
 
-        fn parse_braced<F>(
-            &mut self,
-            tokens: &mut TokenIterator,
-            parse: F,
-        ) -> ParseResult<Index>
+        fn parse_braced<F>(&mut self, tokens: &mut TokenIterator, parse: F) -> ParseResult<Index>
         where
             F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<Index>,
         {
-            self.parse_inner2(
-                tokens,
-                Token::OpenBrace,
-                Token::CloseBrace,
-                parse,
-            )
+            self.parse_inner2(tokens, Token::OpenBrace, Token::CloseBrace, parse)
         }
 
         fn parse_parenthesised<F>(
@@ -4314,12 +4051,7 @@ pub mod ast_gen {
         where
             F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult<Index>,
         {
-            self.parse_inner2(
-                tokens,
-                Token::OpenParens,
-                Token::CloseParens,
-                parse,
-            )
+            self.parse_inner2(tokens, Token::OpenParens, Token::CloseParens, parse)
         }
 
         fn parse_struct_fields(
@@ -4387,24 +4119,22 @@ pub mod ast_gen {
         fn parse_file(&mut self, tokens: &mut TokenIterator) -> Index {
             let start = tokens.current_source_location();
             let mut decls = Vec::new();
-            let file = self.ast.reserve_node();
+            let file = self.ast.reserve_node(Kind::File);
             self.push_scope(file, intern::Index::invalid());
 
             while let Some(next) = tokens.peek_token() {
                 let loc = next.source_location();
-                let decl = match self.parse_constant_decls(tokens).and_then(
-                    |i| match i {
-                        Some(i) => Ok(i),
-                        None => {
-                            let error = ParseError::UnexpectedTokenAtFileScope;
-                            let node = self.push_error(error, loc);
+                let decl = match self.parse_constant_decls(tokens).and_then(|i| match i {
+                    Some(i) => Ok(i),
+                    None => {
+                        let error = ParseError::UnexpectedTokenAtFileScope;
+                        let node = self.push_error(error, loc);
 
-                            self.find_next_fn_or_const(tokens);
+                        self.find_next_fn_or_const(tokens);
 
-                            Ok(node)
-                        }
-                    },
-                ) {
+                        Ok(node)
+                    }
+                }) {
                     Ok(i) => i,
                     Err(err) => self.push_error(err.error, err.loc),
                 };
@@ -4487,16 +4217,9 @@ pub mod ast_gen {
             false
         }
 
-        fn find_next_fn_or_const(
-            &mut self,
-            tokens: &mut TokenIterator,
-        ) -> Option<()> {
+        fn find_next_fn_or_const(&mut self, tokens: &mut TokenIterator) -> Option<()> {
             tokens
-                .advance_until_before_one_of(&[
-                    Token::Const,
-                    Token::Fn,
-                    Token::Type,
-                ])
+                .advance_until_before_one_of(&[Token::Const, Token::Fn, Token::Type])
                 .map(|_| ())
         }
     }
@@ -4504,12 +4227,8 @@ pub mod ast_gen {
 
 pub mod irgen {
 
-    use super::visitor::AstExt;
     use super::*;
-    use crate::{
-        symbol_table::syms2::Symbols,
-        triples::{self, *},
-    };
+    use crate::{symbol_table::syms2::Symbols, triples::*};
     use std::collections::HashMap;
 
     struct IRGen {
@@ -4524,6 +4243,7 @@ pub mod irgen {
             let mut mapping = HashMap::<Index, u32>::new();
             self.ast.visitor().visit(
                 |ast, scopes, i, tag, data| {
+                    _ = (&mapping, ast, scopes, i, tag, data);
                     // pre
                     match tag {
                         Tag::Root => todo!(),
@@ -4589,6 +4309,7 @@ pub mod irgen {
                     }
                 },
                 |ast, scopes, i, tag, data| {
+                    _ = (&mapping, ast, scopes, i, tag, data);
                     // post
                     match tag {
                         Tag::Root => todo!(),
diff --git a/src/bin/main.rs b/src/bin/main.rs
index b745648..b46523b 100644
--- a/src/bin/main.rs
+++ b/src/bin/main.rs
@@ -1,8 +1,7 @@
-use std::{io::Read, path::PathBuf, sync::Arc};
+use std::{io::Read, path::PathBuf};
 
 use clap::Command;
 use compiler::{
-    ast2::intern::InternPool,
     lexer::Tokenizer,
     parser::Tree,
     triples::{MirBuilder, IR},
@@ -29,8 +28,7 @@ fn main() {
         .subcommands([
             Command::new("ast").about("output AST."),
             Command::new("ast2").about("output AST."),
-            Command::new("mir")
-                .about("output machine-level intermediate representation."),
+            Command::new("mir").about("output machine-level intermediate representation."),
             Command::new("ir").about("output intermediate representation."),
             Command::new("asm").about("output x86-64 assembly (intel syntax)."),
         ]);
@@ -85,11 +83,7 @@ fn main() {
                 } = mir;
 
                 for (name, mir) in functions {
-                    println!(
-                        "{}:\n{}",
-                        strings.get_str(name),
-                        mir.display(&strings)
-                    );
+                    println!("{}:\n{}", strings.get_str(name), mir.display(&strings));
                 }
             }
             "asm" => {
diff --git a/src/lib.rs b/src/lib.rs
index 5517302..6cd1907 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -31,10 +31,7 @@ pub mod triples;
 
 pub fn tokenize<'a>(
     bytes: &'a [u8],
-) -> Result<
-    lexer::Tokenizer<'a>,
-    (lexer::Tokenizer<'a>, Vec<lexer::TokenizeError>),
-> {
+) -> Result<lexer::Tokenizer<'a>, (lexer::Tokenizer<'a>, Vec<lexer::TokenizeError>)> {
     lexer::Tokenizer::new_with_errors(bytes)
 }
 
diff --git a/src/mir.rs b/src/mir.rs
index 018a6d1..83f5c44 100644
--- a/src/mir.rs
+++ b/src/mir.rs
@@ -11,7 +11,6 @@ use std::u32;
 use itertools::Itertools;
 
 use crate::asm::amd64::Register;
-use crate::ast::IntegralType;
 use crate::ast2::intern;
 
 #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
@@ -104,9 +103,7 @@ impl Type {
             Type::Byte => Inst::ConstantByte,
             Type::Word => Inst::ConstantWord,
             Type::SinglePrecision | Type::DWord => Inst::ConstantDWord,
-            Type::Function | Type::DoublePrecision | Type::QWord => {
-                Inst::ConstantQWord
-            }
+            Type::Function | Type::DoublePrecision | Type::QWord => Inst::ConstantQWord,
         }
     }
 
@@ -521,16 +518,12 @@ impl OperandKinds {
         reg.union(mem).union(imm)
     }
     const fn to_lhs_binop(self) -> BinaryOperandFlags {
-        let reg = if self
-            .intersects(Self::RegReg.union(Self::RegImm).union(Self::RegMem))
-        {
+        let reg = if self.intersects(Self::RegReg.union(Self::RegImm).union(Self::RegMem)) {
             BinaryOperandFlags::LhsReg
         } else {
             BinaryOperandFlags::empty()
         };
-        let mem = if self
-            .intersects(Self::MemReg.union(Self::MemMem).union(Self::MemImm))
-        {
+        let mem = if self.intersects(Self::MemReg.union(Self::MemMem).union(Self::MemImm)) {
             BinaryOperandFlags::LhsMem
         } else {
             BinaryOperandFlags::empty()
@@ -602,13 +595,7 @@ struct BinaryOperandsRunner<'a> {
 
 impl<'a> BinaryOperandsRunner<'a> {
     #[allow(dead_code)]
-    fn new(
-        inner: BinaryOperands<'a>,
-        lhs: u32,
-        lhs_type: Type,
-        rhs: u32,
-        rhs_type: Type,
-    ) -> Self {
+    fn new(inner: BinaryOperands<'a>, lhs: u32, lhs_type: Type, rhs: u32, rhs_type: Type) -> Self {
         Self {
             inner,
             lhs: (lhs, lhs_type),
@@ -659,9 +646,7 @@ impl<'a> BinaryOperandsRunner<'a> {
         let l_kind = self.mir().as_operand_kind(lhs).as_lhs();
         let r_kind = self.mir().as_operand_kind(rhs).as_rhs();
 
-        if self.inner.commutative
-            && (!l_legal.contains(l_kind) && l_legal.contains(r_kind))
-        {
+        if self.inner.commutative && (!l_legal.contains(l_kind) && l_legal.contains(r_kind)) {
             core::mem::swap(&mut self.lhs, &mut self.rhs);
         }
     }
@@ -722,13 +707,7 @@ impl<'a> BinaryOperands<'a> {
         Self::new(mir, false, OperandKinds::shift())
     }
 
-    fn wrangle(
-        self,
-        lhs: u32,
-        lhs_type: Type,
-        rhs: u32,
-        rhs_type: Type,
-    ) -> (u32, u32) {
+    fn wrangle(self, lhs: u32, lhs_type: Type, rhs: u32, rhs_type: Type) -> (u32, u32) {
         let mut runner = BinaryOperandsRunner {
             inner: self,
             lhs: (lhs, lhs_type),
@@ -805,10 +784,7 @@ impl Mir {
         self.data[node.index()] = data;
     }
 
-    fn indices(
-        &self,
-    ) -> impl Iterator<Item = NodeRef> + DoubleEndedIterator + FusedIterator
-    {
+    fn indices(&self) -> impl Iterator<Item = NodeRef> + DoubleEndedIterator + FusedIterator {
         (0..self.nodes.len() as u32).map(|n| NodeRef::from(n))
     }
 }
@@ -868,12 +844,7 @@ impl Mir {
         node
     }
 
-    pub fn push_const(
-        &mut self,
-        ip: &intern::InternPool,
-        value: intern::Index,
-        ty: Type,
-    ) -> u32 {
+    pub fn push_const(&mut self, ip: &intern::InternPool, value: intern::Index, ty: Type) -> u32 {
         let inst = match ty {
             Type::Byte => Inst::ConstantByte,
             Type::Word => Inst::ConstantWord,
@@ -974,63 +945,27 @@ impl Mir {
         }
     }
 
-    pub fn gen_is_eq(
-        &mut self,
-        ty: Type,
-        signed: bool,
-        lhs: u32,
-        rhs: u32,
-    ) -> u32 {
+    pub fn gen_is_eq(&mut self, ty: Type, signed: bool, lhs: u32, rhs: u32) -> u32 {
         let cmp = self.gen_cmp(ty, lhs, rhs);
         self.push(Inst::IsEq(signed), Data::node(cmp))
     }
-    pub fn gen_is_neq(
-        &mut self,
-        ty: Type,
-        signed: bool,
-        lhs: u32,
-        rhs: u32,
-    ) -> u32 {
+    pub fn gen_is_neq(&mut self, ty: Type, signed: bool, lhs: u32, rhs: u32) -> u32 {
         let cmp = self.gen_cmp(ty, lhs, rhs);
         self.push(Inst::IsNeq(signed), Data::node(cmp))
     }
-    pub fn gen_is_gt(
-        &mut self,
-        ty: Type,
-        signed: bool,
-        lhs: u32,
-        rhs: u32,
-    ) -> u32 {
+    pub fn gen_is_gt(&mut self, ty: Type, signed: bool, lhs: u32, rhs: u32) -> u32 {
         let cmp = self.gen_cmp(ty, lhs, rhs);
         self.push(Inst::IsGt(signed), Data::node(cmp))
     }
-    pub fn gen_is_lt(
-        &mut self,
-        ty: Type,
-        signed: bool,
-        lhs: u32,
-        rhs: u32,
-    ) -> u32 {
+    pub fn gen_is_lt(&mut self, ty: Type, signed: bool, lhs: u32, rhs: u32) -> u32 {
         let cmp = self.gen_cmp(ty, lhs, rhs);
         self.push(Inst::IsLt(signed), Data::node(cmp))
     }
-    pub fn gen_is_ge(
-        &mut self,
-        ty: Type,
-        signed: bool,
-        lhs: u32,
-        rhs: u32,
-    ) -> u32 {
+    pub fn gen_is_ge(&mut self, ty: Type, signed: bool, lhs: u32, rhs: u32) -> u32 {
         let cmp = self.gen_cmp(ty, lhs, rhs);
         self.push(Inst::IsGe(signed), Data::node(cmp))
     }
-    pub fn gen_is_le(
-        &mut self,
-        ty: Type,
-        signed: bool,
-        lhs: u32,
-        rhs: u32,
-    ) -> u32 {
+    pub fn gen_is_le(&mut self, ty: Type, signed: bool, lhs: u32, rhs: u32) -> u32 {
         let cmp = self.gen_cmp(ty, lhs, rhs);
         self.push(Inst::IsLe(signed), Data::node(cmp))
     }
@@ -1057,12 +992,7 @@ impl Mir {
     pub fn gen_load(&mut self, ty: Type, src: u32) -> u32 {
         self.push(Inst::Load(ty), Data::node(src))
     }
-    pub fn gen_get_element_ptr(
-        &mut self,
-        ty: Type,
-        src: u32,
-        index: u32,
-    ) -> u32 {
+    pub fn gen_get_element_ptr(&mut self, ty: Type, src: u32, index: u32) -> u32 {
         self.push(Inst::GetElementPtr(ty), Data::binary(src, index))
     }
     pub fn gen_store(&mut self, ty: Type, src: u32, dst: u32) -> u32 {
@@ -1100,13 +1030,7 @@ impl Mir {
     }
 
     /// truncates a value `src` of `mir::Type` `ty` to `bits` bits, while preserving the sign
-    pub fn gen_truncate_integer(
-        &mut self,
-        src: u32,
-        ty: Type,
-        signed: bool,
-        bits: u16,
-    ) -> u32 {
+    pub fn gen_truncate_integer(&mut self, src: u32, ty: Type, signed: bool, bits: u16) -> u32 {
         // example: u4 -> (byte, false, 4)
         // 1111_1111 << 4 = 1111_0000
         // mask = 0000_1111;
@@ -1118,9 +1042,7 @@ impl Mir {
             Type::Byte => self.gen_u8(mask as u8),
             Type::Word => self.gen_u16(mask as u16),
             Type::SinglePrecision | Type::DWord => self.gen_u32(mask as u32),
-            Type::Function | Type::DoublePrecision | Type::QWord => {
-                self.gen_u64(mask as u64)
-            }
+            Type::Function | Type::DoublePrecision | Type::QWord => self.gen_u64(mask as u64),
         };
 
         let masked = self.gen_bitand(ty, src, mask);
@@ -1151,12 +1073,7 @@ impl Mir {
         // mask = 0000_1111;
         // shift = 8 - 4;
         let src_ty = Type::from_bitsize_int(from.bitsize);
-        let truncated = self.gen_truncate_integer(
-            src,
-            src_ty,
-            from.signed,
-            from.bitsize as u16,
-        );
+        let truncated = self.gen_truncate_integer(src, src_ty, from.signed, from.bitsize as u16);
 
         let dst_ty = Type::from_bitsize_int(to.bitsize);
         if to.signed {
@@ -1179,8 +1096,7 @@ impl Mir {
         let (lhs, rhs) = if ty.is_floating() {
             BinaryOperands::new_sse(self).wrangle(lhs, ty, rhs, ty)
         } else {
-            BinaryOperands::new_add_or_and_xor_adc(self)
-                .wrangle(lhs, ty, rhs, ty)
+            BinaryOperands::new_add_or_and_xor_adc(self).wrangle(lhs, ty, rhs, ty)
         };
         self.push(Inst::Add(ty), Data::binary(lhs, rhs))
     }
@@ -1192,13 +1108,7 @@ impl Mir {
         };
         self.push(Inst::Sub(ty), Data::binary(lhs, rhs))
     }
-    pub fn gen_mul(
-        &mut self,
-        ty: Type,
-        signed: bool,
-        lhs: u32,
-        rhs: u32,
-    ) -> u32 {
+    pub fn gen_mul(&mut self, ty: Type, signed: bool, lhs: u32, rhs: u32) -> u32 {
         if ty.is_floating() {
             self.gen_mul_sse(ty, lhs, rhs)
         } else if signed {
@@ -1208,27 +1118,18 @@ impl Mir {
         }
     }
     pub fn gen_mul_sse(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 {
-        let (lhs, rhs) =
-            BinaryOperands::new_sse(self).wrangle(lhs, ty, rhs, ty);
+        let (lhs, rhs) = BinaryOperands::new_sse(self).wrangle(lhs, ty, rhs, ty);
         self.push(Inst::MulSSE(ty), Data::binary(lhs, rhs))
     }
     pub fn gen_mul_unsigned(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 {
-        let (lhs, rhs) =
-            BinaryOperands::new_mul(self).wrangle(lhs, ty, rhs, ty);
+        let (lhs, rhs) = BinaryOperands::new_mul(self).wrangle(lhs, ty, rhs, ty);
         self.push(Inst::Mul(ty), Data::binary(lhs, rhs))
     }
     pub fn gen_mul_signed(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 {
-        let (lhs, rhs) =
-            BinaryOperands::new_imul(self).wrangle(lhs, ty, rhs, ty);
+        let (lhs, rhs) = BinaryOperands::new_imul(self).wrangle(lhs, ty, rhs, ty);
         self.push(Inst::MulSigned(ty), Data::binary(lhs, rhs))
     }
-    pub fn gen_div(
-        &mut self,
-        ty: Type,
-        signed: bool,
-        lhs: u32,
-        rhs: u32,
-    ) -> u32 {
+    pub fn gen_div(&mut self, ty: Type, signed: bool, lhs: u32, rhs: u32) -> u32 {
         if ty.is_floating() {
             self.gen_div_sse(ty, lhs, rhs)
         } else if signed {
@@ -1238,27 +1139,18 @@ impl Mir {
         }
     }
     pub fn gen_div_sse(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 {
-        let (lhs, rhs) =
-            BinaryOperands::new_sse(self).wrangle(lhs, ty, rhs, ty);
+        let (lhs, rhs) = BinaryOperands::new_sse(self).wrangle(lhs, ty, rhs, ty);
         self.push(Inst::DivSSE(ty), Data::binary(lhs, rhs))
     }
     pub fn gen_div_unsigned(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 {
-        let (lhs, rhs) = BinaryOperands::new_div_idiv_rem_irem(self)
-            .wrangle(lhs, ty, rhs, ty);
+        let (lhs, rhs) = BinaryOperands::new_div_idiv_rem_irem(self).wrangle(lhs, ty, rhs, ty);
         self.push(Inst::Div(ty), Data::binary(lhs, rhs))
     }
     pub fn gen_div_signed(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 {
-        let (lhs, rhs) = BinaryOperands::new_div_idiv_rem_irem(self)
-            .wrangle(lhs, ty, rhs, ty);
+        let (lhs, rhs) = BinaryOperands::new_div_idiv_rem_irem(self).wrangle(lhs, ty, rhs, ty);
         self.push(Inst::DivSigned(ty), Data::binary(lhs, rhs))
     }
-    pub fn gen_rem(
-        &mut self,
-        ty: Type,
-        signed: bool,
-        lhs: u32,
-        rhs: u32,
-    ) -> u32 {
+    pub fn gen_rem(&mut self, ty: Type, signed: bool, lhs: u32, rhs: u32) -> u32 {
         if ty.is_floating() {
             self.gen_rem_fp(ty, lhs, rhs)
         } else if signed {
@@ -1269,34 +1161,28 @@ impl Mir {
     }
     pub fn gen_rem_fp(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 {
         let (lhs, rhs) =
-            BinaryOperands::new(self, false, OperandKinds::any_mem_reg())
-                .wrangle(lhs, ty, rhs, ty);
+            BinaryOperands::new(self, false, OperandKinds::any_mem_reg()).wrangle(lhs, ty, rhs, ty);
         self.push(Inst::RemFP(ty), Data::binary(lhs, rhs))
     }
     pub fn gen_rem_unsigned(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 {
-        let (lhs, rhs) = BinaryOperands::new_div_idiv_rem_irem(self)
-            .wrangle(lhs, ty, rhs, ty);
+        let (lhs, rhs) = BinaryOperands::new_div_idiv_rem_irem(self).wrangle(lhs, ty, rhs, ty);
         self.push(Inst::Rem(ty), Data::binary(lhs, rhs))
     }
     pub fn gen_rem_signed(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 {
-        let (lhs, rhs) = BinaryOperands::new_div_idiv_rem_irem(self)
-            .wrangle(lhs, ty, rhs, ty);
+        let (lhs, rhs) = BinaryOperands::new_div_idiv_rem_irem(self).wrangle(lhs, ty, rhs, ty);
         self.push(Inst::RemSigned(ty), Data::binary(lhs, rhs))
     }
 
     pub fn gen_bitand(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 {
-        let (lhs, rhs) = BinaryOperands::new_add_or_and_xor_adc(self)
-            .wrangle(lhs, ty, rhs, ty);
+        let (lhs, rhs) = BinaryOperands::new_add_or_and_xor_adc(self).wrangle(lhs, ty, rhs, ty);
         self.push(Inst::BitAnd(ty), Data::binary(lhs, rhs))
     }
     pub fn gen_bitor(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 {
-        let (lhs, rhs) = BinaryOperands::new_add_or_and_xor_adc(self)
-            .wrangle(lhs, ty, rhs, ty);
+        let (lhs, rhs) = BinaryOperands::new_add_or_and_xor_adc(self).wrangle(lhs, ty, rhs, ty);
         self.push(Inst::BitOr(ty), Data::binary(lhs, rhs))
     }
     pub fn gen_bitxor(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 {
-        let (lhs, rhs) = BinaryOperands::new_add_or_and_xor_adc(self)
-            .wrangle(lhs, ty, rhs, ty);
+        let (lhs, rhs) = BinaryOperands::new_add_or_and_xor_adc(self).wrangle(lhs, ty, rhs, ty);
         self.push(Inst::BitXOr(ty), Data::binary(lhs, rhs))
     }
     pub fn gen_negate(&mut self, ty: Type, src: u32) -> u32 {
@@ -1310,20 +1196,17 @@ impl Mir {
 
     #[doc(alias = "gen_shift_left")]
     pub fn gen_shl(&mut self, ty: Type, src: u32, shift: u32) -> u32 {
-        let (src, shift) =
-            BinaryOperands::new_shift(self).wrangle(src, ty, shift, Type::Byte);
+        let (src, shift) = BinaryOperands::new_shift(self).wrangle(src, ty, shift, Type::Byte);
         self.push(Inst::ShiftLeft(ty), Data::binary(src, shift))
     }
     #[doc(alias = "gen_shift_right")]
     pub fn gen_shr(&mut self, ty: Type, src: u32, shift: u32) -> u32 {
-        let (src, shift) =
-            BinaryOperands::new_shift(self).wrangle(src, ty, shift, Type::Byte);
+        let (src, shift) = BinaryOperands::new_shift(self).wrangle(src, ty, shift, Type::Byte);
         self.push(Inst::ShiftRightUnsigned(ty), Data::binary(src, shift))
     }
     #[doc(alias = "gen_shift_right_signed")]
     pub fn gen_sar(&mut self, ty: Type, src: u32, shift: u32) -> u32 {
-        let (src, shift) =
-            BinaryOperands::new_shift(self).wrangle(src, ty, shift, Type::Byte);
+        let (src, shift) = BinaryOperands::new_shift(self).wrangle(src, ty, shift, Type::Byte);
         self.push(Inst::ShiftRightSigned(ty), Data::binary(src, shift))
     }
     pub fn gen_ret_val(&mut self, ty: Type, val: u32) -> u32 {
@@ -1354,11 +1237,9 @@ impl Mir {
             Inst::Label => {
                 writeln!(w, "%{node} = label {}", ip.get_str(data.as_index()))
             }
-            Inst::ConstantBytes => writeln!(
-                w,
-                "%{node} = bytes({:x?})",
-                ip.get_bytes(data.as_index())
-            ),
+            Inst::ConstantBytes => {
+                writeln!(w, "%{node} = bytes({:x?})", ip.get_bytes(data.as_index()))
+            }
             Inst::ConstantByte => {
                 writeln!(w, "%{node} = imm8({:x?})", data.as_imm8())
             }
@@ -1398,10 +1279,7 @@ impl Mir {
             }
             Inst::GetElementPtr(ty) => {
                 let (ptr, idx) = data.as_binary();
-                writeln!(
-                    w,
-                    "%{node} = get element ptr {ty}, ptr %{ptr}, idx {idx}"
-                )
+                writeln!(w, "%{node} = get element ptr {ty}, ptr %{ptr}, idx {idx}")
             }
             Inst::Load(ty) => {
                 writeln!(w, "%{node} = load {ty}, ptr %{}", data.as_node())
@@ -1538,10 +1416,7 @@ impl Mir {
             }
             Inst::ShiftRightSigned(ty) => {
                 let (lhs, rhs) = data.as_binary();
-                writeln!(
-                    w,
-                    "%{node} = signed shift right {ty} %{lhs}, {ty} %{rhs}"
-                )
+                writeln!(w, "%{node} = signed shift right {ty} %{lhs}, {ty} %{rhs}")
             }
             Inst::ReturnValue(ty) => {
                 let lhs = data.as_node();
@@ -1577,10 +1452,7 @@ impl Mir {
         Ok(())
     }
 
-    pub fn display<'a, 'b>(
-        &'a self,
-        ip: &'b intern::InternPool,
-    ) -> DisplayMir<'a, 'b> {
+    pub fn display<'a, 'b>(&'a self, ip: &'b intern::InternPool) -> DisplayMir<'a, 'b> {
         DisplayMir { mir: self, ip }
     }
 }
@@ -1627,9 +1499,9 @@ pub mod liveness {
             let dirty = self
                 .interference_graph_for_node(node)
                 .map(|graph| {
-                    graph.neighbors(node.0.into()).filter_map(|n| {
-                        register_map.get(&NodeRef(n.index() as u32)).cloned()
-                    })
+                    graph
+                        .neighbors(node.0.into())
+                        .filter_map(|n| register_map.get(&NodeRef(n.index() as u32)).cloned())
                 })
                 .into_iter()
                 .flatten()
@@ -1686,10 +1558,7 @@ pub mod liveness {
             }
         }
 
-        pub fn new(
-            mir: &Mir,
-            references: &BTreeSet<(NodeRef, NodeRef)>,
-        ) -> Self {
+        pub fn new(mir: &Mir, references: &BTreeSet<(NodeRef, NodeRef)>) -> Self {
             let mut sorted_branches = Vec::new();
             let mut branch_graph_edges = Vec::new();
 
@@ -1785,9 +1654,7 @@ pub mod liveness {
                 .map(|(range, edges)| {
                     (
                         range,
-                        InterferenceGraph::from_edges(
-                            edges.into_iter().map(|(a, b)| (a.0, b.0)),
-                        ),
+                        InterferenceGraph::from_edges(edges.into_iter().map(|(a, b)| (a.0, b.0))),
                     )
                 })
                 .collect::<Vec<_>>();
@@ -1814,16 +1681,11 @@ pub mod liveness {
 
         fn branch_index_for_node(&self, node: NodeRef) -> Option<usize> {
             self.branches
-                .binary_search_by(|(range, _)| {
-                    range.partial_cmp(&node).unwrap()
-                })
+                .binary_search_by(|(range, _)| range.partial_cmp(&node).unwrap())
                 .ok()
         }
 
-        pub fn interference_graph_for_node(
-            &self,
-            node: NodeRef,
-        ) -> Option<&InterferenceGraph> {
+        pub fn interference_graph_for_node(&self, node: NodeRef) -> Option<&InterferenceGraph> {
             if let Some(index) = self.branch_index_for_node(node) {
                 Some(&self.branches[index].1)
             } else {
@@ -1907,8 +1769,7 @@ pub mod liveness {
 
             use Register::*;
             let mut in_colors = [r9, r8, rcx, rdx, rdi, rsi].to_vec();
-            let mut in_colors_sse =
-                [xmm7, xmm6, xmm5, xmm4, xmm3, xmm2, xmm1, xmm0].to_vec();
+            let mut in_colors_sse = [xmm7, xmm6, xmm5, xmm4, xmm3, xmm2, xmm1, xmm0].to_vec();
 
             for node in self.mir.indices() {
                 let want_color = match self.mir.get_node(node).0 {
@@ -1922,9 +1783,7 @@ pub mod liveness {
                     Inst::ShiftLeft(_)
                     | Inst::ShiftRightSigned(_)
                     | Inst::ShiftRightUnsigned(_) => Some(rcx),
-                    Inst::Mul(_) | Inst::Div(_) | Inst::DivSigned(_) => {
-                        Some(rax)
-                    }
+                    Inst::Mul(_) | Inst::Div(_) | Inst::DivSigned(_) => Some(rax),
                     Inst::Rem(_) | Inst::RemSigned(_) => Some(rdx),
                     Inst::ReturnValue(ty) => {
                         if ty.is_floating() {
@@ -1983,15 +1842,10 @@ pub mod liveness {
         pub fn get_register(&self, node: NodeRef) -> Option<Register> {
             self.register_map.get(&node).cloned()
         }
-        pub fn dirty_registers(
-            &self,
-        ) -> std::collections::btree_map::Values<NodeRef, Register> {
+        pub fn dirty_registers(&self) -> std::collections::btree_map::Values<NodeRef, Register> {
             self.register_map.values()
         }
-        pub fn get_scratch_register_at_node(
-            &self,
-            node: NodeRef,
-        ) -> Option<Register> {
+        pub fn get_scratch_register_at_node(&self, node: NodeRef) -> Option<Register> {
             let dirty = self
                 .branches
                 .dirty_registers_at_node(&self.register_map, node);
@@ -2002,11 +1856,7 @@ pub mod liveness {
                 .next()
         }
 
-        pub fn is_register_in_use_at_node(
-            &self,
-            node: NodeRef,
-            reg: Register,
-        ) -> bool {
+        pub fn is_register_in_use_at_node(&self, node: NodeRef, reg: Register) -> bool {
             self.branches
                 .dirty_registers_at_node(&self.register_map, node)
                 .contains(&reg)
@@ -2078,11 +1928,7 @@ pub mod liveness {
                     .map(|graph| {
                         graph
                             .neighbors(node)
-                            .filter_map(|n| {
-                                self.colors
-                                    .get(&NodeRef(n.index() as u32))
-                                    .cloned()
-                            })
+                            .filter_map(|n| self.colors.get(&NodeRef(n.index() as u32)).cloned())
                             .find(|color| color.color() == preferred_color)
                     })
                     .flatten();
@@ -2116,9 +1962,7 @@ pub mod liveness {
                 .map(|graph| {
                     graph
                         .neighbors(node)
-                        .filter_map(|n| {
-                            self.colors.get(&NodeRef(n.index() as u32)).cloned()
-                        })
+                        .filter_map(|n| self.colors.get(&NodeRef(n.index() as u32)).cloned())
                         .collect::<BTreeSet<_>>()
                 })
                 .unwrap_or_default();
@@ -2140,9 +1984,7 @@ pub mod liveness {
                     // here we want to first check clique_colors with tentative coloring.
                     let color = colors
                         .into_iter()
-                        .find_or_first(|&c| {
-                            !clique_colors.contains(&Color::Tentative(c))
-                        })
+                        .find_or_first(|&c| !clique_colors.contains(&Color::Tentative(c)))
                         .expect("ran out of registers :(");
                     v.insert(Color::Final(color));
                     color
@@ -2497,20 +2339,14 @@ impl Function {
         }
     }
 
-    pub fn finish_as_function(
-        self,
-        ip: &intern::InternPool,
-    ) -> Result<String, core::fmt::Error> {
+    pub fn finish_as_function(self, ip: &intern::InternPool) -> Result<String, core::fmt::Error> {
         let mut buf = String::new();
         self.finish(&mut buf, ip)?;
 
         Ok(buf)
     }
 
-    pub fn finish_constants(
-        self,
-        ip: &intern::InternPool,
-    ) -> Result<String, core::fmt::Error> {
+    pub fn finish_constants(self, ip: &intern::InternPool) -> Result<String, core::fmt::Error> {
         use core::fmt::Write;
         let mut buf = String::new();
         let w = &mut buf;
@@ -2674,9 +2510,7 @@ impl Mir {
                 let label = func.get_constant_label(node as usize);
                 ImmRegMem::Rip(RipRelative::Label(Type::QWord, label))
             }
-            Inst::GetElementPtr(ty) => {
-                liveness.get_register(node.into()).unwrap().into()
-            }
+            Inst::GetElementPtr(ty) => liveness.get_register(node.into()).unwrap().into(),
             Inst::Parameter(ty)
             | Inst::Call(ty)
             | Inst::Phi2(ty)
@@ -2723,12 +2557,10 @@ impl Mir {
             Inst::ExternRef(ty) => {
                 // let ty = ty.unwrap_or(Type::QWord);
                 match ty {
-                    None | Some(Type::Function) => {
-                        ImmRegMem::Rip(RipRelative::Reference(format!(
-                            "{}",
-                            strings.get_str(data.as_index())
-                        )))
-                    }
+                    None | Some(Type::Function) => ImmRegMem::Rip(RipRelative::Reference(format!(
+                        "{}",
+                        strings.get_str(data.as_index())
+                    ))),
                     Some(ty) => ImmRegMem::Rip(RipRelative::Label(
                         ty,
                         format!("{}", strings.get_str(data.as_index())),
@@ -2741,10 +2573,7 @@ impl Mir {
         }
     }
 
-    pub fn assemble(
-        &self,
-        strings: &intern::InternPool,
-    ) -> Result<Function, core::fmt::Error> {
+    pub fn assemble(&self, strings: &intern::InternPool) -> Result<Function, core::fmt::Error> {
         use core::fmt::Write;
         // mapping if (i, (stack_offset, bytes)) for local stack variables
         let mut mapping = BTreeMap::<usize, (u32, u32)>::new();
@@ -2770,9 +2599,7 @@ impl Mir {
                 | Inst::ConstantWord
                 | Inst::ConstantDWord
                 | Inst::ConstantQWord => {
-                    func.add_constant_from_inst_and_data(
-                        i, inst, data, strings,
-                    );
+                    func.add_constant_from_inst_and_data(i, inst, data, strings);
                 }
                 Inst::ConstantSinglePrecision => {
                     let bits = data.as_imm32();
@@ -2784,12 +2611,8 @@ impl Mir {
                 }
                 Inst::LoadRegister(ty) => {
                     let src = data.as_node();
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
-                    let src = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, src,
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
+                    let src = self.node_as_operand(&liveness, &mapping, &mut func, strings, src);
                     if ty.is_floating() {
                         match src {
                             ImmRegMem::Byte(_)
@@ -2805,10 +2628,7 @@ impl Mir {
                                     });
 
                                 if spill_rax {
-                                    writeln!(
-                                        func.current_branch(),
-                                        "push rax"
-                                    )?;
+                                    writeln!(func.current_branch(), "push rax")?;
                                 }
 
                                 writeln!(
@@ -2827,16 +2647,10 @@ impl Mir {
                                 }
                             }
                             ImmRegMem::Mem(_) | ImmRegMem::Rip(_) => {
-                                writeln!(
-                                    func.current_branch(),
-                                    "movss {dst}, {src}",
-                                )?;
+                                writeln!(func.current_branch(), "movss {dst}, {src}",)?;
                             }
                             ImmRegMem::Reg(_) => {
-                                writeln!(
-                                    func.current_branch(),
-                                    "movd {dst}, {src}",
-                                )?;
+                                writeln!(func.current_branch(), "movd {dst}, {src}",)?;
                             }
                         }
                     } else {
@@ -2850,21 +2664,12 @@ impl Mir {
                     mapping.insert(i, (offset, size));
                 }
                 Inst::Load(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let src = data.as_node();
-                    let src = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, src,
-                    );
+                    let src = self.node_as_operand(&liveness, &mapping, &mut func, strings, src);
                     match src {
                         ImmRegMem::Reg(_) => {
-                            writeln!(
-                                func.current_branch(),
-                                "mov {}, {ty} ptr [{}]",
-                                dst,
-                                src,
-                            )?;
+                            writeln!(func.current_branch(), "mov {}, {ty} ptr [{}]", dst, src,)?;
                         }
                         ImmRegMem::Mem(ref mem) => {
                             let mut spill_rax = false;
@@ -2878,18 +2683,8 @@ impl Mir {
                             if spill_rax {
                                 writeln!(func.current_branch(), "push rax")?;
                             }
-                            writeln!(
-                                func.current_branch(),
-                                "mov {}, {}",
-                                scratch,
-                                src
-                            )?;
-                            writeln!(
-                                func.current_branch(),
-                                "mov {}, [{}]",
-                                dst,
-                                scratch
-                            )?;
+                            writeln!(func.current_branch(), "mov {}, {}", scratch, src)?;
+                            writeln!(func.current_branch(), "mov {}, [{}]", dst, scratch)?;
                             if spill_rax {
                                 writeln!(func.current_branch(), "pop rax")?;
                             }
@@ -2901,12 +2696,8 @@ impl Mir {
                 }
                 Inst::Store(ty) => {
                     let (src, dst) = data.as_binary();
-                    let src = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, src,
-                    );
-                    let dst = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, dst,
-                    );
+                    let src = self.node_as_operand(&liveness, &mapping, &mut func, strings, src);
+                    let dst = self.node_as_operand(&liveness, &mapping, &mut func, strings, dst);
                     if src.is_floating() {
                         writeln!(func.current_branch(), "movss {dst}, {src}")?;
                     } else {
@@ -2916,9 +2707,7 @@ impl Mir {
                 Inst::GetElementPtr(ty) => {
                     let dst = liveness.get_register(node.into()).unwrap();
                     let (src, idx) = data.as_binary();
-                    let src = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, src,
-                    );
+                    let src = self.node_as_operand(&liveness, &mapping, &mut func, strings, src);
 
                     if let ImmRegMem::Mem(_) = &src {
                         writeln!(func.current_branch(), "lea {dst}, {src}",)?;
@@ -2926,10 +2715,7 @@ impl Mir {
 
                     let offset = idx * ty.bytes();
                     if offset != 0 {
-                        writeln!(
-                            func.current_branch(),
-                            "lea {dst}, [{dst} + {offset}]",
-                        )?;
+                        writeln!(func.current_branch(), "lea {dst}, [{dst} + {offset}]",)?;
                     }
                 }
                 Inst::Parameter(ty) => {
@@ -2952,19 +2738,10 @@ impl Mir {
 
                     let mut spilled_registers = vec![];
 
-                    let mut gprs = Register::SYSV_ARG_GPR
-                        .into_iter()
-                        .rev()
-                        .collect::<Vec<_>>();
-                    let mut sses = Register::SYSV_ARG_SSE
-                        .into_iter()
-                        .rev()
-                        .collect::<Vec<_>>();
+                    let mut gprs = Register::SYSV_ARG_GPR.into_iter().rev().collect::<Vec<_>>();
+                    let mut sses = Register::SYSV_ARG_SSE.into_iter().rev().collect::<Vec<_>>();
 
-                    if liveness.is_register_in_use_at_node(
-                        NodeRef(node),
-                        Register::rax,
-                    ) {
+                    if liveness.is_register_in_use_at_node(NodeRef(node), Register::rax) {
                         writeln!(func.current_branch(), "push rax")?;
                         spilled_registers.push(Register::rax);
                     }
@@ -2972,56 +2749,38 @@ impl Mir {
                     for arg in (start + 1)..end {
                         variant!(self.nodes[arg as usize] => Inst::Argument(ty));
                         let arg = self.data[arg as usize].as_node();
-                        let src = self.node_as_operand(
-                            &liveness, &mapping, &mut func, strings, arg,
-                        );
+                        let src =
+                            self.node_as_operand(&liveness, &mapping, &mut func, strings, arg);
 
                         if ty.is_floating() {
                             let reg = sses.pop().unwrap();
-                            if liveness
-                                .is_register_in_use_at_node(NodeRef(node), reg)
-                            {
+                            if liveness.is_register_in_use_at_node(NodeRef(node), reg) {
                                 writeln!(func.current_branch(), "push {reg}")?;
                                 spilled_registers.push(reg);
                             }
 
-                            writeln!(
-                                func.current_branch(),
-                                "movss {reg}, {src}"
-                            )?;
+                            writeln!(func.current_branch(), "movss {reg}, {src}")?;
                         } else {
                             let reg = gprs.pop().unwrap();
-                            if liveness
-                                .is_register_in_use_at_node(NodeRef(node), reg)
-                            {
+                            if liveness.is_register_in_use_at_node(NodeRef(node), reg) {
                                 writeln!(func.current_branch(), "push {reg}")?;
                                 spilled_registers.push(reg);
                             }
 
                             let reg = ty.register_width(reg);
-                            writeln!(
-                                func.current_branch(),
-                                "mov {reg}, {src}"
-                            )?;
+                            writeln!(func.current_branch(), "mov {reg}, {src}")?;
                         }
                     }
                     let f = self.data[start as usize].as_node();
 
-                    let f = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, f,
-                    );
+                    let f = self.node_as_operand(&liveness, &mapping, &mut func, strings, f);
                     writeln!(func.current_branch(), "test rax, rax")?;
                     writeln!(func.current_branch(), "call {f}")?;
 
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     if ty.is_floating() {
                         if dst.parent_reg() != Register::xmm0 {
-                            writeln!(
-                                func.current_branch(),
-                                "movss {dst}, xmm0"
-                            )?;
+                            writeln!(func.current_branch(), "movss {dst}, xmm0")?;
                         }
                     } else {
                         if dst.parent_reg() != Register::rax {
@@ -3041,83 +2800,51 @@ impl Mir {
                     }
                 }
                 Inst::Add(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let (lhs, rhs) = data.as_binary();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
-                    let rhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, rhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
+                    let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs);
 
                     if ty.is_floating() {
                         writeln!(func.current_branch(), "addss {lhs}, {rhs}")?;
                         if !lhs.occupy_same_register(dst) {
-                            writeln!(
-                                func.current_branch(),
-                                "movss {dst}, {lhs}"
-                            )?;
+                            writeln!(func.current_branch(), "movss {dst}, {lhs}")?;
                         }
                     } else {
                         writeln!(func.current_branch(), "add {lhs}, {rhs}")?;
                         if !lhs.occupy_same_register(dst) {
-                            writeln!(
-                                func.current_branch(),
-                                "mov {dst}, {lhs}"
-                            )?;
+                            writeln!(func.current_branch(), "mov {dst}, {lhs}")?;
                         }
                     }
                 }
                 Inst::Sub(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let (lhs, rhs) = data.as_binary();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
-                    let rhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, rhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
+                    let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs);
                     if ty.is_floating() {
                         writeln!(func.current_branch(), "subss {lhs}, {rhs}")?;
                         if !lhs.occupy_same_register(dst) {
-                            writeln!(
-                                func.current_branch(),
-                                "movss {dst}, {lhs}"
-                            )?;
+                            writeln!(func.current_branch(), "movss {dst}, {lhs}")?;
                         }
                     } else {
                         writeln!(func.current_branch(), "sub {lhs}, {rhs}")?;
                         if !lhs.occupy_same_register(dst) {
-                            writeln!(
-                                func.current_branch(),
-                                "mov {dst}, {lhs}"
-                            )?;
+                            writeln!(func.current_branch(), "mov {dst}, {lhs}")?;
                         }
                     }
                 }
                 Inst::Mul(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let (lhs, rhs) = data.as_binary();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
-                    let rhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, rhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
+                    let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs);
 
-                    let spill_rax = liveness
-                        .is_register_in_use_at_node(node.into(), Register::rax)
+                    let spill_rax = liveness.is_register_in_use_at_node(node.into(), Register::rax)
                         && !(lhs.occupy_same_register(Register::rax)
                             || rhs.occupy_same_register(Register::rax)
                             || dst.parent_reg() == Register::rax);
-                    let spill_rdx = liveness
-                        .is_register_in_use_at_node(node.into(), Register::rdx)
+                    let spill_rdx = liveness.is_register_in_use_at_node(node.into(), Register::rdx)
                         && !(lhs.occupy_same_register(Register::rdx)
                             || rhs.occupy_same_register(Register::rdx)
                             || dst.parent_reg() == Register::rdx);
@@ -3155,24 +2882,16 @@ impl Mir {
                     }
                 }
                 Inst::MulSigned(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let (lhs, rhs) = data.as_binary();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
-                    let rhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, rhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
+                    let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs);
 
-                    let spill_rax = liveness
-                        .is_register_in_use_at_node(node.into(), Register::rax)
+                    let spill_rax = liveness.is_register_in_use_at_node(node.into(), Register::rax)
                         && !(lhs.occupy_same_register(Register::rax)
                             || rhs.occupy_same_register(Register::rax)
                             || dst.parent_reg() == Register::rax);
-                    let spill_rdx = liveness
-                        .is_register_in_use_at_node(node.into(), Register::rdx)
+                    let spill_rdx = liveness.is_register_in_use_at_node(node.into(), Register::rdx)
                         && !(lhs.occupy_same_register(Register::rdx)
                             || rhs.occupy_same_register(Register::rdx)
                             || dst.parent_reg() == Register::rdx);
@@ -3198,24 +2917,16 @@ impl Mir {
                     }
                 }
                 Inst::Div(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let (lhs, rhs) = data.as_binary();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
-                    let rhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, rhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
+                    let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs);
 
-                    let spill_rax = liveness
-                        .is_register_in_use_at_node(node.into(), Register::rax)
+                    let spill_rax = liveness.is_register_in_use_at_node(node.into(), Register::rax)
                         && !(lhs.occupy_same_register(Register::rax)
                             || rhs.occupy_same_register(Register::rax)
                             || dst.parent_reg() == Register::rax);
-                    let spill_rdx = liveness
-                        .is_register_in_use_at_node(node.into(), Register::rdx)
+                    let spill_rdx = liveness.is_register_in_use_at_node(node.into(), Register::rdx)
                         && !(lhs.occupy_same_register(Register::rdx)
                             || rhs.occupy_same_register(Register::rdx)
                             || dst.parent_reg() == Register::rdx);
@@ -3253,24 +2964,16 @@ impl Mir {
                     }
                 }
                 Inst::DivSigned(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let (lhs, rhs) = data.as_binary();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
-                    let rhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, rhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
+                    let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs);
 
-                    let spill_rax = liveness
-                        .is_register_in_use_at_node(node.into(), Register::rax)
+                    let spill_rax = liveness.is_register_in_use_at_node(node.into(), Register::rax)
                         && !(lhs.occupy_same_register(Register::rax)
                             || rhs.occupy_same_register(Register::rax)
                             || dst.parent_reg() == Register::rax);
-                    let spill_rdx = liveness
-                        .is_register_in_use_at_node(node.into(), Register::rdx)
+                    let spill_rdx = liveness.is_register_in_use_at_node(node.into(), Register::rdx)
                         && !(lhs.occupy_same_register(Register::rdx)
                             || rhs.occupy_same_register(Register::rdx)
                             || dst.parent_reg() == Register::rdx);
@@ -3308,24 +3011,16 @@ impl Mir {
                     }
                 }
                 Inst::Rem(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let (lhs, rhs) = data.as_binary();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
-                    let rhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, rhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
+                    let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs);
 
-                    let spill_rax = liveness
-                        .is_register_in_use_at_node(node.into(), Register::rax)
+                    let spill_rax = liveness.is_register_in_use_at_node(node.into(), Register::rax)
                         && !(lhs.occupy_same_register(Register::rax)
                             || rhs.occupy_same_register(Register::rax)
                             || dst.parent_reg() == Register::rax);
-                    let spill_rdx = liveness
-                        .is_register_in_use_at_node(node.into(), Register::rdx)
+                    let spill_rdx = liveness.is_register_in_use_at_node(node.into(), Register::rdx)
                         && !(lhs.occupy_same_register(Register::rdx)
                             || rhs.occupy_same_register(Register::rdx)
                             || dst.parent_reg() == Register::rdx);
@@ -3363,24 +3058,16 @@ impl Mir {
                     }
                 }
                 Inst::RemSigned(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let (lhs, rhs) = data.as_binary();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
-                    let rhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, rhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
+                    let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs);
 
-                    let spill_rax = liveness
-                        .is_register_in_use_at_node(node.into(), Register::rax)
+                    let spill_rax = liveness.is_register_in_use_at_node(node.into(), Register::rax)
                         && !(lhs.occupy_same_register(Register::rax)
                             || rhs.occupy_same_register(Register::rax)
                             || dst.parent_reg() == Register::rax);
-                    let spill_rdx = liveness
-                        .is_register_in_use_at_node(node.into(), Register::rdx)
+                    let spill_rdx = liveness.is_register_in_use_at_node(node.into(), Register::rdx)
                         && !(lhs.occupy_same_register(Register::rdx)
                             || rhs.occupy_same_register(Register::rdx)
                             || dst.parent_reg() == Register::rdx);
@@ -3418,16 +3105,10 @@ impl Mir {
                     }
                 }
                 Inst::MulSSE(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let (lhs, rhs) = data.as_binary();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
-                    let rhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, rhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
+                    let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs);
 
                     writeln!(func.current_branch(), "mulss {lhs}, {rhs}")?;
                     if !lhs.occupy_same_register(dst) {
@@ -3435,16 +3116,10 @@ impl Mir {
                     }
                 }
                 Inst::DivSSE(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let (lhs, rhs) = data.as_binary();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
-                    let rhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, rhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
+                    let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs);
 
                     writeln!(func.current_branch(), "divss {lhs}, {rhs}")?;
                     if !lhs.occupy_same_register(dst) {
@@ -3452,108 +3127,61 @@ impl Mir {
                     }
                 }
                 Inst::RemFP(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let (lhs, rhs) = data.as_binary();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
-                    let rhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, rhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
+                    let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs);
 
                     let ty = ty.int_repr();
                     let size = ty.bytes();
-                    writeln!(
-                        func.current_branch(),
-                        "sub rsp, 0x{:x}",
-                        size * 2
-                    )?;
-                    writeln!(
-                        func.current_branch(),
-                        "movss {ty} ptr [rsp], {lhs}"
-                    )?;
+                    writeln!(func.current_branch(), "sub rsp, 0x{:x}", size * 2)?;
+                    writeln!(func.current_branch(), "movss {ty} ptr [rsp], {lhs}")?;
                     writeln!(
                         func.current_branch(),
                         "movss {ty} ptr [rsp + {size}], {rhs}"
                     )?;
-                    writeln!(
-                        func.current_branch(),
-                        "fld {ty} ptr [rsp + {size}]"
-                    )?;
+                    writeln!(func.current_branch(), "fld {ty} ptr [rsp + {size}]")?;
                     writeln!(func.current_branch(), "fld {ty} ptr [rsp]")?;
                     writeln!(func.current_branch(), "fprem")?;
                     writeln!(func.current_branch(), "fst {ty} ptr [rsp]")?;
-                    writeln!(
-                        func.current_branch(),
-                        "movss {dst}, {ty} ptr [rsp]"
-                    )?;
-                    writeln!(
-                        func.current_branch(),
-                        "add rsp, 0x{:x}",
-                        size * 2
-                    )?;
+                    writeln!(func.current_branch(), "movss {dst}, {ty} ptr [rsp]")?;
+                    writeln!(func.current_branch(), "add rsp, 0x{:x}", size * 2)?;
                 }
                 Inst::BitAnd(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let (lhs, rhs) = data.as_binary();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
-                    let rhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, rhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
+                    let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs);
                     writeln!(func.current_branch(), "and {lhs}, {rhs}")?;
                     if !lhs.occupy_same_register(dst) {
                         writeln!(func.current_branch(), "mov {dst}, {lhs}")?;
                     }
                 }
                 Inst::BitOr(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let (lhs, rhs) = data.as_binary();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
-                    let rhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, rhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
+                    let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs);
                     writeln!(func.current_branch(), "or {lhs}, {rhs}")?;
                     if !lhs.occupy_same_register(dst) {
                         writeln!(func.current_branch(), "mov {dst}, {lhs}")?;
                     }
                 }
                 Inst::BitXOr(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let (lhs, rhs) = data.as_binary();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
-                    let rhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, rhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
+                    let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs);
                     writeln!(func.current_branch(), "xor {lhs}, {rhs}")?;
                     if !lhs.occupy_same_register(dst) {
                         writeln!(func.current_branch(), "mov {dst}, {lhs}")?;
                     }
                 }
                 Inst::ShiftLeft(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let (lhs, rhs) = data.as_binary();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
-                    let rhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, rhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
+                    let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs);
 
                     let lhs_is_rcx = lhs.occupy_same_register(Register::rcx);
                     let rhs_is_rcx = rhs.occupy_same_register(Register::rcx);
@@ -3561,43 +3189,25 @@ impl Mir {
 
                     match rhs {
                         ImmRegMem::Byte(v) => {
-                            writeln!(
-                                func.current_branch(),
-                                "shl {lhs}, {}",
-                                v as u8
-                            )?;
+                            writeln!(func.current_branch(), "shl {lhs}, {}", v as u8)?;
                         }
                         ImmRegMem::DWord(v) => {
-                            writeln!(
-                                func.current_branch(),
-                                "shl {lhs}, {}",
-                                v as u8
-                            )?;
+                            writeln!(func.current_branch(), "shl {lhs}, {}", v as u8)?;
                         }
                         ImmRegMem::QWord(v) => {
-                            writeln!(
-                                func.current_branch(),
-                                "shl {lhs}, {}",
-                                v as u8
-                            )?;
+                            writeln!(func.current_branch(), "shl {lhs}, {}", v as u8)?;
                         }
                         ImmRegMem::Word(v) => {
-                            writeln!(
-                                func.current_branch(),
-                                "shl {lhs}, {}",
-                                v as u8
-                            )?;
+                            writeln!(func.current_branch(), "shl {lhs}, {}", v as u8)?;
                         }
                         ImmRegMem::Reg(reg) => {
                             // reg needs to be moved to CL
                             // if lhs is in rcx, lhs needs to move to rax and we spill rax temporarily
                             // if neither lhs nor rhx nor dst are rcx, spill rcx temporarily
 
-                            let spill_rcx =
-                                liveness.is_register_in_use_at_node(
-                                    node.into(),
-                                    Register::rcx,
-                                ) && !(lhs_is_rcx || rhs_is_rcx || dst_is_rcx);
+                            let spill_rcx = liveness
+                                .is_register_in_use_at_node(node.into(), Register::rcx)
+                                && !(lhs_is_rcx || rhs_is_rcx || dst_is_rcx);
 
                             if spill_rcx {
                                 writeln!(func.current_branch(), "push rcx")?;
@@ -3613,20 +3223,11 @@ impl Mir {
                             }
 
                             if lhs_is_rcx {
-                                if liveness.is_register_in_use_at_node(
-                                    node.into(),
-                                    Register::rax,
-                                ) {
-                                    writeln!(
-                                        func.current_branch(),
-                                        "push rax"
-                                    )?;
+                                if liveness.is_register_in_use_at_node(node.into(), Register::rax) {
+                                    writeln!(func.current_branch(), "push rax")?;
                                 }
 
-                                writeln!(
-                                    func.current_branch(),
-                                    "test rax,rax"
-                                )?;
+                                writeln!(func.current_branch(), "test rax,rax")?;
                                 writeln!(
                                     func.current_branch(),
                                     "mov {}, {lhs}",
@@ -3634,27 +3235,15 @@ impl Mir {
                                         .register_width(Register::rax)
                                 )?;
                                 writeln!(func.current_branch(), "shl rax, cl")?;
-                                writeln!(
-                                    func.current_branch(),
-                                    "mov {dst}, rax"
-                                )?;
+                                writeln!(func.current_branch(), "mov {dst}, rax")?;
 
-                                if liveness.is_register_in_use_at_node(
-                                    node.into(),
-                                    Register::rax,
-                                ) {
+                                if liveness.is_register_in_use_at_node(node.into(), Register::rax) {
                                     writeln!(func.current_branch(), "pop rax")?;
                                 }
                             } else {
-                                writeln!(
-                                    func.current_branch(),
-                                    "shl {lhs}, cl"
-                                )?;
+                                writeln!(func.current_branch(), "shl {lhs}, cl")?;
                                 if lhs.occupy_same_register(dst) {
-                                    writeln!(
-                                        func.current_branch(),
-                                        "mov {dst}, {lhs}"
-                                    )?;
+                                    writeln!(func.current_branch(), "mov {dst}, {lhs}")?;
                                 }
                             }
 
@@ -3669,16 +3258,10 @@ impl Mir {
                     }
                 }
                 Inst::ShiftRightSigned(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let (lhs, rhs) = data.as_binary();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
-                    let rhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, rhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
+                    let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs);
 
                     let lhs_is_rcx = lhs.occupy_same_register(Register::rcx);
                     let rhs_is_rcx = rhs.occupy_same_register(Register::rcx);
@@ -3686,43 +3269,25 @@ impl Mir {
 
                     match rhs {
                         ImmRegMem::Byte(v) => {
-                            writeln!(
-                                func.current_branch(),
-                                "sar {lhs}, {}",
-                                v as u8
-                            )?;
+                            writeln!(func.current_branch(), "sar {lhs}, {}", v as u8)?;
                         }
                         ImmRegMem::DWord(v) => {
-                            writeln!(
-                                func.current_branch(),
-                                "sar {lhs}, {}",
-                                v as u8
-                            )?;
+                            writeln!(func.current_branch(), "sar {lhs}, {}", v as u8)?;
                         }
                         ImmRegMem::QWord(v) => {
-                            writeln!(
-                                func.current_branch(),
-                                "sar {lhs}, {}",
-                                v as u8
-                            )?;
+                            writeln!(func.current_branch(), "sar {lhs}, {}", v as u8)?;
                         }
                         ImmRegMem::Word(v) => {
-                            writeln!(
-                                func.current_branch(),
-                                "sar {lhs}, {}",
-                                v as u8
-                            )?;
+                            writeln!(func.current_branch(), "sar {lhs}, {}", v as u8)?;
                         }
                         ImmRegMem::Reg(reg) => {
                             // reg needs to be moved to CL
                             // if lhs is in rcx, lhs needs to move to rax and we spill rax temporarily
                             // if neither lhs nor rhx nor dst are rcx, spill rcx temporarily
 
-                            let spill_rcx =
-                                liveness.is_register_in_use_at_node(
-                                    node.into(),
-                                    Register::rcx,
-                                ) && !(lhs_is_rcx || rhs_is_rcx || dst_is_rcx);
+                            let spill_rcx = liveness
+                                .is_register_in_use_at_node(node.into(), Register::rcx)
+                                && !(lhs_is_rcx || rhs_is_rcx || dst_is_rcx);
 
                             if spill_rcx {
                                 writeln!(func.current_branch(), "push rcx")?;
@@ -3738,19 +3303,10 @@ impl Mir {
                             }
 
                             if lhs_is_rcx {
-                                if liveness.is_register_in_use_at_node(
-                                    node.into(),
-                                    Register::rax,
-                                ) {
-                                    writeln!(
-                                        func.current_branch(),
-                                        "push rax"
-                                    )?;
+                                if liveness.is_register_in_use_at_node(node.into(), Register::rax) {
+                                    writeln!(func.current_branch(), "push rax")?;
                                 }
-                                writeln!(
-                                    func.current_branch(),
-                                    "test rax,rax"
-                                )?;
+                                writeln!(func.current_branch(), "test rax,rax")?;
                                 writeln!(
                                     func.current_branch(),
                                     "mov {}, {lhs}",
@@ -3758,27 +3314,15 @@ impl Mir {
                                         .register_width(Register::rax)
                                 )?;
                                 writeln!(func.current_branch(), "sar rax, cl")?;
-                                writeln!(
-                                    func.current_branch(),
-                                    "mov {dst}, rax"
-                                )?;
+                                writeln!(func.current_branch(), "mov {dst}, rax")?;
 
-                                if liveness.is_register_in_use_at_node(
-                                    node.into(),
-                                    Register::rax,
-                                ) {
+                                if liveness.is_register_in_use_at_node(node.into(), Register::rax) {
                                     writeln!(func.current_branch(), "pop rax")?;
                                 }
                             } else {
-                                writeln!(
-                                    func.current_branch(),
-                                    "sar {lhs}, cl"
-                                )?;
+                                writeln!(func.current_branch(), "sar {lhs}, cl")?;
                                 if lhs.occupy_same_register(dst) {
-                                    writeln!(
-                                        func.current_branch(),
-                                        "mov {dst}, {lhs}"
-                                    )?;
+                                    writeln!(func.current_branch(), "mov {dst}, {lhs}")?;
                                 }
                             }
 
@@ -3793,16 +3337,10 @@ impl Mir {
                     }
                 }
                 Inst::ShiftRightUnsigned(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let (lhs, rhs) = data.as_binary();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
-                    let rhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, rhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
+                    let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs);
 
                     let lhs_is_rcx = lhs.occupy_same_register(Register::rcx);
                     let rhs_is_rcx = rhs.occupy_same_register(Register::rcx);
@@ -3810,43 +3348,25 @@ impl Mir {
 
                     match rhs {
                         ImmRegMem::Byte(v) => {
-                            writeln!(
-                                func.current_branch(),
-                                "shr {lhs}, {}",
-                                v as u8
-                            )?;
+                            writeln!(func.current_branch(), "shr {lhs}, {}", v as u8)?;
                         }
                         ImmRegMem::DWord(v) => {
-                            writeln!(
-                                func.current_branch(),
-                                "shr {lhs}, {}",
-                                v as u8
-                            )?;
+                            writeln!(func.current_branch(), "shr {lhs}, {}", v as u8)?;
                         }
                         ImmRegMem::QWord(v) => {
-                            writeln!(
-                                func.current_branch(),
-                                "shr {lhs}, {}",
-                                v as u8
-                            )?;
+                            writeln!(func.current_branch(), "shr {lhs}, {}", v as u8)?;
                         }
                         ImmRegMem::Word(v) => {
-                            writeln!(
-                                func.current_branch(),
-                                "shr {lhs}, {}",
-                                v as u8
-                            )?;
+                            writeln!(func.current_branch(), "shr {lhs}, {}", v as u8)?;
                         }
                         ImmRegMem::Reg(reg) => {
                             // reg needs to be moved to CL
                             // if lhs is in rcx, lhs needs to move to rax and we spill rax temporarily
                             // if neither lhs nor rhx nor dst are rcx, spill rcx temporarily
 
-                            let spill_rcx =
-                                liveness.is_register_in_use_at_node(
-                                    node.into(),
-                                    Register::rcx,
-                                ) && !(lhs_is_rcx || rhs_is_rcx || dst_is_rcx);
+                            let spill_rcx = liveness
+                                .is_register_in_use_at_node(node.into(), Register::rcx)
+                                && !(lhs_is_rcx || rhs_is_rcx || dst_is_rcx);
 
                             if spill_rcx {
                                 writeln!(func.current_branch(), "push rcx")?;
@@ -3862,20 +3382,11 @@ impl Mir {
                             }
 
                             if lhs_is_rcx {
-                                if liveness.is_register_in_use_at_node(
-                                    node.into(),
-                                    Register::rax,
-                                ) {
-                                    writeln!(
-                                        func.current_branch(),
-                                        "push rax"
-                                    )?;
+                                if liveness.is_register_in_use_at_node(node.into(), Register::rax) {
+                                    writeln!(func.current_branch(), "push rax")?;
                                 }
 
-                                writeln!(
-                                    func.current_branch(),
-                                    "test rax,rax"
-                                )?;
+                                writeln!(func.current_branch(), "test rax,rax")?;
                                 writeln!(
                                     func.current_branch(),
                                     "mov {}, {lhs}",
@@ -3883,27 +3394,15 @@ impl Mir {
                                         .register_width(Register::rax)
                                 )?;
                                 writeln!(func.current_branch(), "shr rax, cl")?;
-                                writeln!(
-                                    func.current_branch(),
-                                    "mov {dst}, rax"
-                                )?;
+                                writeln!(func.current_branch(), "mov {dst}, rax")?;
 
-                                if liveness.is_register_in_use_at_node(
-                                    node.into(),
-                                    Register::rax,
-                                ) {
+                                if liveness.is_register_in_use_at_node(node.into(), Register::rax) {
                                     writeln!(func.current_branch(), "pop rax")?;
                                 }
                             } else {
-                                writeln!(
-                                    func.current_branch(),
-                                    "shr {lhs}, cl"
-                                )?;
+                                writeln!(func.current_branch(), "shr {lhs}, cl")?;
                                 if lhs.occupy_same_register(dst) {
-                                    writeln!(
-                                        func.current_branch(),
-                                        "mov {dst}, {lhs}"
-                                    )?;
+                                    writeln!(func.current_branch(), "mov {dst}, {lhs}")?;
                                 }
                             }
 
@@ -3918,13 +3417,9 @@ impl Mir {
                     }
                 }
                 Inst::Not(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let lhs = data.as_node();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
                     writeln!(func.current_branch(), "not {lhs}")?;
 
                     if !lhs.occupy_same_register(dst) {
@@ -3932,44 +3427,27 @@ impl Mir {
                     }
                 }
                 Inst::Negate(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let lhs = data.as_node();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
 
                     if ty.is_floating() {
-                        writeln!(
-                            func.current_branch(),
-                            "mulss {lhs}, [rip + .NEG1F32]"
-                        )?;
+                        writeln!(func.current_branch(), "mulss {lhs}, [rip + .NEG1F32]")?;
                         if lhs != ImmRegMem::Reg(dst) {
-                            writeln!(
-                                func.current_branch(),
-                                "movss {dst}, {lhs}"
-                            )?;
+                            writeln!(func.current_branch(), "movss {dst}, {lhs}")?;
                         }
                     } else {
                         writeln!(func.current_branch(), "neg {lhs}")?;
                         if lhs != ImmRegMem::Reg(dst) {
-                            writeln!(
-                                func.current_branch(),
-                                "mov {dst}, {lhs}"
-                            )?;
+                            writeln!(func.current_branch(), "mov {dst}, {lhs}")?;
                         }
                     }
                 }
                 Inst::SignExtend(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let lhs = data.as_node();
                     let lhs_ty = self.type_of_node(lhs).unwrap();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
 
                     if ty == lhs_ty {
                         writeln!(func.current_branch(), "test {dst}, {dst}")?;
@@ -3977,11 +3455,7 @@ impl Mir {
                     } else {
                         match lhs {
                             ImmRegMem::Byte(v) => {
-                                writeln!(
-                                    func.current_branch(),
-                                    "mov {}, {v}",
-                                    dst.into_byte()
-                                )?;
+                                writeln!(func.current_branch(), "mov {}, {v}", dst.into_byte())?;
                                 writeln!(
                                     func.current_branch(),
                                     "movsx {dst}, {}",
@@ -3989,11 +3463,7 @@ impl Mir {
                                 )?;
                             }
                             ImmRegMem::Word(v) => {
-                                writeln!(
-                                    func.current_branch(),
-                                    "mov {},{v}",
-                                    dst.into_word()
-                                )?;
+                                writeln!(func.current_branch(), "mov {},{v}", dst.into_word())?;
                                 writeln!(
                                     func.current_branch(),
                                     "movsx {dst}, {}",
@@ -4001,11 +3471,7 @@ impl Mir {
                                 )?;
                             }
                             ImmRegMem::DWord(v) => {
-                                writeln!(
-                                    func.current_branch(),
-                                    "mov {},{v}",
-                                    dst.into_dword()
-                                )?;
+                                writeln!(func.current_branch(), "mov {},{v}", dst.into_dword())?;
                                 writeln!(
                                     func.current_branch(),
                                     "movsxd {dst}, {}",
@@ -4013,30 +3479,17 @@ impl Mir {
                                 )?;
                             }
                             ImmRegMem::QWord(v) => {
-                                writeln!(
-                                    func.current_branch(),
-                                    "mov {},{v}",
-                                    dst.into_qword()
-                                )?;
+                                writeln!(func.current_branch(), "mov {},{v}", dst.into_qword())?;
                             }
                             ImmRegMem::Mem(mem) => match lhs_ty {
                                 Type::Byte | Type::Word => {
-                                    writeln!(
-                                        func.current_branch(),
-                                        "movsx {dst}, {mem}"
-                                    )?;
+                                    writeln!(func.current_branch(), "movsx {dst}, {mem}")?;
                                 }
                                 Type::DWord => {
-                                    writeln!(
-                                        func.current_branch(),
-                                        "movsxd {dst}, {mem}"
-                                    )?;
+                                    writeln!(func.current_branch(), "movsxd {dst}, {mem}")?;
                                 }
                                 Type::QWord => {
-                                    writeln!(
-                                        func.current_branch(),
-                                        "movs {dst}, {mem}"
-                                    )?;
+                                    writeln!(func.current_branch(), "movs {dst}, {mem}")?;
                                 }
                                 _ => {
                                     panic!("cannot sign-extend a floating register")
@@ -4044,22 +3497,13 @@ impl Mir {
                             },
                             ImmRegMem::Reg(reg) => match lhs_ty {
                                 Type::Byte | Type::Word => {
-                                    writeln!(
-                                        func.current_branch(),
-                                        "movsx {dst}, {reg}"
-                                    )?;
+                                    writeln!(func.current_branch(), "movsx {dst}, {reg}")?;
                                 }
                                 Type::DWord => {
-                                    writeln!(
-                                        func.current_branch(),
-                                        "movsxd {dst}, {reg}"
-                                    )?;
+                                    writeln!(func.current_branch(), "movsxd {dst}, {reg}")?;
                                 }
                                 Type::QWord => {
-                                    writeln!(
-                                        func.current_branch(),
-                                        "mov {dst}, {reg}"
-                                    )?;
+                                    writeln!(func.current_branch(), "mov {dst}, {reg}")?;
                                 }
                                 _ => {
                                     panic!("cannot sign-extend a floating register")
@@ -4070,52 +3514,28 @@ impl Mir {
                     }
                 }
                 Inst::ZeroExtend(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let lhs = data.as_node();
                     let lhs_ty = self.type_of_node(lhs).unwrap();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
 
                     if ty == lhs_ty {
                         writeln!(func.current_branch(), "test {dst}, {dst}")?;
                         writeln!(func.current_branch(), "mov {dst}, {lhs}")?;
                     } else {
-                        writeln!(
-                            func.current_branch(),
-                            "test {0}, {0}",
-                            dst.parent_reg()
-                        )?;
+                        writeln!(func.current_branch(), "test {0}, {0}", dst.parent_reg())?;
                         match lhs {
                             ImmRegMem::Byte(v) => {
-                                writeln!(
-                                    func.current_branch(),
-                                    "mov {}, {v}",
-                                    dst.into_byte()
-                                )?;
+                                writeln!(func.current_branch(), "mov {}, {v}", dst.into_byte())?;
                             }
                             ImmRegMem::Word(v) => {
-                                writeln!(
-                                    func.current_branch(),
-                                    "mov {}, {v}",
-                                    dst.into_word()
-                                )?;
+                                writeln!(func.current_branch(), "mov {}, {v}", dst.into_word())?;
                             }
                             ImmRegMem::DWord(v) => {
-                                writeln!(
-                                    func.current_branch(),
-                                    "mov {}, {v}",
-                                    dst.into_dword()
-                                )?;
+                                writeln!(func.current_branch(), "mov {}, {v}", dst.into_dword())?;
                             }
                             ImmRegMem::QWord(v) => {
-                                writeln!(
-                                    func.current_branch(),
-                                    "mov {}, {v}",
-                                    dst.into_qword()
-                                )?;
+                                writeln!(func.current_branch(), "mov {}, {v}", dst.into_qword())?;
                             }
                             ImmRegMem::Mem(mem) => {
                                 writeln!(
@@ -4137,12 +3557,8 @@ impl Mir {
                 }
                 Inst::Cmp(ty) => {
                     let (lhs, rhs) = data.as_binary();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
-                    let rhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, rhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
+                    let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs);
 
                     if ty.is_floating() {
                         writeln!(func.current_branch(), "comiss {lhs}, {rhs}")?;
@@ -4156,8 +3572,7 @@ impl Mir {
                 | Inst::IsLt(signed)
                 | Inst::IsGe(signed)
                 | Inst::IsLe(signed) => {
-                    let dst =
-                        liveness.get_register(node.into()).unwrap().into_byte();
+                    let dst = liveness.get_register(node.into()).unwrap().into_byte();
 
                     #[cfg_attr(rustfmt, rustfmt::skip)]
                     let mnemonic = match inst {
@@ -4173,32 +3588,19 @@ impl Mir {
                     writeln!(func.current_branch(), "{mnemonic} {dst}")?;
                 }
                 Inst::IsZero(ty) => {
-                    let dst = ty.register_width(
-                        liveness.get_register(node.into()).unwrap(),
-                    );
+                    let dst = ty.register_width(liveness.get_register(node.into()).unwrap());
                     let lhs = data.as_node();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
                     writeln!(func.current_branch(), "mov {dst}, {lhs}")?;
                     writeln!(func.current_branch(), "test {dst}, {dst}")?;
-                    writeln!(
-                        func.current_branch(),
-                        "setz {}",
-                        dst.into_byte()
-                    )?;
+                    writeln!(func.current_branch(), "setz {}", dst.into_byte())?;
                 }
                 Inst::ReturnValue(ty) => {
                     let lhs = data.as_node();
-                    let lhs = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, lhs,
-                    );
+                    let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs);
                     if ty.is_floating() {
                         if !lhs.occupy_same_register(Register::xmm0) {
-                            writeln!(
-                                func.current_branch(),
-                                "movss xmm0, {lhs}",
-                            )?;
+                            writeln!(func.current_branch(), "movss xmm0, {lhs}",)?;
                         }
                     } else {
                         if !lhs.occupy_same_register(Register::rax) {
@@ -4221,34 +3623,21 @@ impl Mir {
                     }
                 }
                 Inst::Branch(condition) => {
-                    let cond = self.node_as_operand(
-                        &liveness, &mapping, &mut func, strings, condition,
-                    );
+                    let cond =
+                        self.node_as_operand(&liveness, &mapping, &mut func, strings, condition);
                     let (lhs, rhs) = data.as_binary();
                     writeln!(func.current_branch(), "test {cond}, {cond}")?;
 
                     match (lhs, rhs) {
                         _ if lhs == node + 1 => {
-                            writeln!(
-                                func.current_branch(),
-                                "jz .{name}__L{rhs}"
-                            )?;
+                            writeln!(func.current_branch(), "jz .{name}__L{rhs}")?;
                         }
                         _ if rhs == node + 1 => {
-                            writeln!(
-                                func.current_branch(),
-                                "jnz .{name}__L{lhs}"
-                            )?;
+                            writeln!(func.current_branch(), "jnz .{name}__L{lhs}")?;
                         }
                         _ => {
-                            writeln!(
-                                func.current_branch(),
-                                "jnz .{name}__L{lhs}"
-                            )?;
-                            writeln!(
-                                func.current_branch(),
-                                "jz .{name}__L{rhs}"
-                            )?;
+                            writeln!(func.current_branch(), "jnz .{name}__L{lhs}")?;
+                            writeln!(func.current_branch(), "jz .{name}__L{rhs}")?;
                         }
                     }
                 }
diff --git a/src/parser.rs b/src/parser.rs
index 51ea59a..f1f502e 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -2,10 +2,7 @@ use itertools::Itertools;
 use num_bigint::{BigInt, BigUint};
 
 use crate::{
-    ast::{
-        self, FloatingType, IntegralType, LetOrVar, Node, PrimitiveType, Tag,
-        Type,
-    },
+    ast::{self, FloatingType, IntegralType, LetOrVar, Node, Tag, Type},
     ast2::intern::{self, AMD64_POINTER_BITS},
     common::NextIf,
     comptime::{self, ComptimeNumber},
@@ -147,17 +144,13 @@ impl Tree {
             .map(|decl| {
                 let name = match self.nodes.get_node(*decl) {
                     Tag::FunctionDecl { proto, .. } => {
-                        let Tag::FunctionProto { name, .. } =
-                            self.nodes.get_node(*proto)
-                        else {
+                        let Tag::FunctionProto { name, .. } = self.nodes.get_node(*proto) else {
                             unreachable!()
                         };
 
                         self.get_ident_str(*name).unwrap().to_owned()
                     }
-                    Tag::GlobalDecl { name, .. } => {
-                        self.get_ident_str(*name).unwrap().to_owned()
-                    }
+                    Tag::GlobalDecl { name, .. } => self.get_ident_str(*name).unwrap().to_owned(),
                     _ => {
                         unreachable!()
                     }
@@ -243,10 +236,7 @@ impl Tree {
         IntegralType { signed, bits }
     }
 
-    fn parse_integral_constant(
-        token: Token,
-        lexeme: &str,
-    ) -> (BigInt, Option<IntegralType>) {
+    fn parse_integral_constant(token: Token, lexeme: &str) -> (BigInt, Option<IntegralType>) {
         let radix = Radix::from_token(token).unwrap();
 
         // TODO: figure out how to do this safely for bigger types, whether to
@@ -269,9 +259,9 @@ impl Tree {
         let value = comptime::bigint::parse_bigint(digits.into_iter(), radix);
 
         let ty = match iter.clone().next() {
-            Some((_, 'u')) | Some((_, 'i')) => Some(Self::parse_integral_type(
-                &lexeme[iter.next().unwrap().0..],
-            )),
+            Some((_, 'u')) | Some((_, 'i')) => {
+                Some(Self::parse_integral_type(&lexeme[iter.next().unwrap().0..]))
+            }
             _ => None,
         };
 
@@ -281,10 +271,7 @@ impl Tree {
         )
     }
 
-    fn parse_floating_constant(
-        _token: Token,
-        lexeme: &str,
-    ) -> (u64, FloatingType) {
+    fn parse_floating_constant(_token: Token, lexeme: &str) -> (u64, FloatingType) {
         // let (dot, exp) = match token {
         //     Token::DotFloatingExpConstant => (true, true),
         //     Token::DotFloatingConstant => (true, false),
@@ -304,12 +291,8 @@ impl Tree {
             );
 
         let bits = match lexeme.1 {
-            FloatingType::Binary32 => {
-                lexeme.0.parse::<f32>().unwrap().to_bits() as u64
-            }
-            FloatingType::Binary64 => {
-                lexeme.0.parse::<f64>().unwrap().to_bits() as u64
-            }
+            FloatingType::Binary32 => lexeme.0.parse::<f32>().unwrap().to_bits() as u64,
+            FloatingType::Binary64 => lexeme.0.parse::<f64>().unwrap().to_bits() as u64,
         };
 
         (bits, lexeme.1)
@@ -328,10 +311,7 @@ impl Tree {
         }
     }
 
-    pub fn parse_primitive_type(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Node> {
+    pub fn parse_primitive_type(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
         let token = tokens.next().ok_or(Error::UnexpectedEndOfTokens)?;
         let prim = match token.token() {
             Token::Void => intern::Index::VOID,
@@ -346,10 +326,7 @@ impl Tree {
         Ok(self.nodes.push_tag(Tag::PrimitiveType(prim)))
     }
 
-    pub fn parse_pointer(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Node> {
+    pub fn parse_pointer(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
         tokens.expect_token(Token::Star)?;
         let _constness = tokens.eat_token(Token::Const);
         let typename = self.parse_typename(tokens)?;
@@ -357,24 +334,19 @@ impl Tree {
         Ok(self.nodes.push_tag(Tag::Pointer { pointee: typename }))
     }
 
-    pub fn parse_typename(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Node> {
+    pub fn parse_typename(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
         match tokens.peek_token_or_err()?.token() {
             Token::Star => self.parse_pointer(tokens),
             Token::Ident => {
                 let token = tokens.next().unwrap();
                 match Self::try_parse_integral_type(token.lexeme())? {
                     Some(int) => {
-                        let ty =
-                            self.intern_pool.get_int_type(int.signed, int.bits);
+                        let ty = self.intern_pool.get_int_type(int.signed, int.bits);
 
                         Ok(self.nodes.push_tag(Tag::IntegralType(ty)))
                     }
                     None => {
-                        let name =
-                            self.intern_pool.insert_string(token.lexeme());
+                        let name = self.intern_pool.insert_string(token.lexeme());
                         Ok(self.nodes.push_tag(Tag::Ident { name }))
                     }
                 }
@@ -383,10 +355,7 @@ impl Tree {
         }
     }
 
-    pub fn parse_var_decl(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Node> {
+    pub fn parse_var_decl(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
         let let_or_var = match tokens
             .eat_token(Token::Let)
             .or_else(|| tokens.eat_token(Token::Var))
@@ -406,8 +375,7 @@ impl Tree {
             None
         };
 
-        let name_str =
-            self.intern_pool.get_str(self.ident_index(name)).to_owned();
+        let name_str = self.intern_pool.get_str(self.ident_index(name)).to_owned();
         let decl = self.nodes.reserve_node();
 
         let assignment = if tokens.eat_token(Token::Equal).is_some() {
@@ -435,10 +403,7 @@ impl Tree {
 
     /// GLOBAL_DECL <-
     ///     const IDENTIFIER (: TYPENAME)? = EXPR;
-    pub fn parse_global_decl(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Node> {
+    pub fn parse_global_decl(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
         _ = tokens.expect_token(Token::Const)?;
 
         let name = self.parse_ident(tokens)?;
@@ -483,10 +448,7 @@ impl Tree {
 
     /// PARAMETER <-
     ///     IDENTIFIER : TYPENAME
-    pub fn parse_parameter(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Node> {
+    pub fn parse_parameter(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
         let name = self.parse_ident(tokens)?;
         tokens.expect_token(Token::Colon)?;
         let ty = self.parse_typename(tokens)?;
@@ -505,10 +467,7 @@ impl Tree {
     /// PARAMETER_LIST <-
     ///     PARAMETER
     ///     PARAMETER_LIST , PARAMETER
-    pub fn parse_parameter_list(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Node> {
+    pub fn parse_parameter_list(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
         let mut parameters = Vec::new();
 
         loop {
@@ -533,10 +492,7 @@ impl Tree {
     ///     fn IDENTIFIER () -> TYPENAME
     ///     fn IDENTIFIER ( PARAMETER_LIST ,? )
     ///     fn IDENTIFIER ( PARAMETER_LIST ,? ) -> TYPENAME
-    pub fn parse_fn_proto(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<(Node, Node)> {
+    pub fn parse_fn_proto(&mut self, tokens: &mut TokenIterator) -> Result<(Node, Node)> {
         tokens.expect_token(Token::Fn)?;
         let name = self.parse_ident(tokens)?;
         tokens.expect_token(Token::OpenParens)?;
@@ -567,10 +523,7 @@ impl Tree {
 
     /// FUNCTION_DECL <-
     ///     FUNCTION_PROTO BLOCK
-    pub fn parse_fn_decl(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Node> {
+    pub fn parse_fn_decl(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
         let (proto, name) = self.parse_fn_proto(tokens)?;
 
         let decl = match self
@@ -580,10 +533,8 @@ impl Tree {
             Some(record) => record.node(),
             None => {
                 let decl = self.nodes.reserve_node();
-                self.st.insert_orderless_symbol(
-                    &self.get_ident_str(name).unwrap().to_owned(),
-                    decl,
-                );
+                self.st
+                    .insert_orderless_symbol(&self.get_ident_str(name).unwrap().to_owned(), decl);
                 decl
             }
         };
@@ -593,9 +544,7 @@ impl Tree {
         let body = self.parse_block(tokens, Some(block))?;
         let unresolved = self
             .st
-            .extract_orderless_if(|_, v| {
-                self.nodes.get_node(v.node()) == &Tag::Undefined
-            })
+            .extract_orderless_if(|_, v| self.nodes.get_node(v.node()) == &Tag::Undefined)
             .collect::<Vec<_>>();
         self.st.into_parent();
         self.st.extend_orderless(unresolved);
@@ -669,10 +618,7 @@ impl Tree {
     /// ASSIGNMENT_EXPR <-
     ///     BINARY_EXPRESSION
     ///     BINARY_EXPRESSION ASSIGNMENT_OP EXPRESSION
-    pub fn parse_assignment_expr(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Node> {
+    pub fn parse_assignment_expr(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
         let lhs = self.parse_binary_expr(tokens, 0)?;
 
         Ok(self.try_parse_assignment(lhs, tokens)?.unwrap_or(lhs))
@@ -700,24 +646,12 @@ impl Tree {
                 Token::MinusEqual => self.nodes.push_tag(Tag::Sub { lhs, rhs }),
                 Token::StarEqual => self.nodes.push_tag(Tag::Mul { lhs, rhs }),
                 Token::SlashEqual => self.nodes.push_tag(Tag::Sub { lhs, rhs }),
-                Token::PercentEqual => {
-                    self.nodes.push_tag(Tag::Rem { lhs, rhs })
-                }
-                Token::PipeEqual => {
-                    self.nodes.push_tag(Tag::BitOr { lhs, rhs })
-                }
-                Token::CaretEqual => {
-                    self.nodes.push_tag(Tag::BitXOr { lhs, rhs })
-                }
-                Token::AmpersandEqual => {
-                    self.nodes.push_tag(Tag::BitAnd { lhs, rhs })
-                }
-                Token::LessLessEqual => {
-                    self.nodes.push_tag(Tag::Shl { lhs, rhs })
-                }
-                Token::GreaterGreaterEqual => {
-                    self.nodes.push_tag(Tag::Shr { lhs, rhs })
-                }
+                Token::PercentEqual => self.nodes.push_tag(Tag::Rem { lhs, rhs }),
+                Token::PipeEqual => self.nodes.push_tag(Tag::BitOr { lhs, rhs }),
+                Token::CaretEqual => self.nodes.push_tag(Tag::BitXOr { lhs, rhs }),
+                Token::AmpersandEqual => self.nodes.push_tag(Tag::BitAnd { lhs, rhs }),
+                Token::LessLessEqual => self.nodes.push_tag(Tag::Shl { lhs, rhs }),
+                Token::GreaterGreaterEqual => self.nodes.push_tag(Tag::Shr { lhs, rhs }),
                 Token::Equal => rhs,
                 _ => {
                     unreachable!()
@@ -731,10 +665,7 @@ impl Tree {
 
     /// RETURN_STATEMENT <-
     ///     return EXPRESSION? ;
-    pub fn try_parse_return_stmt(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Option<Node>> {
+    pub fn try_parse_return_stmt(&mut self, tokens: &mut TokenIterator) -> Result<Option<Node>> {
         if tokens.eat_token(Token::Return).is_some() {
             let expr = if !tokens.is_next_token(Token::Semi) {
                 let expr = Some(self.parse_expr(tokens)?);
@@ -755,10 +686,7 @@ impl Tree {
     ///     RETURN_EXPRESSION
     ///     VAR_DECL ;
     ///     EXPRESSION ;
-    pub fn parse_statement(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Node> {
+    pub fn parse_statement(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
         match tokens.peek_token_or_err()?.token() {
             Token::Return => Ok(self.try_parse_return_stmt(tokens)?.unwrap()),
             Token::Var | Token::Let => {
@@ -854,10 +782,7 @@ impl Tree {
     ///     - POSTFIX_EXPR
     ///     & POSTFIX_EXPR
     ///     * POSTFIX_EXPR
-    pub fn parse_prefix_expr(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Node> {
+    pub fn parse_prefix_expr(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
         match tokens.peek_token_or_err()?.token() {
             Token::Bang => {
                 _ = tokens.next();
@@ -886,10 +811,7 @@ impl Tree {
     /// AS_EXPR <-
     ///     PREFIX_EXPR
     ///     PREFIX_EXPR as TYPENAME
-    pub fn parse_as_expr(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Node> {
+    pub fn parse_as_expr(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
         let expr = self.parse_prefix_expr(tokens)?;
 
         if tokens.eat_token(Token::As).is_some() {
@@ -906,10 +828,7 @@ impl Tree {
     /// ARGUMENT <-
     ///    IDENT : EXPR
     ///    EXPR
-    pub fn parse_argument(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Node> {
+    pub fn parse_argument(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
         if tokens.is_next_token2(Token::Colon) {
             let name = self.parse_ident(tokens)?;
             _ = tokens.expect_token(Token::Colon)?;
@@ -927,10 +846,7 @@ impl Tree {
     /// ARGUMENT_LIST <-
     ///     ARGUMENT
     ///     ARGUMENT_LIST , ARGUMENT
-    pub fn parse_argument_list(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Node> {
+    pub fn parse_argument_list(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
         let mut arguments = Vec::new();
 
         loop {
@@ -954,10 +870,7 @@ impl Tree {
     ///     PRIMARY_EXPR
     ///     PRIMARY_EXPR ( )
     ///     PRIMARY_EXPR ( ARGUMENT_LIST )
-    pub fn parse_postfix_expr(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Node> {
+    pub fn parse_postfix_expr(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
         let lhs = self.parse_primary_expr(tokens)?;
 
         if tokens.eat_token(Token::OpenParens).is_some() {
@@ -983,10 +896,7 @@ impl Tree {
     ///     FLOATING_CONSTANT
     ///     ( EXPRESSION )
     ///     { STATEMENT* EXPRESSION? }
-    pub fn parse_primary_expr(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Node> {
+    pub fn parse_primary_expr(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
         let token = tokens.peek_token_or_err()?;
         match token.token() {
             Token::Ident => {
@@ -995,16 +905,12 @@ impl Tree {
                 let name = ident.lexeme();
                 if let Some(record) = self.st.find_ordered_symbol(name) {
                     Ok(self.nodes.push_tag(Tag::DeclRef(record.node())))
-                } else if let Some(record) = self.st.find_orderless_symbol(name)
-                {
+                } else if let Some(record) = self.st.find_orderless_symbol(name) {
                     Ok(self.nodes.push_tag(Tag::GlobalRef(record.node())))
                 } else {
                     let node = self
                         .st
-                        .insert_orderless_symbol(
-                            name,
-                            self.nodes.reserve_node(),
-                        )
+                        .insert_orderless_symbol(name, self.nodes.reserve_node())
                         .node();
 
                     Ok(self.nodes.push_tag(Tag::GlobalRef(node)))
@@ -1015,10 +921,7 @@ impl Tree {
             | Token::IntegerOctConstant
             | Token::IntegerConstant => {
                 _ = tokens.next();
-                let (bits, ty) = Self::parse_integral_constant(
-                    token.token(),
-                    token.lexeme(),
-                );
+                let (bits, ty) = Self::parse_integral_constant(token.token(), token.lexeme());
                 let (_, bytes) = bits.to_bytes_le();
 
                 const BUF_SIZE: usize = core::mem::size_of::<u64>();
@@ -1027,18 +930,15 @@ impl Tree {
                     .copy_from_slice(&bytes[..bytes.len().min(BUF_SIZE)]);
                 let bytes = match bytes.len() {
                     0..2 => {
-                        let (buf, _) =
-                            buf.split_at(core::mem::size_of::<u32>());
+                        let (buf, _) = buf.split_at(core::mem::size_of::<u32>());
                         self.intern_pool.get_unsigned_integer(
                             u32::from_le_bytes(buf.try_into().unwrap()) as u64,
                         )
                     }
                     0..4 => {
-                        let (buf, _) =
-                            buf.split_at(core::mem::size_of::<u64>());
-                        self.intern_pool.get_unsigned_integer(
-                            u64::from_le_bytes(buf.try_into().unwrap()),
-                        )
+                        let (buf, _) = buf.split_at(core::mem::size_of::<u64>());
+                        self.intern_pool
+                            .get_unsigned_integer(u64::from_le_bytes(buf.try_into().unwrap()))
                     }
                     0.. => self.intern_pool.insert_bytes(&bytes),
                 };
@@ -1055,22 +955,15 @@ impl Tree {
             | Token::DotFloatingConstant
             | Token::DotFloatingExpConstant => {
                 _ = tokens.next();
-                let (bits, ty) = Self::parse_floating_constant(
-                    token.token(),
-                    token.lexeme(),
-                );
+                let (bits, ty) = Self::parse_floating_constant(token.token(), token.lexeme());
 
                 let bytes = match ty {
-                    FloatingType::Binary32 => {
-                        self.intern_pool.get_or_insert(intern::Key::F32 {
-                            bits: f32::from_bits(bits as u32),
-                        })
-                    }
-                    FloatingType::Binary64 => {
-                        self.intern_pool.get_or_insert(intern::Key::F64 {
-                            bits: f64::from_bits(bits),
-                        })
-                    }
+                    FloatingType::Binary32 => self.intern_pool.get_or_insert(intern::Key::F32 {
+                        bits: f32::from_bits(bits as u32),
+                    }),
+                    FloatingType::Binary64 => self.intern_pool.get_or_insert(intern::Key::F64 {
+                        bits: f64::from_bits(bits),
+                    }),
                 };
 
                 Ok(self.nodes.push_tag(Tag::Constant {
@@ -1096,10 +989,7 @@ impl Tree {
     ///     BLOCK
     ///     EXPR
     ///     EXPR ;
-    pub fn parse_expr_or_stmt_or_block(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Node> {
+    pub fn parse_expr_or_stmt_or_block(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
         let peek = tokens.peek_token_or_err()?;
         let body = match peek.token() {
             // block
@@ -1130,10 +1020,7 @@ impl Tree {
 
     /// ELSE_EXPR <-
     ///     'else' (IF_EXPR | EXPR_OR_STATEMENT_OR_BLOCK)
-    pub fn try_parse_else_expr(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Option<Node>> {
+    pub fn try_parse_else_expr(&mut self, tokens: &mut TokenIterator) -> Result<Option<Node>> {
         if tokens.eat_token(Token::Else).is_none() {
             return Ok(None);
         }
@@ -1148,10 +1035,7 @@ impl Tree {
 
     /// IF_EXPR <-
     ///     'if' ( EXPR ) EXPR_OR_STATEMENT_OR_BLOCK ELSE_EXPR?
-    pub fn try_parse_if_expr(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Option<Node>> {
+    pub fn try_parse_if_expr(&mut self, tokens: &mut TokenIterator) -> Result<Option<Node>> {
         if tokens.eat_token(Token::If).is_none() {
             return Ok(None);
         }
@@ -1175,10 +1059,7 @@ impl Tree {
 
     /// IF_EXPR <-
     ///     'if' ( EXPR ) EXPR_OR_STATEMENT_OR_BLOCK ELSE_EXPR?
-    pub fn parse_if_expr(
-        &mut self,
-        tokens: &mut TokenIterator,
-    ) -> Result<Node> {
+    pub fn parse_if_expr(&mut self, tokens: &mut TokenIterator) -> Result<Node> {
         self.try_parse_if_expr(tokens)?
             .ok_or(Error::ExpectedTokenNotFound(Token::If))
     }
@@ -1228,9 +1109,7 @@ impl Tree {
     fn get_typename_str(&self, node: Node) -> Option<String> {
         match self.nodes.get_node(node) {
             Tag::IntegralType(i) => Some(i.to_string()),
-            Tag::Ident { name } => {
-                Some(self.intern_pool.get_str(*name).to_owned())
-            }
+            Tag::Ident { name } => Some(self.intern_pool.get_str(*name).to_owned()),
             Tag::Pointer { pointee } => self.get_typename_str(*pointee),
             Tag::PrimitiveType(prim) => Some(prim.to_string()),
             _ => None,
@@ -1272,9 +1151,7 @@ impl Tree {
                 }
                 children
             }
-            Tag::ReturnStmt { expr } => {
-                expr.into_iter().cloned().collect::<Vec<_>>()
-            }
+            Tag::ReturnStmt { expr } => expr.into_iter().cloned().collect::<Vec<_>>(),
             &Tag::ExprStmt { expr } => {
                 vec![expr]
             }
@@ -1321,10 +1198,7 @@ impl Tree {
             &Tag::ExplicitCast { lhs, typename } => {
                 vec![lhs, typename]
             }
-            Tag::Deref { lhs }
-            | Tag::Ref { lhs }
-            | Tag::Not { lhs }
-            | Tag::Negate { lhs } => {
+            Tag::Deref { lhs } | Tag::Ref { lhs } | Tag::Not { lhs } | Tag::Negate { lhs } => {
                 vec![*lhs]
             }
             Tag::Or { lhs, rhs }
@@ -1371,17 +1245,8 @@ impl Tree {
                 if let Some(parameters) = parameters {
                     self.render_node(writer, parameters, indent)?;
                 }
-                write_indented!(
-                    indent,
-                    writer,
-                    "%{} = function_proto: {{",
-                    node.get()
-                )?;
-                write!(
-                    writer,
-                    "name: \"{}\"",
-                    self.get_ident_str(name).unwrap()
-                )?;
+                write_indented!(indent, writer, "%{} = function_proto: {{", node.get())?;
+                write!(writer, "name: \"{}\"", self.get_ident_str(name).unwrap())?;
                 if let Some(parameters) = parameters {
                     write!(writer, ", parameters: %{}", parameters.get())?;
                 }
@@ -1389,12 +1254,7 @@ impl Tree {
                 writeln!(writer, "}}")
             }
             Tag::ParameterList { parameters } => {
-                writeln_indented!(
-                    indent,
-                    writer,
-                    "%{} = ParameterList [",
-                    node.get()
-                )?;
+                writeln_indented!(indent, writer, "%{} = ParameterList [", node.get())?;
                 for param in parameters {
                     self.render_node(writer, param, indent + 1)?;
                 }
@@ -1410,9 +1270,7 @@ impl Tree {
                     self.get_typename_str(ty).unwrap()
                 )
             }
-            Tag::Pointer { .. }
-            | Tag::IntegralType(_)
-            | Tag::PrimitiveType(_) => {
+            Tag::Pointer { .. } | Tag::IntegralType(_) | Tag::PrimitiveType(_) => {
                 writeln_indented!(
                     indent,
                     writer,
@@ -1469,20 +1327,9 @@ impl Tree {
             Tag::ReturnStmt { expr } => {
                 if let Some(expr) = expr {
                     self.render_node(writer, expr, indent)?;
-                    writeln_indented!(
-                        indent,
-                        writer,
-                        "%{} = return %{};",
-                        node.get(),
-                        expr.get()
-                    )
+                    writeln_indented!(indent, writer, "%{} = return %{};", node.get(), expr.get())
                 } else {
-                    writeln_indented!(
-                        indent,
-                        writer,
-                        "%{} = return;",
-                        node.get()
-                    )
+                    writeln_indented!(indent, writer, "%{} = return;", node.get())
                 }
             }
             Tag::ExprStmt { expr } => self.render_node(writer, expr, indent),
@@ -1493,8 +1340,7 @@ impl Tree {
                 assignment,
             } => {
                 self.render_node(writer, name, indent)?;
-                explicit_type
-                    .map(|node| self.render_node(writer, node, indent));
+                explicit_type.map(|node| self.render_node(writer, node, indent));
                 assignment.map(|node| self.render_node(writer, node, indent));
 
                 write_indented!(
@@ -1513,11 +1359,7 @@ impl Tree {
                     self.get_ident_str(name).unwrap()
                 )?;
                 if let Some(ty) = explicit_type {
-                    write!(
-                        writer,
-                        ", ty: {}",
-                        self.get_typename_str(ty).unwrap()
-                    )?;
+                    write!(writer, ", ty: {}", self.get_typename_str(ty).unwrap())?;
                 }
                 if let Some(assignment) = assignment {
                     write!(writer, ", value: %{assignment}")?;
@@ -1541,11 +1383,7 @@ impl Tree {
                     self.get_ident_str(name).unwrap()
                 )?;
                 if let Some(ty) = explicit_type {
-                    write!(
-                        writer,
-                        ", ty: {}",
-                        self.get_typename_str(ty).unwrap()
-                    )?;
+                    write!(writer, ", ty: {}", self.get_typename_str(ty).unwrap())?;
                 }
                 write!(writer, ", value: %{assignment}")?;
                 writeln!(writer, ");")?;
@@ -1555,26 +1393,13 @@ impl Tree {
                 self.render_node(writer, lhs, indent)?;
                 if let Some(rhs) = rhs {
                     self.render_node(writer, rhs, indent)?;
-                    writeln_indented!(
-                        indent,
-                        writer,
-                        "%{node} = call (%{lhs})(%{rhs})"
-                    )
+                    writeln_indented!(indent, writer, "%{node} = call (%{lhs})(%{rhs})")
                 } else {
-                    writeln_indented!(
-                        indent,
-                        writer,
-                        "%{node} = call (%{lhs})()"
-                    )
+                    writeln_indented!(indent, writer, "%{node} = call (%{lhs})()")
                 }
             }
             Tag::ArgumentList { arguments } => {
-                writeln_indented!(
-                    indent,
-                    writer,
-                    "%{} = ArgumentList [",
-                    node.get()
-                )?;
+                writeln_indented!(indent, writer, "%{} = ArgumentList [", node.get())?;
                 for args in arguments {
                     self.render_node(writer, args, indent + 1)?;
                 }
@@ -1590,12 +1415,7 @@ impl Tree {
                         self.get_ident_str(name).unwrap(),
                     )
                 } else {
-                    writeln_indented!(
-                        indent,
-                        writer,
-                        "%{} = %{expr},",
-                        node.get(),
-                    )
+                    writeln_indented!(indent, writer, "%{} = %{expr},", node.get(),)
                 }
             }
 
@@ -1612,13 +1432,7 @@ impl Tree {
             }
             Tag::Deref { lhs } => {
                 self.render_node(writer, lhs, indent)?;
-                writeln_indented!(
-                    indent,
-                    writer,
-                    "%{} = deref(%{})",
-                    node.get(),
-                    lhs.get()
-                )
+                writeln_indented!(indent, writer, "%{} = deref(%{})", node.get(), lhs.get())
             }
             Tag::Ref { lhs } => {
                 self.render_node(writer, lhs, indent)?;
@@ -1636,13 +1450,7 @@ impl Tree {
             }
             Tag::Negate { lhs } => {
                 self.render_node(writer, lhs, indent)?;
-                writeln_indented!(
-                    indent,
-                    writer,
-                    "%{} = not(%{})",
-                    node.get(),
-                    lhs.get()
-                )
+                writeln_indented!(indent, writer, "%{} = not(%{})", node.get(), lhs.get())
             }
             Tag::Or { lhs, rhs } => {
                 self.render_node(writer, lhs, indent)?;
@@ -1950,10 +1758,7 @@ impl Tree {
         }
     }
 
-    pub fn render<W: core::fmt::Write>(
-        &mut self,
-        writer: &mut W,
-    ) -> core::fmt::Result {
+    pub fn render<W: core::fmt::Write>(&mut self, writer: &mut W) -> core::fmt::Result {
         for decl in &self.global_decls.clone() {
             self.render_node(writer, *decl, 0)?;
         }
@@ -1961,16 +1766,6 @@ impl Tree {
         Ok(())
     }
 
-    fn render2<W: core::fmt::Write>(&mut self, w: &mut W) {
-        for decl in self.global_decls.clone().iter() {
-            ast::tree_visitor::Visitor::new(
-                *decl,
-                |_: &mut Tree, _: Node| {},
-                |_: &mut Tree, _: Node| {},
-            );
-        }
-    }
-
     pub fn peer_type_of_nodes_unwrap(&self, lhs: Node, rhs: Node) -> Type {
         self.peer_type_of_nodes(lhs, rhs).expect({
             let at = self.type_of_node(lhs);
@@ -2031,9 +1826,7 @@ impl Tree {
                 pointee: Box::new(self.type_of_node(*pointee)),
             },
             Tag::Constant { ty, .. } => ty.clone(),
-            Tag::IntegralType(t) => {
-                self.intern_pool.as_ast1_type(AMD64_POINTER_BITS, *t)
-            }
+            Tag::IntegralType(t) => self.intern_pool.as_ast1_type(AMD64_POINTER_BITS, *t),
             Tag::PrimitiveType(t) => match *t {
                 intern::Index::F32 => Type::Floating(FloatingType::Binary32),
                 intern::Index::F64 => Type::Floating(FloatingType::Binary64),
@@ -2054,9 +1847,7 @@ impl Tree {
                     (Some(a), b) => self.peer_type_of_nodes(*a, *b).expect({
                         let at = self.type_of_node(*a);
                         let bt = self.type_of_node(*b);
-                        &format!(
-                            "incompatible types for %{a}({at}) and %{b}({bt})"
-                        )
+                        &format!("incompatible types for %{a}({at}) and %{b}({bt})")
                     }),
                 };
 
@@ -2081,9 +1872,7 @@ impl Tree {
 
                 ty
             }
-            Tag::CallExpr { lhs, .. } => {
-                self.type_of_node(*lhs).return_type().unwrap().clone()
-            }
+            Tag::CallExpr { lhs, .. } => self.type_of_node(*lhs).return_type().unwrap().clone(),
             Tag::ExplicitCast { typename, .. } => self.type_of_node(*typename),
             Tag::Deref { lhs } => self.type_of_node(*lhs).remove_ptr().unwrap(),
             Tag::Ref { lhs } => self.type_of_node(*lhs).into_ptr(),
@@ -2099,15 +1888,11 @@ impl Tree {
             | Tag::And { lhs, rhs }
             | Tag::BitOr { lhs, rhs }
             | Tag::BitAnd { lhs, rhs }
-            | Tag::BitXOr { lhs, rhs } => {
-                self.peer_type_of_nodes(*lhs, *rhs).expect({
-                    let at = self.type_of_node(*lhs);
-                    let bt = self.type_of_node(*rhs);
-                    &format!(
-                        "incompatible types for %{lhs}({at}) and %{rhs}({bt})"
-                    )
-                })
-            }
+            | Tag::BitXOr { lhs, rhs } => self.peer_type_of_nodes(*lhs, *rhs).expect({
+                let at = self.type_of_node(*lhs);
+                let bt = self.type_of_node(*rhs);
+                &format!("incompatible types for %{lhs}({at}) and %{rhs}({bt})")
+            }),
             Tag::Shl { lhs, .. } => self.type_of_node(*lhs),
             Tag::Shr { lhs, .. } => self.type_of_node(*lhs),
             Tag::Eq { .. } => Type::bool(),
@@ -2181,9 +1966,7 @@ impl Tree {
 
                 is_comptime
             }
-            Tag::Not { lhs } | Tag::Negate { lhs } => {
-                self.is_node_comptime(*lhs, true)
-            }
+            Tag::Not { lhs } | Tag::Negate { lhs } => self.is_node_comptime(*lhs, true),
             Tag::Or { lhs, rhs }
             | Tag::And { lhs, rhs }
             | Tag::BitOr { lhs, rhs }
@@ -2202,8 +1985,7 @@ impl Tree {
             | Tag::Mul { lhs, rhs }
             | Tag::Rem { lhs, rhs }
             | Tag::Div { lhs, rhs } => {
-                self.is_node_comptime(*lhs, true)
-                    && self.is_node_comptime(*rhs, true)
+                self.is_node_comptime(*lhs, true) && self.is_node_comptime(*rhs, true)
             }
             _ => false,
         }
@@ -2212,15 +1994,13 @@ impl Tree {
     pub fn value_of_comptime_node(&self, node: Node) -> Option<ComptimeNumber> {
         match self.nodes.get_node(node) {
             Tag::Constant { bytes, ty } => {
-                let ty =
-                    self.intern_pool.from_ast1_type(AMD64_POINTER_BITS, ty);
-                let number =
-                    crate::ast2::interned_type_and_value_to_comptime_number(
-                        &self.intern_pool,
-                        AMD64_POINTER_BITS,
-                        ty,
-                        *bytes,
-                    );
+                let ty = self.intern_pool.from_ast1_type(AMD64_POINTER_BITS, ty);
+                let number = crate::ast2::interned_type_and_value_to_comptime_number(
+                    &self.intern_pool,
+                    AMD64_POINTER_BITS,
+                    ty,
+                    *bytes,
+                );
 
                 Some(number)
             }
@@ -2258,17 +2038,14 @@ impl Tree {
             |_: &mut Tree, _| {},
             |tree: &mut Tree, node| {
                 if let Ok(value) = tree.fold_comptime_inner(node, false) {
-                    let (value, ty) =
-                        crate::ast2::comptime_number_to_interned_type_and_value(
-                            &mut tree.intern_pool,
-                            AMD64_POINTER_BITS,
-                            value,
-                        );
-                    let ty =
-                        tree.intern_pool.as_ast1_type(AMD64_POINTER_BITS, ty);
+                    let (value, ty) = crate::ast2::comptime_number_to_interned_type_and_value(
+                        &mut tree.intern_pool,
+                        AMD64_POINTER_BITS,
+                        value,
+                    );
+                    let ty = tree.intern_pool.as_ast1_type(AMD64_POINTER_BITS, ty);
 
-                    *tree.nodes.get_node_mut(node) =
-                        Tag::Constant { bytes: value, ty };
+                    *tree.nodes.get_node_mut(node) = Tag::Constant { bytes: value, ty };
                 }
             },
         )
@@ -2283,15 +2060,13 @@ impl Tree {
         if self.is_node_comptime(decl, check_declrefs) {
             match self.nodes.get_node(decl) {
                 Tag::Constant { bytes, ty } => {
-                    let ty =
-                        self.intern_pool.from_ast1_type(AMD64_POINTER_BITS, ty);
-                    let number =
-                        crate::ast2::interned_type_and_value_to_comptime_number(
-                            &self.intern_pool,
-                            AMD64_POINTER_BITS,
-                            ty,
-                            *bytes,
-                        );
+                    let ty = self.intern_pool.from_ast1_type(AMD64_POINTER_BITS, ty);
+                    let number = crate::ast2::interned_type_and_value_to_comptime_number(
+                        &self.intern_pool,
+                        AMD64_POINTER_BITS,
+                        ty,
+                        *bytes,
+                    );
 
                     return Ok(number);
                 }
@@ -2523,8 +2298,7 @@ impl Tree {
         match self.nodes[node].clone() {
             Tag::FunctionProto { .. } => {}
             Tag::FunctionDecl { proto, body } => {
-                let Tag::FunctionProto { return_type, .. } = self.nodes[proto]
-                else {
+                let Tag::FunctionProto { return_type, .. } = self.nodes[proto] else {
                     unreachable!()
                 };
 
@@ -2533,25 +2307,19 @@ impl Tree {
 
                 if let Some(peer_t) = body_t.equal_type(&ret_t) {
                     if body_t == Type::comptime_number() {
-                        let Tag::Block { trailing_expr, .. } = self.nodes[body]
-                        else {
+                        let Tag::Block { trailing_expr, .. } = self.nodes[body] else {
                             unreachable!()
                         };
                         if let Some(expr) = trailing_expr {
                             let ty = self.nodes.push_tag(Tag::PrimitiveType(
-                                self.intern_pool.from_ast1_type(
-                                    AMD64_POINTER_BITS,
-                                    &peer_t,
-                                ),
+                                self.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &peer_t),
                             ));
                             let expr = self.nodes.push_tag(Tag::ExplicitCast {
                                 lhs: expr,
                                 typename: ty,
                             });
 
-                            let Tag::Block { trailing_expr, .. } =
-                                &mut self.nodes[body]
-                            else {
+                            let Tag::Block { trailing_expr, .. } = &mut self.nodes[body] else {
                                 unreachable!()
                             };
                             *trailing_expr = Some(expr)
@@ -2576,10 +2344,7 @@ impl Tree {
                 };
                 if bits < ty.bit_width() as u32 {
                     errors.push(AnalysisError::new(
-                        AnalysisErrorTag::InsufficientBitsInTypeForConstant(
-                            bits,
-                            ty.clone(),
-                        ),
+                        AnalysisErrorTag::InsufficientBitsInTypeForConstant(bits, ty.clone()),
                     ));
                 }
             }
diff --git a/src/triples.rs b/src/triples.rs
index afb6cea..9d90e05 100644
--- a/src/triples.rs
+++ b/src/triples.rs
@@ -6,12 +6,9 @@ use std::{
 };
 
 use crate::{
-    ast::{IntegralType, Node as AstNode, Tag, Type},
-    ast2::intern::{
-        self, InternPool, AMD64_POINTER_BITS, AMD64_POINTER_TYPE_INFO,
-    },
+    ast::{Node as AstNode, Tag, Type},
+    ast2::intern::{self, InternPool, AMD64_POINTER_BITS, AMD64_POINTER_TYPE_INFO},
     parser::Tree,
-    string_table::{ImmOrIndex, Index as StringsIndex, StringTable},
     variant, write_indented, writeln_indented,
 };
 
@@ -48,9 +45,7 @@ fn mir_unalignment(signed: bool, bits: u32) -> Option<(bool, u16)> {
 impl Type2 {
     fn mir_type(self) -> mir::Type {
         match self {
-            Type2::Integral(_, bits) => {
-                mir::Type::from_bitsize_int(bits as u32)
-            }
+            Type2::Integral(_, bits) => mir::Type::from_bitsize_int(bits as u32),
             Type2::Binary32 => mir::Type::SinglePrecision,
             Type2::Binary64 => mir::Type::DoublePrecision,
             Type2::Bool => mir::Type::from_bitsize_int(1),
@@ -135,9 +130,7 @@ impl From<&Type> for Type2 {
             Type::Pointer { .. } => Type2::Pointer,
             Type::Fn { .. } => Type2::Pointer,
             _ => {
-                unimplemented!(
-                    "conversion from {value:?} to triples type not implemented"
-                )
+                unimplemented!("conversion from {value:?} to triples type not implemented")
             }
         }
     }
@@ -284,15 +277,15 @@ impl From<u64> for Data {
     }
 }
 
-impl From<crate::string_table::ImmOrIndex> for Data {
-    fn from(value: crate::string_table::ImmOrIndex) -> Self {
-        match value {
-            ImmOrIndex::U64(v) => v.into(),
-            ImmOrIndex::U32(v) => v.into(),
-            ImmOrIndex::Index(v) => v.into(),
-        }
-    }
-}
+// impl From<crate::string_table::ImmOrIndex> for Data {
+//     fn from(value: crate::string_table::ImmOrIndex) -> Self {
+//         match value {
+//             ImmOrIndex::U64(v) => v.into(),
+//             ImmOrIndex::U32(v) => v.into(),
+//             ImmOrIndex::Index(v) => v.into(),
+//         }
+//     }
+// }
 
 impl From<intern::Index> for Data {
     fn from(value: intern::Index) -> Self {
@@ -397,33 +390,24 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
                 );
 
                 self.ir.push(Inst::FunctionStart, {
-                    variant!(
-                        Tag::Ident { name } = self.tree.nodes.get_node(*name)
-                    );
+                    variant!(Tag::Ident { name } = self.tree.nodes.get_node(*name));
                     Some((*name).into())
                 });
 
                 if let Some(parameters) = parameters {
                     variant!(
-                        Tag::ParameterList { parameters } =
-                            self.tree.nodes.get_node(*parameters)
+                        Tag::ParameterList { parameters } = self.tree.nodes.get_node(*parameters)
                     );
 
                     for param in parameters {
-                        variant!(
-                            Tag::Parameter { ty, .. } =
-                                self.tree.nodes.get_node(*param)
-                        );
+                        variant!(Tag::Parameter { ty, .. } = self.tree.nodes.get_node(*param));
                         let ty = self.tree.type_of_node(*ty);
                         let size = ty.size_of();
                         let align = ty.align_of();
-                        let ty = self
-                            .intern_pool()
-                            .from_ast1_type(AMD64_POINTER_BITS, &ty);
-                        let ir = self.ir.push(
-                            Inst::Parameter(ty),
-                            Some(Data::new(size, align)),
-                        );
+                        let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                        let ir = self
+                            .ir
+                            .push(Inst::Parameter(ty), Some(Data::new(size, align)));
 
                         self.lookup.insert(*param, NodeOrList::Node(ir));
                     }
@@ -434,53 +418,43 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
                 self.tree.st.into_parent();
                 if value != !0 {
                     let ty = self.tree.type_of_node(*body);
-                    let ty = self
-                        .intern_pool()
-                        .from_ast1_type(AMD64_POINTER_BITS, &ty);
-                    self.ir.push(
-                        Inst::ReturnValue(ty.into()),
-                        Some(Data::lhs(value)),
-                    );
+                    let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                    self.ir
+                        .push(Inst::ReturnValue(ty.into()), Some(Data::lhs(value)));
                 }
 
                 self.ir.push(Inst::FunctionEnd, None)
             }
             Tag::CallExpr { lhs, rhs } => {
-                let ty =
-                    self.tree.type_of_node(*lhs).return_type().unwrap().clone();
-                let args = if let Some(args) = *rhs {
-                    variant!(
-                        self.tree.nodes.get_node(args) => Tag::ArgumentList { arguments }
-                    );
+                let ty = self.tree.type_of_node(*lhs).return_type().unwrap().clone();
+                let args =
+                    if let Some(args) = *rhs {
+                        variant!(
+                            self.tree.nodes.get_node(args) => Tag::ArgumentList { arguments }
+                        );
 
-                    let args = arguments.clone().iter().map(|arg| {
+                        let args = arguments.clone().iter().map(|arg| {
                             variant!(*self.tree.nodes.get_node(*arg) => Tag::Argument { expr ,..});
                             (self.visit(expr), self.tree.type_of_node(expr))
                     }).collect::<Vec<_>>();
 
-                    let start = self.ir.nodes.len();
-                    for (arg, ty) in args {
-                        let ty = self
-                            .intern_pool()
-                            .from_ast1_type(AMD64_POINTER_BITS, &ty);
-                        _ = self.ir.push(
-                            Inst::Argument(ty.into()),
-                            Some(Data::lhs(arg)),
-                        );
-                    }
-                    let end = self.ir.nodes.len();
+                        let start = self.ir.nodes.len();
+                        for (arg, ty) in args {
+                            let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                            _ = self
+                                .ir
+                                .push(Inst::Argument(ty.into()), Some(Data::lhs(arg)));
+                        }
+                        let end = self.ir.nodes.len();
 
-                    Some((start as u32, end as u32))
-                } else {
-                    None
-                };
-                let (start, end) = args.unwrap_or((
-                    self.ir.nodes.len() as u32,
-                    self.ir.nodes.len() as u32,
-                ));
+                        Some((start as u32, end as u32))
+                    } else {
+                        None
+                    };
+                let (start, end) =
+                    args.unwrap_or((self.ir.nodes.len() as u32, self.ir.nodes.len() as u32));
 
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
                 self.ir.push(Inst::InlineType(ty.into()), None);
 
                 let func = self.visit(*lhs);
@@ -504,20 +478,17 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
             }
             Tag::VarDecl { assignment, .. } => {
                 let ty = self.tree.type_of_node(node);
-                let alloca = self.ir.push(
-                    Inst::Alloca,
-                    Some(Data::new(ty.size_of(), ty.align_of())),
-                );
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                let alloca = self
+                    .ir
+                    .push(Inst::Alloca, Some(Data::new(ty.size_of(), ty.align_of())));
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
 
                 if let Some(assignment) = assignment {
                     let value = self.visit(*assignment);
                     // discard store
-                    let _ = self.ir.push(
-                        Inst::Store(ty.into()),
-                        Some(Data::new(value, alloca)),
-                    );
+                    let _ = self
+                        .ir
+                        .push(Inst::Store(ty.into()), Some(Data::new(value, alloca)));
                 }
                 self.lookup.insert(node, NodeOrList::Node(alloca));
                 alloca
@@ -531,8 +502,7 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
 
                 variant!(self.tree.nodes.get_node(*name) => Tag::Ident { name });
 
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
                 let global = self.ir.push(
                     Inst::GlobalConstant(*name, ty.into()),
                     Some(Data::lhs(value)),
@@ -544,12 +514,10 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
             }
             Tag::GlobalRef(decl) => {
                 let ty = self.tree.type_of_node(*decl);
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
-                let node = self.ir.push(
-                    Inst::ExternRef(ty.into()),
-                    Some(Data::lhs(decl.get())),
-                );
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                let node = self
+                    .ir
+                    .push(Inst::ExternRef(ty.into()), Some(Data::lhs(decl.get())));
                 self.fixup.push(node);
                 node
             }
@@ -566,41 +534,33 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
                 let dest = self.visit(*lhs);
                 let source = self.visit(*rhs);
 
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
                 self.ir
                     .push(Inst::Store(ty.into()), Some(Data::new(source, dest)))
             }
             Tag::ReturnStmt { expr } => {
                 if let Some(expr) = expr {
                     let ty = self.tree.type_of_node(*expr);
-                    let ty = self
-                        .intern_pool()
-                        .from_ast1_type(AMD64_POINTER_BITS, &ty);
+                    let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
                     let expr = self.visit(*expr);
-                    self.ir.push(
-                        Inst::ReturnValue(ty.into()),
-                        Some(Data::lhs(expr)),
-                    )
+                    self.ir
+                        .push(Inst::ReturnValue(ty.into()), Some(Data::lhs(expr)))
                 } else {
                     self.ir.push(Inst::Return, None)
                 }
             }
             Tag::ExprStmt { expr } => self.visit(*expr),
             Tag::Deref { lhs } => {
-                let ty =
-                    self.tree.type_of_node(*lhs).pointee().unwrap().clone();
+                let ty = self.tree.type_of_node(*lhs).pointee().unwrap().clone();
                 let lhs = self.visit(*lhs);
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
                 self.ir.push(Inst::Load(ty.into()), Some(Data::lhs(lhs)))
             }
             Tag::Add { lhs, rhs } => {
                 let ty = self.tree.type_of_node(node);
                 let lhs = self.visit(*lhs);
                 let rhs = self.visit(*rhs);
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
                 self.ir
                     .push(Inst::Add(ty.into()), Some(Data::new(lhs, rhs)))
             }
@@ -608,8 +568,7 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
                 let ty = self.tree.type_of_node(node);
                 let lhs = self.visit(*lhs);
                 let rhs = self.visit(*rhs);
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
                 self.ir
                     .push(Inst::Sub(ty.into()), Some(Data::new(lhs, rhs)))
             }
@@ -617,8 +576,7 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
                 let ty = self.tree.type_of_node(node);
                 let lhs = self.visit(*lhs);
                 let rhs = self.visit(*rhs);
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
                 self.ir
                     .push(Inst::BitAnd(ty.into()), Some(Data::new(lhs, rhs)))
             }
@@ -626,8 +584,7 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
                 let ty = self.tree.type_of_node(node);
                 let lhs = self.visit(*lhs);
                 let rhs = self.visit(*rhs);
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
                 self.ir
                     .push(Inst::BitOr(ty.into()), Some(Data::new(lhs, rhs)))
             }
@@ -635,8 +592,7 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
                 let ty = self.tree.type_of_node(node);
                 let lhs = self.visit(*lhs);
                 let rhs = self.visit(*rhs);
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
                 self.ir
                     .push(Inst::BitXOr(ty.into()), Some(Data::new(lhs, rhs)))
             }
@@ -656,8 +612,7 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
                     })
                     .into();
 
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
                 let inst = match tag {
                     Tag::Eq { .. } => Inst::Eq(ty),
                     Tag::NEq { .. } => Inst::Neq(ty),
@@ -676,31 +631,27 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
                 let ty = self.tree.type_of_node(node);
                 let lhs = self.visit(*lhs);
                 let rhs = self.visit(*rhs);
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
                 self.ir
                     .push(Inst::Mul(ty.into()), Some(Data::new(lhs, rhs)))
             }
             Tag::Negate { lhs } => {
                 let ty = self.tree.type_of_node(node);
                 let lhs = self.visit(*lhs);
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
                 self.ir.push(Inst::Negate(ty.into()), Some(Data::lhs(lhs)))
             }
             Tag::Not { lhs } => {
                 let ty = self.tree.type_of_node(node);
                 let lhs = self.visit(*lhs);
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
                 self.ir.push(Inst::Not(ty.into()), Some(Data::lhs(lhs)))
             }
             Tag::Shl { lhs, rhs } => {
                 let ty = self.tree.type_of_node(node);
                 let lhs = self.visit(*lhs);
                 let rhs = self.visit(*rhs);
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
                 self.ir
                     .push(Inst::ShiftLeft(ty.into()), Some(Data::new(lhs, rhs)))
             }
@@ -708,28 +659,21 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
                 let ty = self.tree.type_of_node(node);
                 let lhs = self.visit(*lhs);
                 let rhs = self.visit(*rhs);
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
-                self.ir.push(
-                    Inst::ShiftRight(ty.into()),
-                    Some(Data::new(lhs, rhs)),
-                )
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                self.ir
+                    .push(Inst::ShiftRight(ty.into()), Some(Data::new(lhs, rhs)))
             }
             Tag::Ref { lhs } => {
                 let ty = self.tree.type_of_node(*lhs);
                 let lhs = self.visit(*lhs);
                 // self.ir.push(Inst::Load(ty.into()), Some(Data::lhs(lhs)))
                 // nothing happens here because lhs is of type pointer
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
-                self.ir.push(
-                    Inst::GetElementPtr(ty.into()),
-                    Some(Data::new(lhs, 0)),
-                )
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                self.ir
+                    .push(Inst::GetElementPtr(ty.into()), Some(Data::new(lhs, 0)))
             }
             Tag::Constant { bytes, ty } => {
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, ty);
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, ty);
                 self.ir.push(Inst::Constant, Some((ty, *bytes).into()))
             }
             Tag::ExplicitCast { lhs, typename } => {
@@ -742,12 +686,8 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
                     //noop?
                     lhs
                 } else {
-                    let l_ty = self
-                        .intern_pool()
-                        .from_ast1_type(AMD64_POINTER_BITS, &l_ty);
-                    let r_ty = self
-                        .intern_pool()
-                        .from_ast1_type(AMD64_POINTER_BITS, &r_ty);
+                    let l_ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &l_ty);
+                    let r_ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &r_ty);
                     self.ir.push(
                         Inst::ExplicitCast(l_ty.into(), r_ty.into()),
                         Some(Data::lhs(lhs)),
@@ -760,16 +700,14 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
                 let condition = self.visit(*condition);
                 let br = self.ir.push(Inst::Branch(condition), None);
 
-                let label_lhs = self.ir.push(
-                    Inst::Label,
-                    Some(intern::Index::EMPTY_STRING.into()),
-                );
+                let label_lhs = self
+                    .ir
+                    .push(Inst::Label, Some(intern::Index::EMPTY_STRING.into()));
                 let _ = self.visit(*body);
                 let jmp = self.ir.push(Inst::Jump, None);
-                let nojump = self.ir.push(
-                    Inst::Label,
-                    Some(intern::Index::EMPTY_STRING.into()),
-                );
+                let nojump = self
+                    .ir
+                    .push(Inst::Label, Some(intern::Index::EMPTY_STRING.into()));
 
                 self.ir.data[br as usize] = Some(Data::new(label_lhs, nojump));
                 self.ir.data[jmp as usize] = Some(Data::lhs(nojump));
@@ -782,37 +720,32 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> {
             } => {
                 assert_eq!(self.tree.type_of_node(*condition), Type::Bool);
                 let ty = self.tree.peer_type_of_nodes_unwrap(*body, *else_expr);
-                let ty =
-                    self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
+                let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty);
 
                 let condition = self.visit(*condition);
                 let br = self.ir.push(Inst::Branch(condition), None);
 
-                let label_lhs = self.ir.push(
-                    Inst::Label,
-                    Some(intern::Index::EMPTY_STRING.into()),
-                );
+                let label_lhs = self
+                    .ir
+                    .push(Inst::Label, Some(intern::Index::EMPTY_STRING.into()));
                 let lhs = self.visit(*body);
                 let ljmp = self.ir.push(Inst::Jump, None);
-                let label_rhs = self.ir.push(
-                    Inst::Label,
-                    Some(intern::Index::EMPTY_STRING.into()),
-                );
+                let label_rhs = self
+                    .ir
+                    .push(Inst::Label, Some(intern::Index::EMPTY_STRING.into()));
                 let rhs = self.visit(*else_expr);
                 let rjmp = self.ir.push(Inst::Jump, None);
 
-                let nojump = self.ir.push(
-                    Inst::Label,
-                    Some(intern::Index::EMPTY_STRING.into()),
-                );
+                let nojump = self
+                    .ir
+                    .push(Inst::Label, Some(intern::Index::EMPTY_STRING.into()));
                 let phi = if ty != intern::Index::VOID {
                     self.ir.push(Inst::Phi2(ty), Some(Data::new(lhs, rhs)))
                 } else {
                     br
                 };
 
-                self.ir.data[br as usize] =
-                    Some(Data::new(label_lhs, label_rhs));
+                self.ir.data[br as usize] = Some(Data::new(label_lhs, label_rhs));
                 self.ir.data[ljmp as usize] = Some(Data::lhs(nojump));
                 self.ir.data[rjmp as usize] = Some(Data::lhs(nojump));
                 phi
@@ -845,10 +778,7 @@ impl IR {
         node
     }
 
-    pub fn build<'b, 'tree>(
-        &'b mut self,
-        tree: &'tree mut Tree,
-    ) -> IRBuilder<'tree, 'b> {
+    pub fn build<'b, 'tree>(&'b mut self, tree: &'tree mut Tree) -> IRBuilder<'tree, 'b> {
         let global_decls = tree.global_decls.clone();
         let mut builder = IRBuilder::new(self, tree);
 
@@ -859,11 +789,7 @@ impl IR {
         for &fix in builder.fixup.iter() {
             let ast_node = builder.ir.data[fix as usize].unwrap().lhs;
 
-            let idx = match builder
-                .tree
-                .nodes
-                .get_node(AstNode::new(ast_node).unwrap())
-            {
+            let idx = match builder.tree.nodes.get_node(AstNode::new(ast_node).unwrap()) {
                 Tag::FunctionDecl { proto, .. } => {
                     variant!(builder.tree.nodes.get_node(*proto) => Tag::FunctionProto { name,..});
                     variant!(builder.tree.nodes.get_node(*name) => Tag::Ident { name });
@@ -898,12 +824,7 @@ impl IRBuilder<'_, '_> {
         match inst {
             Inst::Label => {
                 let label = self.intern_pool().get_str(data.as_index());
-                writeln_indented!(
-                    indent - 1,
-                    w,
-                    "%{} = label \"{label}\":",
-                    node
-                )?;
+                writeln_indented!(indent - 1, w, "%{} = label \"{label}\":", node)?;
             }
             Inst::FunctionStart => {
                 let label = self.intern_pool().get_str(data.as_index());
@@ -955,129 +876,48 @@ impl IRBuilder<'_, '_> {
             }
             Inst::Add(ty) => {
                 let (lhs, rhs) = data.as_lhs_rhs();
-                writeln_indented!(
-                    indent,
-                    w,
-                    "%{} = add_{ty}(%{} + %{})",
-                    node,
-                    lhs,
-                    rhs
-                )?;
+                writeln_indented!(indent, w, "%{} = add_{ty}(%{} + %{})", node, lhs, rhs)?;
             }
             Inst::Sub(ty) => {
                 let (lhs, rhs) = data.as_lhs_rhs();
-                writeln_indented!(
-                    indent,
-                    w,
-                    "%{} = sub_{ty}(%{} - %{})",
-                    node,
-                    lhs,
-                    rhs
-                )?;
+                writeln_indented!(indent, w, "%{} = sub_{ty}(%{} - %{})", node, lhs, rhs)?;
             }
             Inst::Eq(ty) => {
                 let (lhs, rhs) = data.as_lhs_rhs();
-                writeln_indented!(
-                    indent,
-                    w,
-                    "%{} = eq_{ty}(%{} == %{})",
-                    node,
-                    lhs,
-                    rhs
-                )?;
+                writeln_indented!(indent, w, "%{} = eq_{ty}(%{} == %{})", node, lhs, rhs)?;
             }
             Inst::Neq(ty) => {
                 let (lhs, rhs) = data.as_lhs_rhs();
-                writeln_indented!(
-                    indent,
-                    w,
-                    "%{} = neq_{ty}(%{} != %{})",
-                    node,
-                    lhs,
-                    rhs
-                )?;
+                writeln_indented!(indent, w, "%{} = neq_{ty}(%{} != %{})", node, lhs, rhs)?;
             }
             Inst::Gt(ty) => {
                 let (lhs, rhs) = data.as_lhs_rhs();
-                writeln_indented!(
-                    indent,
-                    w,
-                    "%{} = gt_{ty}(%{} > %{})",
-                    node,
-                    lhs,
-                    rhs
-                )?;
+                writeln_indented!(indent, w, "%{} = gt_{ty}(%{} > %{})", node, lhs, rhs)?;
             }
             Inst::Lt(ty) => {
                 let (lhs, rhs) = data.as_lhs_rhs();
-                writeln_indented!(
-                    indent,
-                    w,
-                    "%{} = lt_{ty}(%{} < %{})",
-                    node,
-                    lhs,
-                    rhs
-                )?;
+                writeln_indented!(indent, w, "%{} = lt_{ty}(%{} < %{})", node, lhs, rhs)?;
             }
             Inst::Ge(ty) => {
                 let (lhs, rhs) = data.as_lhs_rhs();
-                writeln_indented!(
-                    indent,
-                    w,
-                    "%{} = ge_{ty}(%{} >= %{})",
-                    node,
-                    lhs,
-                    rhs
-                )?;
+                writeln_indented!(indent, w, "%{} = ge_{ty}(%{} >= %{})", node, lhs, rhs)?;
             }
             Inst::Le(ty) => {
                 let (lhs, rhs) = data.as_lhs_rhs();
-                writeln_indented!(
-                    indent,
-                    w,
-                    "%{} = le_{ty}(%{} <= %{})",
-                    node,
-                    lhs,
-                    rhs
-                )?;
+                writeln_indented!(indent, w, "%{} = le_{ty}(%{} <= %{})", node, lhs, rhs)?;
             }
             Inst::Mul(ty) => {
                 let (lhs, rhs) = data.as_lhs_rhs();
-                writeln_indented!(
-                    indent,
-                    w,
-                    "%{} = mul_{ty}(%{} * %{})",
-                    node,
-                    lhs,
-                    rhs
-                )?;
+                writeln_indented!(indent, w, "%{} = mul_{ty}(%{} * %{})", node, lhs, rhs)?;
             }
             Inst::Negate(ty) => {
-                writeln_indented!(
-                    indent,
-                    w,
-                    "%{} = negate_{ty}(%{})",
-                    node,
-                    data.lhs
-                )?;
+                writeln_indented!(indent, w, "%{} = negate_{ty}(%{})", node, data.lhs)?;
             }
             Inst::Not(ty) => {
-                writeln_indented!(
-                    indent,
-                    w,
-                    "%{} = bitwise_not_{ty}(%{})",
-                    node,
-                    data.lhs
-                )?;
+                writeln_indented!(indent, w, "%{} = bitwise_not_{ty}(%{})", node, data.lhs)?;
             }
             Inst::ExplicitCast(from, to) => {
-                writeln_indented!(
-                    indent,
-                    w,
-                    "%{} = cast_{from}_to_{to}(%{})",
-                    node,
-                    data.lhs
-                )?;
+                writeln_indented!(indent, w, "%{} = cast_{from}_to_{to}(%{})", node, data.lhs)?;
             }
             Inst::ShiftLeft(ty) => {
                 writeln_indented!(
@@ -1100,25 +940,14 @@ impl IRBuilder<'_, '_> {
                 )?;
             }
             Inst::ReturnValue(ty) => {
-                writeln_indented!(
-                    indent,
-                    w,
-                    "%{} = return {ty} %{}",
-                    node,
-                    data.lhs
-                )?;
+                writeln_indented!(indent, w, "%{} = return {ty} %{}", node, data.lhs)?;
             }
             Inst::Return => {
                 writeln_indented!(indent, w, "%{} = return", node)?;
             }
             Inst::Alloca => {
                 let (size, align) = data.as_lhs_rhs();
-                writeln_indented!(
-                    indent,
-                    w,
-                    "%{} = alloca {size} (align: {align})",
-                    node
-                )?;
+                writeln_indented!(indent, w, "%{} = alloca {size} (align: {align})", node)?;
             }
             Inst::GetElementPtr(ty) => {
                 let (ptr, idx) = data.as_lhs_rhs();
@@ -1132,21 +961,11 @@ impl IRBuilder<'_, '_> {
             }
             Inst::Load(ty) => {
                 let source = data.lhs;
-                writeln_indented!(
-                    indent,
-                    w,
-                    "%{} = load {ty}, %{source}",
-                    node
-                )?;
+                writeln_indented!(indent, w, "%{} = load {ty}, %{source}", node)?;
             }
             Inst::Store(ty) => {
                 let (src, dst) = data.as_lhs_rhs();
-                writeln_indented!(
-                    indent,
-                    w,
-                    "%{} = store {ty}, ptr %{dst}, %{src}",
-                    node
-                )?;
+                writeln_indented!(indent, w, "%{} = store {ty}, ptr %{dst}, %{src}", node)?;
             }
             Inst::ExternRef(ty) => {
                 let idx = data.as_index();
@@ -1172,20 +991,12 @@ impl IRBuilder<'_, '_> {
             }
             Inst::Phi2(ty) => {
                 let (lhs, rhs) = data.as_lhs_rhs();
-                writeln_indented!(
-                    indent,
-                    w,
-                    "%{node} = phi [{ty} %{lhs}, {ty} %{rhs}]"
-                )?;
+                writeln_indented!(indent, w, "%{node} = phi [{ty} %{lhs}, {ty} %{rhs}]")?;
             }
             Inst::GlobalConstant(name, ty) => {
                 let label = self.intern_pool().get_str(name);
                 let value = data.lhs;
-                writeln_indented!(
-                    indent,
-                    w,
-                    "%{node} = global const '{label}' {ty} %{value}"
-                )?;
+                writeln_indented!(indent, w, "%{node} = global const '{label}' {ty} %{value}")?;
             }
             _ => {
                 unimplemented!("{inst:?} rendering unimplemented")
@@ -1259,9 +1070,7 @@ impl<'a> IrToMirMapping<'a> {
 
         match self.ir.nodes[ir as usize] {
             Inst::GlobalConstant(name, ty) => {
-                eprintln!(
-                    "does this even get hit anymore???????????????????//"
-                );
+                eprintln!("does this even get hit anymore???????????????????//");
                 let ty = self.ip.to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
                 let ext = mir::NodeRef(mir.gen_extern(Some(ty), name));
                 self.insert(ir, ext);
@@ -1311,8 +1120,7 @@ impl<'a> MirBuilder<'a> {
                 }
             }
         }
-        let mut unresolved_jumps_branches =
-            BTreeSet::<(Node, LeftRight)>::new();
+        let mut unresolved_jumps_branches = BTreeSet::<(Node, LeftRight)>::new();
 
         loop {
             let ir_node = self.ir.node();
@@ -1332,18 +1140,14 @@ impl<'a> MirBuilder<'a> {
                     let range = unresolved_jumps_branches
                         .range(
                             (ir_node, LeftRight::Left(mir::NodeRef::MIN))
-                                ..=(
-                                    ir_node,
-                                    LeftRight::Right(mir::NodeRef::MAX),
-                                ),
+                                ..=(ir_node, LeftRight::Right(mir::NodeRef::MAX)),
                         )
                         .map(|(_, n)| n)
                         .cloned()
                         .collect::<Vec<_>>();
 
                     for unresolved in range {
-                        unresolved_jumps_branches
-                            .remove(&(ir_node, unresolved));
+                        unresolved_jumps_branches.remove(&(ir_node, unresolved));
 
                         let mir_node = unresolved.noderef();
                         let (inst, data) = mir.get_node_mut(mir_node);
@@ -1356,12 +1160,8 @@ impl<'a> MirBuilder<'a> {
                                 let (lhs, rhs) = data.as_binary_noderefs();
 
                                 *data = match unresolved {
-                                    LeftRight::Left(_) => {
-                                        mir::Data::binary(label, rhs.0)
-                                    }
-                                    LeftRight::Right(_) => {
-                                        mir::Data::binary(lhs.0, label)
-                                    }
+                                    LeftRight::Left(_) => mir::Data::binary(label, rhs.0),
+                                    LeftRight::Right(_) => mir::Data::binary(lhs.0, label),
                                 };
                             }
                             _ => {
@@ -1374,9 +1174,7 @@ impl<'a> MirBuilder<'a> {
                 }
                 Inst::Constant => {
                     let (ty, val) = data.unwrap().as_index_index();
-                    let mir_ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let mir_ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
                     mir.push_const(self.intern_pool(), val, mir_ty)
                 }
                 Inst::Alloca => {
@@ -1384,37 +1182,26 @@ impl<'a> MirBuilder<'a> {
                     mir.gen_alloca(l, r)
                 }
                 Inst::Load(ty) => {
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let src = mapping
-                        .get(&mut mir, data.unwrap().as_u32())
-                        .unwrap()
-                        .0;
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let src = mapping.get(&mut mir, data.unwrap().as_u32()).unwrap().0;
                     mir.gen_load(ty, src)
                 }
                 Inst::Store(ty) => {
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
                     let (src, dst) = data.unwrap().as_lhs_rhs();
                     let src = mapping.get(&mut mir, src).unwrap().0;
                     let dst = mapping.get(&mut mir, dst).unwrap().0;
                     mir.gen_store(ty, src, dst)
                 }
                 Inst::GetElementPtr(ty) => {
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
                     let (ptr, idx) = data.unwrap().as_lhs_rhs();
                     let src = mapping.get(&mut mir, ptr).unwrap().0;
                     mir.gen_get_element_ptr(ty, src, idx)
                 }
                 Inst::Parameter(ty) => {
                     // let (size, _) = data.unwrap().as_lhs_rhs();
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
                     mir.gen_param(ty.into())
                 }
                 Inst::Eq(ty)
@@ -1441,9 +1228,7 @@ impl<'a> MirBuilder<'a> {
                     let signed = self
                         .intern_pool()
                         .is_type_signed(ty, AMD64_POINTER_TYPE_INFO);
-                    let mir_ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let mir_ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
                     mir.gen_cmp_byte(mir_ty, signed, ord, invert, lhs, rhs)
                 }
                 Inst::Add(ty) => {
@@ -1451,26 +1236,17 @@ impl<'a> MirBuilder<'a> {
                     let lhs = mapping.get(&mut mir, src).unwrap().0;
                     let rhs = mapping.get(&mut mir, dst).unwrap().0;
 
-                    let info = self
-                        .intern_pool()
-                        .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
 
                     match info.bitsize {
                         8 | 16 | 32 | 64 => mir.gen_add(ty, lhs, rhs),
                         64.. => {
                             unimplemented!()
                         }
-                        bits => {
+                        _ => {
                             let sum = mir.gen_add(ty, lhs, rhs);
-                            mir.gen_truncate_integer(
-                                sum,
-                                ty,
-                                info.signed,
-                                info.bitsize as u16,
-                            )
+                            mir.gen_truncate_integer(sum, ty, info.signed, info.bitsize as u16)
                         }
                     }
                 }
@@ -1479,14 +1255,9 @@ impl<'a> MirBuilder<'a> {
                     let lhs = mapping.get(&mut mir, src).unwrap().0;
                     let rhs = mapping.get(&mut mir, dst).unwrap().0;
 
-                    let info = self
-                        .intern_pool()
-                        .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let unalignment =
-                        mir_unalignment(info.signed, info.bitsize);
+                    let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let unalignment = mir_unalignment(info.signed, info.bitsize);
 
                     let sum = mir.gen_sub(ty, lhs, rhs);
                     if let Some((signed, bits)) = unalignment {
@@ -1498,14 +1269,9 @@ impl<'a> MirBuilder<'a> {
                 Inst::Mul(ty) => {
                     let (lhs, rhs) = data.unwrap().as_lhs_rhs();
 
-                    let info = self
-                        .intern_pool()
-                        .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let unalignment =
-                        mir_unalignment(info.signed, info.bitsize);
+                    let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let unalignment = mir_unalignment(info.signed, info.bitsize);
 
                     let lhs = mapping.get(&mut mir, lhs).unwrap().0;
                     let rhs = mapping.get(&mut mir, rhs).unwrap().0;
@@ -1520,14 +1286,9 @@ impl<'a> MirBuilder<'a> {
                 Inst::Div(ty) => {
                     let (lhs, rhs) = data.unwrap().as_lhs_rhs();
 
-                    let info = self
-                        .intern_pool()
-                        .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let unalignment =
-                        mir_unalignment(info.signed, info.bitsize);
+                    let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let unalignment = mir_unalignment(info.signed, info.bitsize);
 
                     let lhs = mapping.get(&mut mir, lhs).unwrap().0;
                     let rhs = mapping.get(&mut mir, rhs).unwrap().0;
@@ -1542,14 +1303,9 @@ impl<'a> MirBuilder<'a> {
                 Inst::Rem(ty) => {
                     let (lhs, rhs) = data.unwrap().as_lhs_rhs();
 
-                    let info = self
-                        .intern_pool()
-                        .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let unalignment =
-                        mir_unalignment(info.signed, info.bitsize);
+                    let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let unalignment = mir_unalignment(info.signed, info.bitsize);
 
                     let lhs = mapping.get(&mut mir, lhs).unwrap().0;
                     let rhs = mapping.get(&mut mir, rhs).unwrap().0;
@@ -1564,21 +1320,15 @@ impl<'a> MirBuilder<'a> {
                 Inst::BitAnd(ty) => {
                     let (lhs, rhs) = data.unwrap().as_lhs_rhs();
 
-                    let info = self
-                        .intern_pool()
-                        .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let unalignment =
-                        mir_unalignment(info.signed, info.bitsize);
+                    let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let unalignment = mir_unalignment(info.signed, info.bitsize);
 
-                    let (lhs, rhs) =
-                        if self.ir.ir.nodes[lhs as usize].is_constant() {
-                            (rhs, lhs)
-                        } else {
-                            (lhs, rhs)
-                        };
+                    let (lhs, rhs) = if self.ir.ir.nodes[lhs as usize].is_constant() {
+                        (rhs, lhs)
+                    } else {
+                        (lhs, rhs)
+                    };
 
                     let lhs = mapping.get(&mut mir, lhs).unwrap().0;
                     let rhs = mapping.get(&mut mir, rhs).unwrap().0;
@@ -1593,21 +1343,15 @@ impl<'a> MirBuilder<'a> {
                 Inst::BitOr(ty) => {
                     let (lhs, rhs) = data.unwrap().as_lhs_rhs();
 
-                    let info = self
-                        .intern_pool()
-                        .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let unalignment =
-                        mir_unalignment(info.signed, info.bitsize);
+                    let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let unalignment = mir_unalignment(info.signed, info.bitsize);
 
-                    let (lhs, rhs) =
-                        if self.ir.ir.nodes[lhs as usize].is_constant() {
-                            (rhs, lhs)
-                        } else {
-                            (lhs, rhs)
-                        };
+                    let (lhs, rhs) = if self.ir.ir.nodes[lhs as usize].is_constant() {
+                        (rhs, lhs)
+                    } else {
+                        (lhs, rhs)
+                    };
 
                     let lhs = mapping.get(&mut mir, lhs).unwrap().0;
                     let rhs = mapping.get(&mut mir, rhs).unwrap().0;
@@ -1622,24 +1366,18 @@ impl<'a> MirBuilder<'a> {
                 Inst::BitXOr(ty) => {
                     let (lhs, rhs) = data.unwrap().as_lhs_rhs();
 
-                    let (lhs, rhs) =
-                        if self.ir.ir.nodes[lhs as usize].is_constant() {
-                            (rhs, lhs)
-                        } else {
-                            (lhs, rhs)
-                        };
+                    let (lhs, rhs) = if self.ir.ir.nodes[lhs as usize].is_constant() {
+                        (rhs, lhs)
+                    } else {
+                        (lhs, rhs)
+                    };
 
                     let lhs = mapping.get(&mut mir, lhs).unwrap().0;
                     let rhs = mapping.get(&mut mir, rhs).unwrap().0;
 
-                    let info = self
-                        .intern_pool()
-                        .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let unalignment =
-                        mir_unalignment(info.signed, info.bitsize);
+                    let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let unalignment = mir_unalignment(info.signed, info.bitsize);
 
                     let sum = mir.gen_bitxor(ty, lhs, rhs);
                     if let Some((signed, bits)) = unalignment {
@@ -1653,18 +1391,12 @@ impl<'a> MirBuilder<'a> {
                     let lhs = mapping.get(&mut mir, src).unwrap().0;
                     let rhs = mapping.get(&mut mir, dst).unwrap().0;
 
-                    let info = self
-                        .intern_pool()
-                        .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let unalignment =
-                        mir_unalignment(info.signed, info.bitsize);
+                    let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let unalignment = mir_unalignment(info.signed, info.bitsize);
 
                     // TODO: check rhs type and pass it to gen_sh{l,r}?
-                    let rhs =
-                        mir.gen_truncate_integer(rhs, ty.into(), false, 8);
+                    let rhs = mir.gen_truncate_integer(rhs, ty.into(), false, 8);
 
                     let sum = mir.gen_shl(ty, lhs, rhs);
                     if let Some((signed, bits)) = unalignment {
@@ -1678,18 +1410,12 @@ impl<'a> MirBuilder<'a> {
                     let lhs = mapping.get(&mut mir, src).unwrap().0;
                     let rhs = mapping.get(&mut mir, dst).unwrap().0;
 
-                    let info = self
-                        .intern_pool()
-                        .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let unalignment =
-                        mir_unalignment(info.signed, info.bitsize);
+                    let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let unalignment = mir_unalignment(info.signed, info.bitsize);
 
                     // TODO: check rhs type and pass it to gen_sh{l,r}?
-                    let rhs =
-                        mir.gen_truncate_integer(rhs, ty.into(), false, 8);
+                    let rhs = mir.gen_truncate_integer(rhs, ty.into(), false, 8);
 
                     let sum = mir.gen_shr(ty, lhs, rhs);
                     if let Some((signed, bits)) = unalignment {
@@ -1702,14 +1428,9 @@ impl<'a> MirBuilder<'a> {
                     let lhs = data.unwrap().as_u32();
                     let lhs = mapping.get(&mut mir, lhs).unwrap().0;
 
-                    let info = self
-                        .intern_pool()
-                        .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let unalignment =
-                        mir_unalignment(info.signed, info.bitsize);
+                    let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let unalignment = mir_unalignment(info.signed, info.bitsize);
 
                     let sum = mir.gen_not(ty, lhs);
                     if let Some((signed, bits)) = unalignment {
@@ -1722,14 +1443,9 @@ impl<'a> MirBuilder<'a> {
                     let lhs = data.unwrap().as_u32();
                     let lhs = mapping.get(&mut mir, lhs).unwrap().0;
 
-                    let info = self
-                        .intern_pool()
-                        .size_of_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
-                    let unalignment =
-                        mir_unalignment(info.signed, info.bitsize);
+                    let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let unalignment = mir_unalignment(info.signed, info.bitsize);
 
                     let sum = mir.gen_negate(ty, lhs);
                     if let Some((signed, bits)) = unalignment {
@@ -1742,23 +1458,17 @@ impl<'a> MirBuilder<'a> {
                     let lhs = data.unwrap().as_u32();
                     let lhs = mapping.get(&mut mir, lhs).unwrap().0;
 
-                    let to_info = self
-                        .intern_pool()
-                        .size_of_type(to, AMD64_POINTER_TYPE_INFO);
-                    let to_ty = self
-                        .intern_pool()
-                        .to_mir_type(to, AMD64_POINTER_TYPE_INFO);
-                    let to_unalignment =
-                        mir_unalignment(to_info.signed, to_info.bitsize);
+                    let to_info = self.intern_pool().size_of_type(to, AMD64_POINTER_TYPE_INFO);
+                    let to_ty = self.intern_pool().to_mir_type(to, AMD64_POINTER_TYPE_INFO);
+                    let _to_unalignment = mir_unalignment(to_info.signed, to_info.bitsize);
 
                     let from_info = self
                         .intern_pool()
                         .size_of_type(from, AMD64_POINTER_TYPE_INFO);
-                    let from_ty = self
+                    let _from_ty = self
                         .intern_pool()
                         .to_mir_type(from, AMD64_POINTER_TYPE_INFO);
-                    let from_unalignment =
-                        mir_unalignment(from_info.signed, from_info.bitsize);
+                    let _from_unalignment = mir_unalignment(from_info.signed, from_info.bitsize);
 
                     if from == to {
                         lhs
@@ -1776,12 +1486,7 @@ impl<'a> MirBuilder<'a> {
                         let one = mir.gen_u8(0b1);
                         mir.gen_bitand(mir::Type::Byte, lhs, one)
                     } else if from_info.bitsize > to_info.bitsize {
-                        mir.gen_truncate_integer(
-                            lhs,
-                            to_ty,
-                            to_info.signed,
-                            to_info.bitsize as u16,
-                        )
+                        mir.gen_truncate_integer(lhs, to_ty, to_info.signed, to_info.bitsize as u16)
                     } else if from_info.bitsize < to_info.bitsize {
                         mir.gen_extend_integer(lhs, from_info, to_info)
                     } else {
@@ -1793,9 +1498,7 @@ impl<'a> MirBuilder<'a> {
                     let src = data.unwrap().as_u32();
                     let src = mapping.get(&mut mir, src).unwrap().0;
 
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
 
                     mir.gen_ret_val(ty, src)
                 }
@@ -1808,18 +1511,13 @@ impl<'a> MirBuilder<'a> {
                     let label = match mapping.get(&mut mir, label) {
                         Some(label) => label.0,
                         None => {
-                            unresolved_jumps_branches.insert((
-                                label,
-                                LeftRight::Left(mir::NodeRef(jmp)),
-                            ));
+                            unresolved_jumps_branches
+                                .insert((label, LeftRight::Left(mir::NodeRef(jmp))));
                             0
                         }
                     };
 
-                    mir.set_node_data(
-                        mir::NodeRef(jmp),
-                        mir::Data::node(label),
-                    );
+                    mir.set_node_data(mir::NodeRef(jmp), mir::Data::node(label));
 
                     jmp
                 }
@@ -1832,28 +1530,21 @@ impl<'a> MirBuilder<'a> {
                     let lhs = match mapping.get(&mut mir, lhs) {
                         Some(n) => n.0,
                         None => {
-                            unresolved_jumps_branches.insert((
-                                lhs,
-                                LeftRight::Left(mir::NodeRef(br)),
-                            ));
+                            unresolved_jumps_branches
+                                .insert((lhs, LeftRight::Left(mir::NodeRef(br))));
                             0
                         }
                     };
                     let rhs = match mapping.get(&mut mir, rhs) {
                         Some(n) => n.0,
                         None => {
-                            unresolved_jumps_branches.insert((
-                                rhs,
-                                LeftRight::Right(mir::NodeRef(br)),
-                            ));
+                            unresolved_jumps_branches
+                                .insert((rhs, LeftRight::Right(mir::NodeRef(br))));
                             0
                         }
                     };
 
-                    mir.set_node_data(
-                        mir::NodeRef(br),
-                        mir::Data::binary(lhs, rhs),
-                    );
+                    mir.set_node_data(mir::NodeRef(br), mir::Data::binary(lhs, rhs));
 
                     br
                 }
@@ -1864,16 +1555,12 @@ impl<'a> MirBuilder<'a> {
                     let (start, end) = data.unwrap().as_lhs_rhs();
 
                     variant!(&ir.nodes[end as usize -1] => Inst::InlineType(ty));
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(*ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(*ty, AMD64_POINTER_TYPE_INFO);
 
                     let args = (start..(end - 1))
                         .map(|arg| {
                             variant!(&ir.nodes[arg as usize] => Inst::Argument(ty));
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(*ty, AMD64_POINTER_TYPE_INFO);
+                            let ty = self.intern_pool().to_mir_type(*ty, AMD64_POINTER_TYPE_INFO);
                             let arg = ir.data[arg as usize].unwrap().lhs;
                             let arg = mapping.get(&mut mir, arg).unwrap().0;
                             (ty, arg)
@@ -1886,16 +1573,12 @@ impl<'a> MirBuilder<'a> {
                     let (src, dst) = data.unwrap().as_lhs_rhs();
                     let lhs = mapping.get(&mut mir, src).unwrap().0;
                     let rhs = mapping.get(&mut mir, dst).unwrap().0;
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
 
                     mir.gen_phi2(ty, lhs, rhs)
                 }
                 Inst::GlobalConstant(name, ty) => {
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
                     let ext = mir.gen_extern(Some(ty), name);
 
                     ext
@@ -1904,16 +1587,12 @@ impl<'a> MirBuilder<'a> {
                     continue;
                 }
                 Inst::ExternRef(ty) => {
-                    let ty = self
-                        .intern_pool()
-                        .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                    let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
                     mir.gen_extern(Some(ty), data.unwrap().as_index())
                 }
                 #[allow(unreachable_patterns)]
                 _ => {
-                    eprintln!(
-                        "ir inst {inst:?} not supported in mir translation"
-                    );
+                    eprintln!("ir inst {inst:?} not supported in mir translation");
                     unimplemented!()
                 }
             };
@@ -1930,9 +1609,7 @@ impl<'a> MirBuilder<'a> {
                 break;
             };
             match inst {
-                Inst::FunctionStart => {
-                    self.build_function(data.unwrap().as_index())
-                }
+                Inst::FunctionStart => self.build_function(data.unwrap().as_index()),
                 Inst::GlobalConstant(name, ..) => {
                     let mut mir = mir::Mir::new(name);
                     let value = data.unwrap().lhs;
@@ -1941,9 +1618,8 @@ impl<'a> MirBuilder<'a> {
                     let _value = match inst {
                         Inst::Constant => {
                             let (ty, val) = data.unwrap().as_index_index();
-                            let mir_ty = self
-                                .intern_pool()
-                                .to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
+                            let mir_ty =
+                                self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO);
                             mir.push_const(self.intern_pool(), val, mir_ty)
                         }
                         _ => {
@@ -1982,7 +1658,7 @@ fn u10(x: i10) -> i10 {
         tree.render(&mut buf).unwrap();
         println!("AST:\n{buf}");
 
-        let mut intern = InternPool::new();
+        let mut _intern = InternPool::new();
         let mut ir = IR::new();
         {
             let builder = ir.build(&mut tree);