Commit 836d8a1f64

Andrew Kelley <andrew@ziglang.org>
2023-05-04 03:11:07
stage2: move most simple types to InternPool
1 parent bcd4bb8
src/arch/aarch64/CodeGen.zig
@@ -3071,7 +3071,7 @@ fn errUnionErr(
     const mod = self.bin_file.options.module.?;
     const err_ty = error_union_ty.errorUnionSet();
     const payload_ty = error_union_ty.errorUnionPayload();
-    if (err_ty.errorSetIsEmpty()) {
+    if (err_ty.errorSetIsEmpty(mod)) {
         return MCValue{ .immediate = 0 };
     }
     if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
@@ -3151,7 +3151,7 @@ fn errUnionPayload(
     const mod = self.bin_file.options.module.?;
     const err_ty = error_union_ty.errorUnionSet();
     const payload_ty = error_union_ty.errorUnionPayload();
-    if (err_ty.errorSetIsEmpty()) {
+    if (err_ty.errorSetIsEmpty(mod)) {
         return try error_union_bind.resolveToMcv(self);
     }
     if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
@@ -4905,9 +4905,10 @@ fn isErr(
     error_union_bind: ReadArg.Bind,
     error_union_ty: Type,
 ) !MCValue {
+    const mod = self.bin_file.options.module.?;
     const error_type = error_union_ty.errorUnionSet();
 
-    if (error_type.errorSetIsEmpty()) {
+    if (error_type.errorSetIsEmpty(mod)) {
         return MCValue{ .immediate = 0 }; // always false
     }
 
src/arch/arm/CodeGen.zig
@@ -2047,7 +2047,7 @@ fn errUnionErr(
     const mod = self.bin_file.options.module.?;
     const err_ty = error_union_ty.errorUnionSet();
     const payload_ty = error_union_ty.errorUnionPayload();
-    if (err_ty.errorSetIsEmpty()) {
+    if (err_ty.errorSetIsEmpty(mod)) {
         return MCValue{ .immediate = 0 };
     }
     if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
@@ -2124,7 +2124,7 @@ fn errUnionPayload(
     const mod = self.bin_file.options.module.?;
     const err_ty = error_union_ty.errorUnionSet();
     const payload_ty = error_union_ty.errorUnionPayload();
-    if (err_ty.errorSetIsEmpty()) {
+    if (err_ty.errorSetIsEmpty(mod)) {
         return try error_union_bind.resolveToMcv(self);
     }
     if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
@@ -4882,9 +4882,10 @@ fn isErr(
     error_union_bind: ReadArg.Bind,
     error_union_ty: Type,
 ) !MCValue {
+    const mod = self.bin_file.options.module.?;
     const error_type = error_union_ty.errorUnionSet();
 
-    if (error_type.errorSetIsEmpty()) {
+    if (error_type.errorSetIsEmpty(mod)) {
         return MCValue{ .immediate = 0 }; // always false
     }
 
src/arch/sparc64/CodeGen.zig
@@ -3530,7 +3530,7 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type)
     const mod = self.bin_file.options.module.?;
     const err_ty = error_union_ty.errorUnionSet();
     const payload_ty = error_union_ty.errorUnionPayload();
-    if (err_ty.errorSetIsEmpty()) {
+    if (err_ty.errorSetIsEmpty(mod)) {
         return error_union_mcv;
     }
     if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
src/arch/wasm/CodeGen.zig
@@ -1036,8 +1036,8 @@ fn genValtype(ty: Type, mod: *Module) u8 {
 /// Differently from `genValtype` this also allows `void` to create a block
 /// with no return type
 fn genBlockType(ty: Type, mod: *Module) u8 {
-    return switch (ty.tag()) {
-        .void, .noreturn => wasm.block_empty,
+    return switch (ty.ip_index) {
+        .void_type, .noreturn_type => wasm.block_empty,
         else => genValtype(ty, mod),
     };
 }
@@ -3948,7 +3948,7 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro
     const pl_ty = err_union_ty.errorUnionPayload();
 
     const result = result: {
-        if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
+        if (err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {
             switch (opcode) {
                 .i32_ne => break :result WValue{ .imm32 = 0 },
                 .i32_eq => break :result WValue{ .imm32 = 1 },
@@ -4013,7 +4013,7 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
     const payload_ty = err_ty.errorUnionPayload();
 
     const result = result: {
-        if (err_ty.errorUnionSet().errorSetIsEmpty()) {
+        if (err_ty.errorUnionSet().errorSetIsEmpty(mod)) {
             break :result WValue{ .imm32 = 0 };
         }
 
@@ -6214,7 +6214,7 @@ fn lowerTry(
     const pl_ty = err_union_ty.errorUnionPayload();
     const pl_has_bits = pl_ty.hasRuntimeBitsIgnoreComptime(mod);
 
-    if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
+    if (!err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {
         // Block we can jump out of when error is not set
         try func.startBlock(.block, wasm.block_empty);
 
src/arch/x86_64/CodeGen.zig
@@ -3624,7 +3624,7 @@ fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
     const operand = try self.resolveInst(ty_op.operand);
 
     const result: MCValue = result: {
-        if (err_ty.errorSetIsEmpty()) {
+        if (err_ty.errorSetIsEmpty(mod)) {
             break :result MCValue{ .immediate = 0 };
         }
 
@@ -5811,7 +5811,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:
     switch (tag) {
         .not => {
             const limb_abi_size = @intCast(u16, @min(src_ty.abiSize(mod), 8));
-            const int_info = if (src_ty.tag() == .bool)
+            const int_info = if (src_ty.ip_index == .bool_type)
                 std.builtin.Type.Int{ .signedness = .unsigned, .bits = 1 }
             else
                 src_ty.intInfo(mod);
@@ -8716,7 +8716,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
                 try self.asmRegisterRegister(.{ ._, .@"test" }, alias_reg, alias_reg);
                 return .{ .eflags = .z };
             }
-            assert(some_info.ty.tag() == .bool);
+            assert(some_info.ty.ip_index == .bool_type);
             const opt_abi_size = @intCast(u32, opt_ty.abiSize(mod));
             try self.asmRegisterImmediate(
                 .{ ._, .bt },
@@ -8808,7 +8808,7 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, ty: Type, operand: MCValue) !
     const mod = self.bin_file.options.module.?;
     const err_type = ty.errorUnionSet();
 
-    if (err_type.errorSetIsEmpty()) {
+    if (err_type.errorSetIsEmpty(mod)) {
         return MCValue{ .immediate = 0 }; // always false
     }
 
src/codegen/c.zig
@@ -1508,7 +1508,7 @@ pub const DeclGen = struct {
         }
         if (fn_decl.val.castTag(.function)) |func_payload|
             if (func_payload.data.is_cold) try w.writeAll("zig_cold ");
-        if (fn_info.return_type.tag() == .noreturn) try w.writeAll("zig_noreturn ");
+        if (fn_info.return_type.ip_index == .noreturn_type) try w.writeAll("zig_noreturn ");
 
         const trailing = try renderTypePrefix(
             dg.decl_index,
@@ -3783,7 +3783,7 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue {
     const ty_op = f.air.instructions.items(.data)[inst].ty_op;
     const operand_ty = f.typeOf(ty_op.operand);
     const scalar_ty = operand_ty.scalarType(mod);
-    if (scalar_ty.tag() != .bool) return try airUnBuiltinCall(f, inst, "not", .bits);
+    if (scalar_ty.ip_index != .bool_type) return try airUnBuiltinCall(f, inst, "not", .bits);
 
     const op = try f.resolveInst(ty_op.operand);
     try reap(f, inst, &.{ty_op.operand});
@@ -4292,7 +4292,7 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue {
     const writer = f.object.writer();
 
     const inst_ty = f.typeOfIndex(inst);
-    const result = if (inst_ty.tag() != .void and !f.liveness.isUnused(inst))
+    const result = if (inst_ty.ip_index != .void_type and !f.liveness.isUnused(inst))
         try f.allocLocal(inst, inst_ty)
     else
         .none;
@@ -4354,7 +4354,7 @@ fn lowerTry(
     const payload_ty = err_union_ty.errorUnionPayload();
     const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);
 
-    if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
+    if (!err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {
         try writer.writeAll("if (");
         if (!payload_has_bits) {
             if (is_ptr)
@@ -5549,7 +5549,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
     if (!payload_ty.hasRuntimeBits(mod)) {
         try f.writeCValue(writer, operand, .Other);
     } else {
-        if (!error_ty.errorSetIsEmpty())
+        if (!error_ty.errorSetIsEmpty(mod))
             if (operand_is_ptr)
                 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })
             else
@@ -5768,7 +5768,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
     try f.writeCValue(writer, local, .Other);
     try writer.writeAll(" = ");
 
-    if (!error_ty.errorSetIsEmpty())
+    if (!error_ty.errorSetIsEmpty(mod))
         if (payload_ty.hasRuntimeBits(mod))
             if (is_ptr)
                 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })
@@ -6032,7 +6032,7 @@ fn airCmpBuiltinCall(
     try writer.writeByte(')');
     if (!ref_ret) try writer.print(" {s} {}", .{
         compareOperatorC(operator),
-        try f.fmtIntLiteral(Type.initTag(.i32), Value.zero),
+        try f.fmtIntLiteral(Type.i32, Value.zero),
     });
     try writer.writeAll(";\n");
     try v.end(f, inst, writer);
@@ -7749,7 +7749,7 @@ const LowerFnRetTyBuffer = struct {
     payload: Type.Payload.AnonStruct,
 };
 fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, mod: *const Module) Type {
-    if (ret_ty.zigTypeTag(mod) == .NoReturn) return Type.initTag(.noreturn);
+    if (ret_ty.zigTypeTag(mod) == .NoReturn) return Type.noreturn;
 
     if (lowersToArray(ret_ty, mod)) {
         buffer.names = [1][]const u8{"array"};
src/codegen/llvm.zig
@@ -1730,7 +1730,7 @@ pub const Object = struct {
                 return ptr_di_ty;
             },
             .Opaque => {
-                if (ty.tag() == .anyopaque) {
+                if (ty.ip_index == .anyopaque_type) {
                     const di_ty = dib.createBasicType("anyopaque", 0, DW.ATE.signed);
                     gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
                     return di_ty;
@@ -2847,25 +2847,23 @@ pub const DeclGen = struct {
                 const llvm_addrspace = toLlvmAddressSpace(ptr_info.@"addrspace", target);
                 return dg.context.pointerType(llvm_addrspace);
             },
-            .Opaque => switch (t.tag()) {
-                .@"opaque" => {
-                    const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = dg.module });
-                    if (gop.found_existing) return gop.value_ptr.*;
+            .Opaque => {
+                if (t.ip_index == .anyopaque_type) return dg.context.intType(8);
 
-                    // The Type memory is ephemeral; since we want to store a longer-lived
-                    // reference, we need to copy it here.
-                    gop.key_ptr.* = try t.copy(dg.object.type_map_arena.allocator());
+                const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = dg.module });
+                if (gop.found_existing) return gop.value_ptr.*;
 
-                    const opaque_obj = t.castTag(.@"opaque").?.data;
-                    const name = try opaque_obj.getFullyQualifiedName(dg.module);
-                    defer gpa.free(name);
+                // The Type memory is ephemeral; since we want to store a longer-lived
+                // reference, we need to copy it here.
+                gop.key_ptr.* = try t.copy(dg.object.type_map_arena.allocator());
 
-                    const llvm_struct_ty = dg.context.structCreateNamed(name);
-                    gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls
-                    return llvm_struct_ty;
-                },
-                .anyopaque => return dg.context.intType(8),
-                else => unreachable,
+                const opaque_obj = t.castTag(.@"opaque").?.data;
+                const name = try opaque_obj.getFullyQualifiedName(dg.module);
+                defer gpa.free(name);
+
+                const llvm_struct_ty = dg.context.structCreateNamed(name);
+                gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls
+                return llvm_struct_ty;
             },
             .Array => {
                 const elem_ty = t.childType();
@@ -5531,7 +5529,7 @@ pub const FuncGen = struct {
         const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);
         const err_union_llvm_ty = try fg.dg.lowerType(err_union_ty);
 
-        if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
+        if (!err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {
             const is_err = err: {
                 const err_set_ty = try fg.dg.lowerType(Type.anyerror);
                 const zero = err_set_ty.constNull();
@@ -6715,7 +6713,7 @@ pub const FuncGen = struct {
         const err_set_ty = try self.dg.lowerType(Type.anyerror);
         const zero = err_set_ty.constNull();
 
-        if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
+        if (err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {
             const llvm_i1 = self.context.intType(1);
             switch (op) {
                 .EQ => return llvm_i1.constInt(1, .False), // 0 == 0
@@ -6864,7 +6862,7 @@ pub const FuncGen = struct {
         const operand = try self.resolveInst(ty_op.operand);
         const operand_ty = self.typeOf(ty_op.operand);
         const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
-        if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
+        if (err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {
             const err_llvm_ty = try self.dg.lowerType(Type.anyerror);
             if (operand_is_ptr) {
                 return operand;
src/codegen/spirv.zig
@@ -2849,6 +2849,7 @@ pub const DeclGen = struct {
     }
 
     fn airTry(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
+        const mod = self.module;
         const pl_op = self.air.instructions.items(.data)[inst].pl_op;
         const err_union_id = try self.resolve(pl_op.operand);
         const extra = self.air.extraData(Air.Try, pl_op.payload);
@@ -2862,7 +2863,7 @@ pub const DeclGen = struct {
 
         const eu_layout = self.errorUnionLayout(payload_ty);
 
-        if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) {
+        if (!err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {
             const err_id = if (eu_layout.payload_has_bits)
                 try self.extractField(Type.anyerror, err_union_id, eu_layout.errorFieldIndex())
             else
@@ -2910,12 +2911,13 @@ pub const DeclGen = struct {
     fn airErrUnionErr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
         if (self.liveness.isUnused(inst)) return null;
 
+        const mod = self.module;
         const ty_op = self.air.instructions.items(.data)[inst].ty_op;
         const operand_id = try self.resolve(ty_op.operand);
         const err_union_ty = self.typeOf(ty_op.operand);
         const err_ty_ref = try self.resolveType(Type.anyerror, .direct);
 
-        if (err_union_ty.errorUnionSet().errorSetIsEmpty()) {
+        if (err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) {
             // No error possible, so just return undefined.
             return try self.spv.constUndef(err_ty_ref);
         }
src/Air.zig
@@ -1333,7 +1333,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: InternPool) Type {
         .ret_load,
         .unreach,
         .trap,
-        => return Type.initTag(.noreturn),
+        => return Type.noreturn,
 
         .breakpoint,
         .dbg_stmt,
@@ -1370,7 +1370,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: InternPool) Type {
         .wasm_memory_grow => return Type.i32,
         .wasm_memory_size => return Type.u32,
 
-        .bool_to_int => return Type.initTag(.u1),
+        .bool_to_int => return Type.u1,
 
         .tag_name, .error_name => return Type.initTag(.const_slice_u8_sentinel_0),
 
src/Module.zig
@@ -1005,7 +1005,7 @@ pub const Struct = struct {
     /// If the layout is packed, this is the backing integer type of the packed struct.
     /// Whether zig chooses this type or the user specifies it, it is stored here.
     /// This will be set to the noreturn type until status is `have_layout`.
-    backing_int_ty: Type = Type.initTag(.noreturn),
+    backing_int_ty: Type = Type.noreturn,
     status: enum {
         none,
         field_types_wip,
@@ -1705,31 +1705,34 @@ pub const Fn = struct {
         is_resolved: bool = false,
 
         pub fn addErrorSet(self: *InferredErrorSet, gpa: Allocator, err_set_ty: Type) !void {
-            switch (err_set_ty.tag()) {
-                .error_set => {
-                    const names = err_set_ty.castTag(.error_set).?.data.names.keys();
-                    for (names) |name| {
-                        try self.errors.put(gpa, name, {});
-                    }
-                },
-                .error_set_single => {
-                    const name = err_set_ty.castTag(.error_set_single).?.data;
-                    try self.errors.put(gpa, name, {});
-                },
-                .error_set_inferred => {
-                    const ies = err_set_ty.castTag(.error_set_inferred).?.data;
-                    try self.inferred_error_sets.put(gpa, ies, {});
+            switch (err_set_ty.ip_index) {
+                .anyerror_type => {
+                    self.is_anyerror = true;
                 },
-                .error_set_merged => {
-                    const names = err_set_ty.castTag(.error_set_merged).?.data.keys();
-                    for (names) |name| {
+                .none => switch (err_set_ty.tag()) {
+                    .error_set => {
+                        const names = err_set_ty.castTag(.error_set).?.data.names.keys();
+                        for (names) |name| {
+                            try self.errors.put(gpa, name, {});
+                        }
+                    },
+                    .error_set_single => {
+                        const name = err_set_ty.castTag(.error_set_single).?.data;
                         try self.errors.put(gpa, name, {});
-                    }
-                },
-                .anyerror => {
-                    self.is_anyerror = true;
+                    },
+                    .error_set_inferred => {
+                        const ies = err_set_ty.castTag(.error_set_inferred).?.data;
+                        try self.inferred_error_sets.put(gpa, ies, {});
+                    },
+                    .error_set_merged => {
+                        const names = err_set_ty.castTag(.error_set_merged).?.data.keys();
+                        for (names) |name| {
+                            try self.errors.put(gpa, name, {});
+                        }
+                    },
+                    else => unreachable,
                 },
-                else => unreachable,
+                else => @panic("TODO"),
             }
         }
     };
@@ -4566,7 +4569,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
     const struct_obj = try new_decl_arena_allocator.create(Module.Struct);
     const struct_ty = try Type.Tag.@"struct".create(new_decl_arena_allocator, struct_obj);
     const struct_val = try Value.Tag.ty.create(new_decl_arena_allocator, struct_ty);
-    const ty_ty = comptime Type.initTag(.type);
+    const ty_ty = comptime Type.type;
     struct_obj.* = .{
         .owner_decl = undefined, // set below
         .fields = .{},
src/print_air.zig
@@ -370,7 +370,6 @@ const Writer = struct {
         switch (t) {
             .inferred_alloc_const => try s.writeAll("(inferred_alloc_const)"),
             .inferred_alloc_mut => try s.writeAll("(inferred_alloc_mut)"),
-            .generic_poison => try s.writeAll("(generic_poison)"),
             else => try ty.print(s, w.module),
         }
     }
src/Sema.zig
@@ -1776,7 +1776,7 @@ fn analyzeAsType(
     src: LazySrcLoc,
     air_inst: Air.Inst.Ref,
 ) !Type {
-    const wanted_type = Type.initTag(.type);
+    const wanted_type = Type.type;
     const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src);
     const val = try sema.resolveConstValue(block, src, coerced_inst, "types must be comptime-known");
     const ty = val.toType();
@@ -3132,7 +3132,7 @@ fn zirUnionDecl(
     errdefer mod.abortAnonDecl(new_decl_index);
     union_obj.* = .{
         .owner_decl = new_decl_index,
-        .tag_ty = Type.initTag(.null),
+        .tag_ty = Type.null,
         .fields = .{},
         .zir_index = inst,
         .layout = small.layout,
@@ -6362,7 +6362,7 @@ fn zirCall(
             if (arg_index >= fn_params_len)
                 break :inst Air.Inst.Ref.var_args_param_type;
 
-            if (func_ty_info.param_types[arg_index].tag() == .generic_poison)
+            if (func_ty_info.param_types[arg_index].isGenericPoison())
                 break :inst Air.Inst.Ref.generic_poison_type;
 
             break :inst try sema.addType(func_ty_info.param_types[arg_index]);
@@ -8175,7 +8175,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
         return sema.fail(block, rhs_src, "expected error set type, found '{}'", .{rhs_ty.fmt(sema.mod)});
 
     // Anything merged with anyerror is anyerror.
-    if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror) {
+    if (lhs_ty.ip_index == .anyerror_type or rhs_ty.ip_index == .anyerror_type) {
         return Air.Inst.Ref.anyerror_type;
     }
 
@@ -8206,7 +8206,7 @@ fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
     const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
     const duped_name = try sema.arena.dupe(u8, inst_data.get(sema.code));
     return sema.addConstant(
-        Type.initTag(.enum_literal),
+        .{ .ip_index = .enum_literal_type, .legacy = undefined },
         try Value.Tag.enum_literal.create(sema.arena, duped_name),
     );
 }
@@ -8503,6 +8503,7 @@ fn analyzeErrUnionPayload(
     operand_src: LazySrcLoc,
     safety_check: bool,
 ) CompileError!Air.Inst.Ref {
+    const mod = sema.mod;
     const payload_ty = err_union_ty.errorUnionPayload();
     if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {
         if (val.getError()) |name| {
@@ -8516,7 +8517,7 @@ fn analyzeErrUnionPayload(
 
     // If the error set has no fields then no safety check is needed.
     if (safety_check and block.wantSafety() and
-        !err_union_ty.errorUnionSet().errorSetIsEmpty())
+        !err_union_ty.errorUnionSet().errorSetIsEmpty(mod))
     {
         try sema.panicUnwrapError(block, operand, .unwrap_errunion_err, .is_non_err);
     }
@@ -8602,7 +8603,7 @@ fn analyzeErrUnionPayloadPtr(
 
     // If the error set has no fields then no safety check is needed.
     if (safety_check and block.wantSafety() and
-        !err_union_ty.errorUnionSet().errorSetIsEmpty())
+        !err_union_ty.errorUnionSet().errorSetIsEmpty(mod))
     {
         try sema.panicUnwrapError(block, operand, .unwrap_errunion_err_ptr, .is_non_err_ptr);
     }
@@ -8701,7 +8702,7 @@ fn zirFunc(
                 break :blk ret_ty;
             } else |err| switch (err) {
                 error.GenericPoison => {
-                    break :blk Type.initTag(.generic_poison);
+                    break :blk Type.generic_poison;
                 },
                 else => |e| return e,
             }
@@ -8778,7 +8779,7 @@ fn resolveGenericBody(
     };
     switch (err) {
         error.GenericPoison => {
-            if (dest_ty.tag() == .type) {
+            if (dest_ty.ip_index == .type_type) {
                 return Value.initTag(.generic_poison_type);
             } else {
                 return Value.initTag(.generic_poison);
@@ -9319,7 +9320,7 @@ fn zirParam(
                 // We result the param instruction with a poison value and
                 // insert an anytype parameter.
                 try block.params.append(sema.gpa, .{
-                    .ty = Type.initTag(.generic_poison),
+                    .ty = Type.generic_poison,
                     .is_comptime = comptime_syntax,
                     .name = param_name,
                 });
@@ -9340,7 +9341,7 @@ fn zirParam(
             // We result the param instruction with a poison value and
             // insert an anytype parameter.
             try block.params.append(sema.gpa, .{
-                .ty = Type.initTag(.generic_poison),
+                .ty = Type.generic_poison,
                 .is_comptime = comptime_syntax,
                 .name = param_name,
             });
@@ -9438,7 +9439,7 @@ fn zirParamAnytype(
     // We are evaluating a generic function without any comptime args provided.
 
     try block.params.append(sema.gpa, .{
-        .ty = Type.initTag(.generic_poison),
+        .ty = Type.generic_poison,
         .is_comptime = comptime_syntax,
         .name = param_name,
     });
@@ -18877,7 +18878,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
         },
         .ErrorSet => {
             const payload_val = union_val.val.optionalValue(mod) orelse
-                return sema.addType(Type.initTag(.anyerror));
+                return sema.addType(Type.anyerror);
             const slice_val = payload_val.castTag(.slice).?.data;
 
             const len = try sema.usizeCast(block, src, slice_val.len.toUnsignedInt(mod));
@@ -19150,7 +19151,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
             errdefer mod.abortAnonDecl(new_decl_index);
             union_obj.* = .{
                 .owner_decl = new_decl_index,
-                .tag_ty = Type.initTag(.null),
+                .tag_ty = Type.null,
                 .fields = .{},
                 .zir_index = inst,
                 .layout = layout,
@@ -22697,7 +22698,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
         extra_index += 1;
         const ret_ty_tv = sema.resolveInstConst(block, ret_src, ret_ty_ref, "return type must be comptime-known") catch |err| switch (err) {
             error.GenericPoison => {
-                break :blk Type.initTag(.generic_poison);
+                break :blk Type.generic_poison;
             },
             else => |e| return e,
         };
@@ -23022,7 +23023,7 @@ fn zirBuiltinExtern(
         new_decl.src_line = sema.owner_decl.src_line;
         // We only access this decl through the decl_ref with the correct type created
         // below, so this type doesn't matter
-        new_decl.ty = Type.Tag.init(.anyopaque);
+        new_decl.ty = Type.anyopaque;
         new_decl.val = try Value.Tag.variable.create(new_decl_arena_allocator, new_var);
         new_decl.@"align" = 0;
         new_decl.@"linksection" = null;
@@ -24380,9 +24381,8 @@ fn fieldCallBind(
                         decl_type.fnParamLen() >= 1)
                     {
                         const first_param_type = decl_type.fnParamType(0);
-                        const first_param_tag = first_param_type.tag();
                         // zig fmt: off
-                        if (first_param_tag == .generic_poison or (
+                        if (first_param_type.isGenericPoison() or (
                                 first_param_type.zigTypeTag(mod) == .Pointer and
                                 (first_param_type.ptrSize() == .One or
                                 first_param_type.ptrSize() == .C) and
@@ -25535,10 +25535,7 @@ fn coerceExtra(
     inst_src: LazySrcLoc,
     opts: CoerceOpts,
 ) CoersionError!Air.Inst.Ref {
-    switch (dest_ty_unresolved.tag()) {
-        .generic_poison => return inst,
-        else => {},
-    }
+    if (dest_ty_unresolved.isGenericPoison()) return inst;
     const dest_ty_src = inst_src; // TODO better source location
     const dest_ty = try sema.resolveTypeFields(dest_ty_unresolved);
     const inst_ty = try sema.resolveTypeFields(sema.typeOf(inst));
@@ -25577,7 +25574,8 @@ fn coerceExtra(
 
             // cast from ?*T and ?[*]T to ?*anyopaque
             // but don't do it if the source type is a double pointer
-            if (dest_ty.isPtrLikeOptional(mod) and dest_ty.elemType2(mod).tag() == .anyopaque and
+            if (dest_ty.isPtrLikeOptional(mod) and
+                dest_ty.elemType2(mod).ip_index == .anyopaque_type and
                 inst_ty.isPtrAtRuntime(mod))
             anyopaque_check: {
                 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :optional;
@@ -25715,7 +25713,7 @@ fn coerceExtra(
 
             // cast from *T and [*]T to *anyopaque
             // but don't do it if the source type is a double pointer
-            if (dest_info.pointee_type.tag() == .anyopaque and inst_ty.zigTypeTag(mod) == .Pointer) to_anyopaque: {
+            if (dest_info.pointee_type.ip_index == .anyopaque_type and inst_ty.zigTypeTag(mod) == .Pointer) to_anyopaque: {
                 if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
                 const elem_ty = inst_ty.elemType2(mod);
                 if (elem_ty.zigTypeTag(mod) == .Pointer or elem_ty.isPtrLikeOptional(mod)) {
@@ -26759,6 +26757,8 @@ fn coerceInMemoryAllowedErrorSets(
     dest_src: LazySrcLoc,
     src_src: LazySrcLoc,
 ) !InMemoryCoercionResult {
+    const mod = sema.mod;
+
     // Coercion to `anyerror`. Note that this check can return false negatives
     // in case the error sets did not get resolved.
     if (dest_ty.isAnyError()) {
@@ -26769,36 +26769,41 @@ fn coerceInMemoryAllowedErrorSets(
         const dst_ies = dst_payload.data;
         // We will make an effort to return `ok` without resolving either error set, to
         // avoid unnecessary "unable to resolve error set" dependency loop errors.
-        switch (src_ty.tag()) {
-            .error_set_inferred => {
-                // If both are inferred error sets of functions, and
-                // the dest includes the source function, the coercion is OK.
-                // This check is important because it works without forcing a full resolution
-                // of inferred error sets.
-                const src_ies = src_ty.castTag(.error_set_inferred).?.data;
-
-                if (dst_ies.inferred_error_sets.contains(src_ies)) {
-                    return .ok;
-                }
-            },
-            .error_set_single => {
-                const name = src_ty.castTag(.error_set_single).?.data;
-                if (dst_ies.errors.contains(name)) return .ok;
-            },
-            .error_set_merged => {
-                const names = src_ty.castTag(.error_set_merged).?.data.keys();
-                for (names) |name| {
-                    if (!dst_ies.errors.contains(name)) break;
-                } else return .ok;
+        switch (src_ty.ip_index) {
+            .none => switch (src_ty.tag()) {
+                .error_set_inferred => {
+                    // If both are inferred error sets of functions, and
+                    // the dest includes the source function, the coercion is OK.
+                    // This check is important because it works without forcing a full resolution
+                    // of inferred error sets.
+                    const src_ies = src_ty.castTag(.error_set_inferred).?.data;
+
+                    if (dst_ies.inferred_error_sets.contains(src_ies)) {
+                        return .ok;
+                    }
+                },
+                .error_set_single => {
+                    const name = src_ty.castTag(.error_set_single).?.data;
+                    if (dst_ies.errors.contains(name)) return .ok;
+                },
+                .error_set_merged => {
+                    const names = src_ty.castTag(.error_set_merged).?.data.keys();
+                    for (names) |name| {
+                        if (!dst_ies.errors.contains(name)) break;
+                    } else return .ok;
+                },
+                .error_set => {
+                    const names = src_ty.castTag(.error_set).?.data.names.keys();
+                    for (names) |name| {
+                        if (!dst_ies.errors.contains(name)) break;
+                    } else return .ok;
+                },
+                else => unreachable,
             },
-            .error_set => {
-                const names = src_ty.castTag(.error_set).?.data.names.keys();
-                for (names) |name| {
-                    if (!dst_ies.errors.contains(name)) break;
-                } else return .ok;
+            .anyerror_type => {},
+            else => switch (mod.intern_pool.indexToKey(src_ty.ip_index)) {
+                else => @panic("TODO"),
             },
-            .anyerror => {},
-            else => unreachable,
         }
 
         if (dst_ies.func == sema.owner_func) {
@@ -26818,79 +26823,87 @@ fn coerceInMemoryAllowedErrorSets(
     var missing_error_buf = std.ArrayList([]const u8).init(sema.gpa);
     defer missing_error_buf.deinit();
 
-    switch (src_ty.tag()) {
-        .error_set_inferred => {
-            const src_data = src_ty.castTag(.error_set_inferred).?.data;
+    switch (src_ty.ip_index) {
+        .none => switch (src_ty.tag()) {
+            .error_set_inferred => {
+                const src_data = src_ty.castTag(.error_set_inferred).?.data;
 
-            try sema.resolveInferredErrorSet(block, src_src, src_data);
-            // src anyerror status might have changed after the resolution.
-            if (src_ty.isAnyError()) {
-                // dest_ty.isAnyError() == true is already checked for at this point.
-                return .from_anyerror;
-            }
+                try sema.resolveInferredErrorSet(block, src_src, src_data);
+                // src anyerror status might have changed after the resolution.
+                if (src_ty.isAnyError()) {
+                    // dest_ty.isAnyError() == true is already checked for at this point.
+                    return .from_anyerror;
+                }
 
-            for (src_data.errors.keys()) |key| {
-                if (!dest_ty.errorSetHasField(key)) {
-                    try missing_error_buf.append(key);
+                for (src_data.errors.keys()) |key| {
+                    if (!dest_ty.errorSetHasField(key)) {
+                        try missing_error_buf.append(key);
+                    }
                 }
-            }
 
-            if (missing_error_buf.items.len != 0) {
-                return InMemoryCoercionResult{
-                    .missing_error = try sema.arena.dupe([]const u8, missing_error_buf.items),
-                };
-            }
+                if (missing_error_buf.items.len != 0) {
+                    return InMemoryCoercionResult{
+                        .missing_error = try sema.arena.dupe([]const u8, missing_error_buf.items),
+                    };
+                }
 
-            return .ok;
-        },
-        .error_set_single => {
-            const name = src_ty.castTag(.error_set_single).?.data;
-            if (dest_ty.errorSetHasField(name)) {
                 return .ok;
-            }
-            const list = try sema.arena.alloc([]const u8, 1);
-            list[0] = name;
-            return InMemoryCoercionResult{ .missing_error = list };
-        },
-        .error_set_merged => {
-            const names = src_ty.castTag(.error_set_merged).?.data.keys();
-            for (names) |name| {
-                if (!dest_ty.errorSetHasField(name)) {
-                    try missing_error_buf.append(name);
+            },
+            .error_set_single => {
+                const name = src_ty.castTag(.error_set_single).?.data;
+                if (dest_ty.errorSetHasField(name)) {
+                    return .ok;
+                }
+                const list = try sema.arena.alloc([]const u8, 1);
+                list[0] = name;
+                return InMemoryCoercionResult{ .missing_error = list };
+            },
+            .error_set_merged => {
+                const names = src_ty.castTag(.error_set_merged).?.data.keys();
+                for (names) |name| {
+                    if (!dest_ty.errorSetHasField(name)) {
+                        try missing_error_buf.append(name);
+                    }
                 }
-            }
 
-            if (missing_error_buf.items.len != 0) {
-                return InMemoryCoercionResult{
-                    .missing_error = try sema.arena.dupe([]const u8, missing_error_buf.items),
-                };
-            }
+                if (missing_error_buf.items.len != 0) {
+                    return InMemoryCoercionResult{
+                        .missing_error = try sema.arena.dupe([]const u8, missing_error_buf.items),
+                    };
+                }
 
-            return .ok;
-        },
-        .error_set => {
-            const names = src_ty.castTag(.error_set).?.data.names.keys();
-            for (names) |name| {
-                if (!dest_ty.errorSetHasField(name)) {
-                    try missing_error_buf.append(name);
+                return .ok;
+            },
+            .error_set => {
+                const names = src_ty.castTag(.error_set).?.data.names.keys();
+                for (names) |name| {
+                    if (!dest_ty.errorSetHasField(name)) {
+                        try missing_error_buf.append(name);
+                    }
                 }
-            }
 
-            if (missing_error_buf.items.len != 0) {
-                return InMemoryCoercionResult{
-                    .missing_error = try sema.arena.dupe([]const u8, missing_error_buf.items),
-                };
-            }
+                if (missing_error_buf.items.len != 0) {
+                    return InMemoryCoercionResult{
+                        .missing_error = try sema.arena.dupe([]const u8, missing_error_buf.items),
+                    };
+                }
 
-            return .ok;
-        },
-        .anyerror => switch (dest_ty.tag()) {
-            .error_set_inferred => unreachable, // Caught by dest_ty.isAnyError() above.
-            .error_set_single, .error_set_merged, .error_set => return .from_anyerror,
-            .anyerror => unreachable, // Filtered out above.
+                return .ok;
+            },
             else => unreachable,
         },
-        else => unreachable,
+
+        .anyerror_type => switch (dest_ty.ip_index) {
+            .none => switch (dest_ty.tag()) {
+                .error_set_inferred => unreachable, // Caught by dest_ty.isAnyError() above.
+                .error_set_single, .error_set_merged, .error_set => return .from_anyerror,
+                else => unreachable,
+            },
+            .anyerror_type => unreachable, // Filtered out above.
+            else => @panic("TODO"),
+        },
+
+        else => @panic("TODO"),
     }
 
     unreachable;
@@ -29355,42 +29368,49 @@ fn analyzeIsNonErrComptimeOnly(
     // exception if the error union error set is known to be empty,
     // we allow the comparison but always make it comptime-known.
     const set_ty = operand_ty.errorUnionSet();
-    switch (set_ty.tag()) {
-        .anyerror => {},
-        .error_set_inferred => blk: {
-            // If the error set is empty, we must return a comptime true or false.
-            // However we want to avoid unnecessarily resolving an inferred error set
-            // in case it is already non-empty.
-            const ies = set_ty.castTag(.error_set_inferred).?.data;
-            if (ies.is_anyerror) break :blk;
-            if (ies.errors.count() != 0) break :blk;
-            if (maybe_operand_val == null) {
-                // Try to avoid resolving inferred error set if possible.
-                if (ies.errors.count() != 0) break :blk;
+    switch (set_ty.ip_index) {
+        .none => switch (set_ty.tag()) {
+            .error_set_inferred => blk: {
+                // If the error set is empty, we must return a comptime true or false.
+                // However we want to avoid unnecessarily resolving an inferred error set
+                // in case it is already non-empty.
+                const ies = set_ty.castTag(.error_set_inferred).?.data;
                 if (ies.is_anyerror) break :blk;
-                for (ies.inferred_error_sets.keys()) |other_ies| {
-                    if (ies == other_ies) continue;
-                    try sema.resolveInferredErrorSet(block, src, other_ies);
-                    if (other_ies.is_anyerror) {
-                        ies.is_anyerror = true;
-                        ies.is_resolved = true;
-                        break :blk;
-                    }
+                if (ies.errors.count() != 0) break :blk;
+                if (maybe_operand_val == null) {
+                    // Try to avoid resolving inferred error set if possible.
+                    if (ies.errors.count() != 0) break :blk;
+                    if (ies.is_anyerror) break :blk;
+                    for (ies.inferred_error_sets.keys()) |other_ies| {
+                        if (ies == other_ies) continue;
+                        try sema.resolveInferredErrorSet(block, src, other_ies);
+                        if (other_ies.is_anyerror) {
+                            ies.is_anyerror = true;
+                            ies.is_resolved = true;
+                            break :blk;
+                        }
 
-                    if (other_ies.errors.count() != 0) break :blk;
-                }
-                if (ies.func == sema.owner_func) {
-                    // We're checking the inferred errorset of the current function and none of
-                    // its child inferred error sets contained any errors meaning that any value
-                    // so far with this type can't contain errors either.
-                    return Air.Inst.Ref.bool_true;
+                        if (other_ies.errors.count() != 0) break :blk;
+                    }
+                    if (ies.func == sema.owner_func) {
+                        // We're checking the inferred errorset of the current function and none of
+                        // its child inferred error sets contained any errors meaning that any value
+                        // so far with this type can't contain errors either.
+                        return Air.Inst.Ref.bool_true;
+                    }
+                    try sema.resolveInferredErrorSet(block, src, ies);
+                    if (ies.is_anyerror) break :blk;
+                    if (ies.errors.count() == 0) return Air.Inst.Ref.bool_true;
                 }
-                try sema.resolveInferredErrorSet(block, src, ies);
-                if (ies.is_anyerror) break :blk;
-                if (ies.errors.count() == 0) return Air.Inst.Ref.bool_true;
-            }
+            },
+            else => if (set_ty.errorSetNames().len == 0) return Air.Inst.Ref.bool_true,
+        },
+
+        .anyerror_type => {},
+
+        else => switch (mod.intern_pool.indexToKey(set_ty.ip_index)) {
+            else => @panic("TODO"),
         },
-        else => if (set_ty.errorSetNames().len == 0) return Air.Inst.Ref.bool_true,
     }
 
     if (maybe_operand_val) |err_union| {
@@ -30308,43 +30328,48 @@ fn wrapErrorUnionSet(
     const inst_ty = sema.typeOf(inst);
     const dest_err_set_ty = dest_ty.errorUnionSet();
     if (try sema.resolveMaybeUndefVal(inst)) |val| {
-        switch (dest_err_set_ty.tag()) {
-            .anyerror => {},
-            .error_set_single => ok: {
-                const expected_name = val.castTag(.@"error").?.data.name;
-                const n = dest_err_set_ty.castTag(.error_set_single).?.data;
-                if (mem.eql(u8, expected_name, n)) break :ok;
-                return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
-            },
-            .error_set => {
-                const expected_name = val.castTag(.@"error").?.data.name;
-                const error_set = dest_err_set_ty.castTag(.error_set).?.data;
-                if (!error_set.names.contains(expected_name)) {
+        switch (dest_err_set_ty.ip_index) {
+            .anyerror_type => {},
+
+            .none => switch (dest_err_set_ty.tag()) {
+                .error_set_single => ok: {
+                    const expected_name = val.castTag(.@"error").?.data.name;
+                    const n = dest_err_set_ty.castTag(.error_set_single).?.data;
+                    if (mem.eql(u8, expected_name, n)) break :ok;
                     return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
-                }
-            },
-            .error_set_inferred => ok: {
-                const expected_name = val.castTag(.@"error").?.data.name;
-                const ies = dest_err_set_ty.castTag(.error_set_inferred).?.data;
-
-                // We carefully do this in an order that avoids unnecessarily
-                // resolving the destination error set type.
-                if (ies.is_anyerror) break :ok;
-                if (ies.errors.contains(expected_name)) break :ok;
-                if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, dest_err_set_ty, inst_ty, inst_src, inst_src)) {
-                    break :ok;
-                }
+                },
+                .error_set => {
+                    const expected_name = val.castTag(.@"error").?.data.name;
+                    const error_set = dest_err_set_ty.castTag(.error_set).?.data;
+                    if (!error_set.names.contains(expected_name)) {
+                        return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
+                    }
+                },
+                .error_set_inferred => ok: {
+                    const expected_name = val.castTag(.@"error").?.data.name;
+                    const ies = dest_err_set_ty.castTag(.error_set_inferred).?.data;
+
+                    // We carefully do this in an order that avoids unnecessarily
+                    // resolving the destination error set type.
+                    if (ies.is_anyerror) break :ok;
+                    if (ies.errors.contains(expected_name)) break :ok;
+                    if (.ok == try sema.coerceInMemoryAllowedErrorSets(block, dest_err_set_ty, inst_ty, inst_src, inst_src)) {
+                        break :ok;
+                    }
 
-                return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
-            },
-            .error_set_merged => {
-                const expected_name = val.castTag(.@"error").?.data.name;
-                const error_set = dest_err_set_ty.castTag(.error_set_merged).?.data;
-                if (!error_set.contains(expected_name)) {
                     return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
-                }
+                },
+                .error_set_merged => {
+                    const expected_name = val.castTag(.@"error").?.data.name;
+                    const error_set = dest_err_set_ty.castTag(.error_set_merged).?.data;
+                    if (!error_set.contains(expected_name)) {
+                        return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
+                    }
+                },
+                else => unreachable,
             },
-            else => unreachable,
+
+            else => @panic("TODO"),
         }
         return sema.addConstant(dest_ty, val);
     }
@@ -30380,7 +30405,7 @@ fn resolvePeerTypes(
 ) !Type {
     const mod = sema.mod;
     switch (instructions.len) {
-        0 => return Type.initTag(.noreturn),
+        0 => return Type.noreturn,
         1 => return sema.typeOf(instructions[0]),
         else => {},
     }
@@ -31445,24 +31470,7 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
         .i64,
         .u128,
         .i128,
-        .anyopaque,
-        .bool,
-        .void,
-        .anyerror,
-        .noreturn,
-        .@"anyframe",
-        .null,
-        .undefined,
-        .atomic_order,
-        .atomic_rmw_op,
-        .calling_convention,
-        .address_space,
-        .float_mode,
-        .reduce_op,
-        .modifier,
-        .prefetch_options,
-        .export_options,
-        .extern_options,
+
         .manyptr_u8,
         .manyptr_const_u8,
         .manyptr_const_u8_sentinel_0,
@@ -31476,17 +31484,12 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
         .error_set_inferred,
         .error_set_merged,
         .@"opaque",
-        .generic_poison,
         .array_u8,
         .array_u8_sentinel_0,
         .enum_simple,
         => false,
 
         .single_const_pointer_to_comptime_int,
-        .type,
-        .comptime_int,
-        .enum_literal,
-        .type_info,
         .function,
         => true,
 
@@ -31709,17 +31712,6 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
                 try sema.resolveTypeFieldsUnion(ty, union_obj);
                 return ty;
             },
-            .type_info => return sema.getBuiltinType("Type"),
-            .extern_options => return sema.getBuiltinType("ExternOptions"),
-            .export_options => return sema.getBuiltinType("ExportOptions"),
-            .atomic_order => return sema.getBuiltinType("AtomicOrder"),
-            .atomic_rmw_op => return sema.getBuiltinType("AtomicRmwOp"),
-            .calling_convention => return sema.getBuiltinType("CallingConvention"),
-            .address_space => return sema.getBuiltinType("AddressSpace"),
-            .float_mode => return sema.getBuiltinType("FloatMode"),
-            .reduce_op => return sema.getBuiltinType("ReduceOp"),
-            .modifier => return sema.getBuiltinType("CallModifier"),
-            .prefetch_options => return sema.getBuiltinType("PrefetchOptions"),
 
             else => return ty,
         },
@@ -31772,6 +31764,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
         .const_slice_u8_type,
         .anyerror_void_error_union_type,
         .generic_poison_type,
+        .var_args_param_type,
         .empty_struct_type,
         => return ty,
 
@@ -31789,7 +31782,6 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
         .bool_false => unreachable,
         .empty_struct => unreachable,
         .generic_poison => unreachable,
-        .var_args_param_type => unreachable,
 
         .type_info_type => return sema.getBuiltinType("Type"),
         .extern_options_type => return sema.getBuiltinType("ExternOptions"),
@@ -32118,7 +32110,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
                 return sema.failWithOwnedErrorMsg(msg);
             }
             gop.value_ptr.* = .{
-                .ty = Type.initTag(.noreturn),
+                .ty = Type.noreturn,
                 .abi_align = 0,
                 .default_val = Value.initTag(.unreachable_value),
                 .is_comptime = is_comptime,
@@ -32552,7 +32544,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
         const field_ty: Type = if (!has_type)
             Type.void
         else if (field_type_ref == .none)
-            Type.initTag(.noreturn)
+            Type.noreturn
         else
             sema.resolveType(&block_scope, .unneeded, field_type_ref) catch |err| switch (err) {
                 error.NeededSourceLocation => {
@@ -32956,7 +32948,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
     };
 
     switch (ty.tag()) {
-        .comptime_int,
         .u1,
         .u8,
         .i8,
@@ -32969,9 +32960,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
         .i64,
         .u128,
         .i128,
-        .bool,
-        .type,
-        .anyerror,
+
         .error_set_single,
         .error_set,
         .error_set_merged,
@@ -32984,28 +32973,14 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
         .const_slice_u8_sentinel_0,
         .const_slice,
         .mut_slice,
-        .anyopaque,
         .optional_single_mut_pointer,
         .optional_single_const_pointer,
-        .enum_literal,
         .anyerror_void_error_union,
         .error_set_inferred,
         .@"opaque",
         .manyptr_u8,
         .manyptr_const_u8,
         .manyptr_const_u8_sentinel_0,
-        .atomic_order,
-        .atomic_rmw_op,
-        .calling_convention,
-        .address_space,
-        .float_mode,
-        .reduce_op,
-        .modifier,
-        .prefetch_options,
-        .export_options,
-        .extern_options,
-        .type_info,
-        .@"anyframe",
         .anyframe_T,
         .many_const_pointer,
         .many_mut_pointer,
@@ -33138,10 +33113,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
         },
 
         .empty_struct, .empty_struct_literal => return Value.initTag(.empty_struct_value),
-        .void => return Value.void,
-        .noreturn => return Value.initTag(.unreachable_value),
-        .null => return Value.null,
-        .undefined => return Value.initTag(.undef),
 
         .vector, .array, .array_u8 => {
             if (ty.arrayLen() == 0)
@@ -33154,7 +33125,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
 
         .inferred_alloc_const => unreachable,
         .inferred_alloc_mut => unreachable,
-        .generic_poison => return error.GenericPoison,
     }
 }
 
@@ -33194,34 +33164,12 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
         .i64 => return .i64_type,
         .u128 => return .u128_type,
         .i128 => return .i128_type,
-        .anyopaque => return .anyopaque_type,
-        .bool => return .bool_type,
-        .void => return .void_type,
-        .type => return .type_type,
-        .anyerror => return .anyerror_type,
-        .comptime_int => return .comptime_int_type,
-        .noreturn => return .noreturn_type,
-        .@"anyframe" => return .anyframe_type,
-        .null => return .null_type,
-        .undefined => return .undefined_type,
-        .enum_literal => return .enum_literal_type,
-        .atomic_order => return .atomic_order_type,
-        .atomic_rmw_op => return .atomic_rmw_op_type,
-        .calling_convention => return .calling_convention_type,
-        .address_space => return .address_space_type,
-        .float_mode => return .float_mode_type,
-        .reduce_op => return .reduce_op_type,
-        .modifier => return .call_modifier_type,
-        .prefetch_options => return .prefetch_options_type,
-        .export_options => return .export_options_type,
-        .extern_options => return .extern_options_type,
-        .type_info => return .type_info_type,
+
         .manyptr_u8 => return .manyptr_u8_type,
         .manyptr_const_u8 => return .manyptr_const_u8_type,
         .single_const_pointer_to_comptime_int => return .single_const_pointer_to_comptime_int_type,
         .const_slice_u8 => return .const_slice_u8_type,
         .anyerror_void_error_union => return .anyerror_void_error_union_type,
-        .generic_poison => return .generic_poison_type,
         else => {},
     }
     try sema.air_instructions.append(sema.gpa, .{
@@ -33658,22 +33606,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
         .i64,
         .u128,
         .i128,
-        .anyopaque,
-        .bool,
-        .void,
-        .anyerror,
-        .noreturn,
-        .@"anyframe",
-        .atomic_order,
-        .atomic_rmw_op,
-        .calling_convention,
-        .address_space,
-        .float_mode,
-        .reduce_op,
-        .modifier,
-        .prefetch_options,
-        .export_options,
-        .extern_options,
+
         .manyptr_u8,
         .manyptr_const_u8,
         .manyptr_const_u8_sentinel_0,
@@ -33687,19 +33620,12 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
         .error_set_inferred,
         .error_set_merged,
         .@"opaque",
-        .generic_poison,
         .array_u8,
         .array_u8_sentinel_0,
         .enum_simple,
         => false,
 
         .single_const_pointer_to_comptime_int,
-        .type,
-        .comptime_int,
-        .enum_literal,
-        .null,
-        .undefined,
-        .type_info,
         .function,
         => true,
 
@@ -34476,17 +34402,6 @@ fn enumHasInt(sema: *Sema, ty: Type, int: Value) CompileError!bool {
             const tag_ty = try mod.intType(.unsigned, bits);
             return sema.intInRange(tag_ty, int, fields_len);
         },
-        .atomic_order,
-        .atomic_rmw_op,
-        .calling_convention,
-        .address_space,
-        .float_mode,
-        .reduce_op,
-        .modifier,
-        .prefetch_options,
-        .export_options,
-        .extern_options,
-        => unreachable,
 
         else => unreachable,
     }
src/type.zig
@@ -85,9 +85,9 @@ pub const Type = struct {
                     .address_space,
                     .float_mode,
                     .reduce_op,
+                    .call_modifier,
                     => return .Enum,
 
-                    .call_modifier,
                     .prefetch_options,
                     .export_options,
                     .extern_options,
@@ -95,7 +95,7 @@ pub const Type = struct {
 
                     .type_info => return .Union,
 
-                    .generic_poison => unreachable,
+                    .generic_poison => return error.GenericPoison,
                     .var_args_param => unreachable,
                 },
 
@@ -107,8 +107,6 @@ pub const Type = struct {
             }
         }
         switch (ty.tag()) {
-            .generic_poison => return error.GenericPoison,
-
             .u1,
             .u8,
             .i8,
@@ -125,19 +123,11 @@ pub const Type = struct {
 
             .error_set,
             .error_set_single,
-            .anyerror,
             .error_set_inferred,
             .error_set_merged,
             => return .ErrorSet,
 
-            .anyopaque, .@"opaque" => return .Opaque,
-            .bool => return .Bool,
-            .void => return .Void,
-            .type => return .Type,
-            .comptime_int => return .ComptimeInt,
-            .noreturn => return .NoReturn,
-            .null => return .Null,
-            .undefined => return .Undefined,
+            .@"opaque" => return .Opaque,
 
             .function => return .Fn,
 
@@ -172,18 +162,14 @@ pub const Type = struct {
             .optional_single_const_pointer,
             .optional_single_mut_pointer,
             => return .Optional,
-            .enum_literal => return .EnumLiteral,
 
             .anyerror_void_error_union, .error_union => return .ErrorUnion,
 
-            .anyframe_T, .@"anyframe" => return .AnyFrame,
+            .anyframe_T => return .AnyFrame,
 
             .empty_struct,
             .empty_struct_literal,
             .@"struct",
-            .prefetch_options,
-            .export_options,
-            .extern_options,
             .tuple,
             .anon_struct,
             => return .Struct,
@@ -192,19 +178,11 @@ pub const Type = struct {
             .enum_nonexhaustive,
             .enum_simple,
             .enum_numbered,
-            .atomic_order,
-            .atomic_rmw_op,
-            .calling_convention,
-            .address_space,
-            .float_mode,
-            .reduce_op,
-            .modifier,
             => return .Enum,
 
             .@"union",
             .union_safety_tagged,
             .union_tagged,
-            .type_info,
             => return .Union,
         }
     }
@@ -393,7 +371,7 @@ pub const Type = struct {
     pub fn ptrInfo(self: Type) Payload.Pointer {
         switch (self.tag()) {
             .single_const_pointer_to_comptime_int => return .{ .data = .{
-                .pointee_type = Type.initTag(.comptime_int),
+                .pointee_type = Type.comptime_int,
                 .sentinel = null,
                 .@"align" = 0,
                 .@"addrspace" = .generic,
@@ -405,7 +383,7 @@ pub const Type = struct {
                 .size = .One,
             } },
             .const_slice_u8 => return .{ .data = .{
-                .pointee_type = Type.initTag(.u8),
+                .pointee_type = Type.u8,
                 .sentinel = null,
                 .@"align" = 0,
                 .@"addrspace" = .generic,
@@ -417,7 +395,7 @@ pub const Type = struct {
                 .size = .Slice,
             } },
             .const_slice_u8_sentinel_0 => return .{ .data = .{
-                .pointee_type = Type.initTag(.u8),
+                .pointee_type = Type.u8,
                 .sentinel = Value.zero,
                 .@"align" = 0,
                 .@"addrspace" = .generic,
@@ -465,7 +443,7 @@ pub const Type = struct {
                 .size = .Many,
             } },
             .manyptr_const_u8 => return .{ .data = .{
-                .pointee_type = Type.initTag(.u8),
+                .pointee_type = Type.u8,
                 .sentinel = null,
                 .@"align" = 0,
                 .@"addrspace" = .generic,
@@ -477,7 +455,7 @@ pub const Type = struct {
                 .size = .Many,
             } },
             .manyptr_const_u8_sentinel_0 => return .{ .data = .{
-                .pointee_type = Type.initTag(.u8),
+                .pointee_type = Type.u8,
                 .sentinel = Value.zero,
                 .@"align" = 0,
                 .@"addrspace" = .generic,
@@ -501,7 +479,7 @@ pub const Type = struct {
                 .size = .Many,
             } },
             .manyptr_u8 => return .{ .data = .{
-                .pointee_type = Type.initTag(.u8),
+                .pointee_type = Type.u8,
                 .sentinel = null,
                 .@"align" = 0,
                 .@"addrspace" = .generic,
@@ -608,23 +586,6 @@ pub const Type = struct {
         if (a.legacy.tag_if_small_enough == b.legacy.tag_if_small_enough) return true;
 
         switch (a.tag()) {
-            .generic_poison => unreachable,
-
-            .bool,
-            .void,
-            .type,
-            .comptime_int,
-            .noreturn,
-            .null,
-            .undefined,
-            .anyopaque,
-            .@"anyframe",
-            .enum_literal,
-            => |a_tag| {
-                assert(a_tag != b.tag()); // because of the comparison at the top of the function.
-                return false;
-            },
-
             .u1,
             .u8,
             .i8,
@@ -653,10 +614,6 @@ pub const Type = struct {
                 return a_ies == b_ies;
             },
 
-            .anyerror => {
-                return b.tag() == .anyerror;
-            },
-
             .error_set,
             .error_set_single,
             .error_set_merged,
@@ -927,13 +884,6 @@ pub const Type = struct {
                 return true;
             },
 
-            // we can't compare these based on tags because it wouldn't detect if,
-            // for example, a was resolved into .@"struct" but b was one of these tags.
-            .prefetch_options,
-            .export_options,
-            .extern_options,
-            => unreachable, // needed to resolve the type before now
-
             .enum_full, .enum_nonexhaustive => {
                 const a_enum_obj = a.cast(Payload.EnumFull).?.data;
                 const b_enum_obj = (b.cast(Payload.EnumFull) orelse return false).data;
@@ -949,26 +899,12 @@ pub const Type = struct {
                 const b_enum_obj = (b.cast(Payload.EnumNumbered) orelse return false).data;
                 return a_enum_obj == b_enum_obj;
             },
-            // we can't compare these based on tags because it wouldn't detect if,
-            // for example, a was resolved into .enum_simple but b was one of these tags.
-            .atomic_order,
-            .atomic_rmw_op,
-            .calling_convention,
-            .address_space,
-            .float_mode,
-            .reduce_op,
-            .modifier,
-            => unreachable, // needed to resolve the type before now
 
             .@"union", .union_safety_tagged, .union_tagged => {
                 const a_union_obj = a.cast(Payload.Union).?.data;
                 const b_union_obj = (b.cast(Payload.Union) orelse return false).data;
                 return a_union_obj == b_union_obj;
             },
-            // we can't compare these based on tags because it wouldn't detect if,
-            // for example, a was resolved into .union_tagged but b was one of these tags.
-            .type_info => unreachable, // needed to resolve the type before now
-
         }
     }
 
@@ -987,31 +923,6 @@ pub const Type = struct {
             return;
         }
         switch (ty.tag()) {
-            .generic_poison => unreachable,
-
-            .bool => std.hash.autoHash(hasher, std.builtin.TypeId.Bool),
-            .void => std.hash.autoHash(hasher, std.builtin.TypeId.Void),
-            .type => std.hash.autoHash(hasher, std.builtin.TypeId.Type),
-            .comptime_int => std.hash.autoHash(hasher, std.builtin.TypeId.ComptimeInt),
-            .noreturn => std.hash.autoHash(hasher, std.builtin.TypeId.NoReturn),
-            .null => std.hash.autoHash(hasher, std.builtin.TypeId.Null),
-            .undefined => std.hash.autoHash(hasher, std.builtin.TypeId.Undefined),
-
-            .anyopaque => {
-                std.hash.autoHash(hasher, std.builtin.TypeId.Opaque);
-                std.hash.autoHash(hasher, Tag.anyopaque);
-            },
-
-            .@"anyframe" => {
-                std.hash.autoHash(hasher, std.builtin.TypeId.AnyFrame);
-                std.hash.autoHash(hasher, Tag.@"anyframe");
-            },
-
-            .enum_literal => {
-                std.hash.autoHash(hasher, std.builtin.TypeId.EnumLiteral);
-                std.hash.autoHash(hasher, Tag.enum_literal);
-            },
-
             .u1,
             .u8,
             .i8,
@@ -1046,12 +957,6 @@ pub const Type = struct {
                 for (names) |name| hasher.update(name);
             },
 
-            .anyerror => {
-                // anyerror is distinct from other error sets
-                std.hash.autoHash(hasher, std.builtin.TypeId.ErrorSet);
-                std.hash.autoHash(hasher, Tag.anyerror);
-            },
-
             .error_set_inferred => {
                 // inferred error sets are compared using their data pointer
                 const ies: *Module.Fn.InferredErrorSet = ty.castTag(.error_set_inferred).?.data;
@@ -1209,12 +1114,6 @@ pub const Type = struct {
                 }
             },
 
-            // we can't hash these based on tags because they wouldn't match the expanded version.
-            .prefetch_options,
-            .export_options,
-            .extern_options,
-            => unreachable, // needed to resolve the type before now
-
             .enum_full, .enum_nonexhaustive => {
                 const enum_obj: *const Module.EnumFull = ty.cast(Payload.EnumFull).?.data;
                 std.hash.autoHash(hasher, std.builtin.TypeId.Enum);
@@ -1230,24 +1129,12 @@ pub const Type = struct {
                 std.hash.autoHash(hasher, std.builtin.TypeId.Enum);
                 std.hash.autoHash(hasher, enum_obj);
             },
-            // we can't hash these based on tags because they wouldn't match the expanded version.
-            .atomic_order,
-            .atomic_rmw_op,
-            .calling_convention,
-            .address_space,
-            .float_mode,
-            .reduce_op,
-            .modifier,
-            => unreachable, // needed to resolve the type before now
 
             .@"union", .union_safety_tagged, .union_tagged => {
                 const union_obj: *const Module.Union = ty.cast(Payload.Union).?.data;
                 std.hash.autoHash(hasher, std.builtin.TypeId.Union);
                 std.hash.autoHash(hasher, union_obj);
             },
-            // we can't hash these based on tags because they wouldn't match the expanded version.
-            .type_info => unreachable, // needed to resolve the type before now
-
         }
     }
 
@@ -1305,19 +1192,9 @@ pub const Type = struct {
             .i64,
             .u128,
             .i128,
-            .anyopaque,
-            .bool,
-            .void,
-            .type,
-            .anyerror,
-            .comptime_int,
-            .noreturn,
-            .null,
-            .undefined,
             .single_const_pointer_to_comptime_int,
             .const_slice_u8,
             .const_slice_u8_sentinel_0,
-            .enum_literal,
             .anyerror_void_error_union,
             .inferred_alloc_const,
             .inferred_alloc_mut,
@@ -1325,19 +1202,6 @@ pub const Type = struct {
             .manyptr_u8,
             .manyptr_const_u8,
             .manyptr_const_u8_sentinel_0,
-            .atomic_order,
-            .atomic_rmw_op,
-            .calling_convention,
-            .address_space,
-            .float_mode,
-            .reduce_op,
-            .modifier,
-            .prefetch_options,
-            .export_options,
-            .extern_options,
-            .type_info,
-            .@"anyframe",
-            .generic_poison,
             => unreachable,
 
             .array_u8,
@@ -1580,20 +1444,8 @@ pub const Type = struct {
                 .i64,
                 .u128,
                 .i128,
-                .anyopaque,
-                .bool,
-                .void,
-                .type,
-                .anyerror,
-                .@"anyframe",
-                .comptime_int,
-                .noreturn,
                 => return writer.writeAll(@tagName(t)),
 
-                .enum_literal => return writer.writeAll("@Type(.EnumLiteral)"),
-                .null => return writer.writeAll("@Type(.Null)"),
-                .undefined => return writer.writeAll("@Type(.Undefined)"),
-
                 .empty_struct, .empty_struct_literal => return writer.writeAll("struct {}"),
 
                 .@"struct" => {
@@ -1640,17 +1492,6 @@ pub const Type = struct {
                 .manyptr_u8 => return writer.writeAll("[*]u8"),
                 .manyptr_const_u8 => return writer.writeAll("[*]const u8"),
                 .manyptr_const_u8_sentinel_0 => return writer.writeAll("[*:0]const u8"),
-                .atomic_order => return writer.writeAll("std.builtin.AtomicOrder"),
-                .atomic_rmw_op => return writer.writeAll("std.builtin.AtomicRmwOp"),
-                .calling_convention => return writer.writeAll("std.builtin.CallingConvention"),
-                .address_space => return writer.writeAll("std.builtin.AddressSpace"),
-                .float_mode => return writer.writeAll("std.builtin.FloatMode"),
-                .reduce_op => return writer.writeAll("std.builtin.ReduceOp"),
-                .modifier => return writer.writeAll("std.builtin.CallModifier"),
-                .prefetch_options => return writer.writeAll("std.builtin.PrefetchOptions"),
-                .export_options => return writer.writeAll("std.builtin.ExportOptions"),
-                .extern_options => return writer.writeAll("std.builtin.ExternOptions"),
-                .type_info => return writer.writeAll("std.builtin.Type"),
                 .function => {
                     const payload = ty.castTag(.function).?.data;
                     try writer.writeAll("fn(");
@@ -1889,7 +1730,6 @@ pub const Type = struct {
                 },
                 .inferred_alloc_const => return writer.writeAll("(inferred_alloc_const)"),
                 .inferred_alloc_mut => return writer.writeAll("(inferred_alloc_mut)"),
-                .generic_poison => return writer.writeAll("(generic poison)"),
             }
             unreachable;
         }
@@ -1931,20 +1771,6 @@ pub const Type = struct {
         switch (t) {
             .inferred_alloc_const => unreachable,
             .inferred_alloc_mut => unreachable,
-            .generic_poison => unreachable,
-
-            // TODO get rid of these Type.Tag values.
-            .atomic_order => unreachable,
-            .atomic_rmw_op => unreachable,
-            .calling_convention => unreachable,
-            .address_space => unreachable,
-            .float_mode => unreachable,
-            .reduce_op => unreachable,
-            .modifier => unreachable,
-            .prefetch_options => unreachable,
-            .export_options => unreachable,
-            .extern_options => unreachable,
-            .type_info => unreachable,
 
             .u1,
             .u8,
@@ -1958,19 +1784,8 @@ pub const Type = struct {
             .i64,
             .u128,
             .i128,
-            .anyopaque,
-            .bool,
-            .void,
-            .type,
-            .anyerror,
-            .@"anyframe",
-            .comptime_int,
-            .noreturn,
             => try writer.writeAll(@tagName(t)),
 
-            .enum_literal => try writer.writeAll("@TypeOf(.enum_literal)"),
-            .null => try writer.writeAll("@TypeOf(null)"),
-            .undefined => try writer.writeAll("@TypeOf(undefined)"),
             .empty_struct_literal => try writer.writeAll("@TypeOf(.{})"),
 
             .empty_struct => {
@@ -2249,34 +2064,12 @@ pub const Type = struct {
             .i32 => return Value.initTag(.i32_type),
             .u64 => return Value.initTag(.u64_type),
             .i64 => return Value.initTag(.i64_type),
-            .anyopaque => return Value.initTag(.anyopaque_type),
-            .bool => return Value.initTag(.bool_type),
-            .void => return Value.initTag(.void_type),
-            .type => return Value.initTag(.type_type),
-            .anyerror => return Value.initTag(.anyerror_type),
-            .@"anyframe" => return Value.initTag(.anyframe_type),
-            .comptime_int => return Value.initTag(.comptime_int_type),
-            .noreturn => return Value.initTag(.noreturn_type),
-            .null => return Value.initTag(.null_type),
-            .undefined => return Value.initTag(.undefined_type),
             .single_const_pointer_to_comptime_int => return Value.initTag(.single_const_pointer_to_comptime_int_type),
             .const_slice_u8 => return Value.initTag(.const_slice_u8_type),
             .const_slice_u8_sentinel_0 => return Value.initTag(.const_slice_u8_sentinel_0_type),
-            .enum_literal => return Value.initTag(.enum_literal_type),
             .manyptr_u8 => return Value.initTag(.manyptr_u8_type),
             .manyptr_const_u8 => return Value.initTag(.manyptr_const_u8_type),
             .manyptr_const_u8_sentinel_0 => return Value.initTag(.manyptr_const_u8_sentinel_0_type),
-            .atomic_order => return Value.initTag(.atomic_order_type),
-            .atomic_rmw_op => return Value.initTag(.atomic_rmw_op_type),
-            .calling_convention => return Value.initTag(.calling_convention_type),
-            .address_space => return Value.initTag(.address_space_type),
-            .float_mode => return Value.initTag(.float_mode_type),
-            .reduce_op => return Value.initTag(.reduce_op_type),
-            .modifier => return Value.initTag(.modifier_type),
-            .prefetch_options => return Value.initTag(.prefetch_options_type),
-            .export_options => return Value.initTag(.export_options_type),
-            .extern_options => return Value.initTag(.extern_options_type),
-            .type_info => return Value.initTag(.type_info_type),
             .inferred_alloc_const => unreachable,
             .inferred_alloc_mut => unreachable,
             else => return Value.Tag.ty.create(allocator, self),
@@ -2378,8 +2171,7 @@ pub const Type = struct {
             .i64,
             .u128,
             .i128,
-            .bool,
-            .anyerror,
+
             .const_slice_u8,
             .const_slice_u8_sentinel_0,
             .array_u8_sentinel_0,
@@ -2388,18 +2180,7 @@ pub const Type = struct {
             .manyptr_u8,
             .manyptr_const_u8,
             .manyptr_const_u8_sentinel_0,
-            .atomic_order,
-            .atomic_rmw_op,
-            .calling_convention,
-            .address_space,
-            .float_mode,
-            .reduce_op,
-            .modifier,
-            .prefetch_options,
-            .export_options,
-            .extern_options,
-            .@"anyframe",
-            .anyopaque,
+
             .@"opaque",
             .error_set_single,
             .error_union,
@@ -2435,16 +2216,8 @@ pub const Type = struct {
 
             // These are false because they are comptime-only types.
             .single_const_pointer_to_comptime_int,
-            .void,
-            .type,
-            .comptime_int,
-            .noreturn,
-            .null,
-            .undefined,
-            .enum_literal,
             .empty_struct,
             .empty_struct_literal,
-            .type_info,
             // These are function *bodies*, not pointers.
             // Special exceptions have to be made when emitting functions due to
             // this returning false.
@@ -2558,7 +2331,6 @@ pub const Type = struct {
 
             .inferred_alloc_const => unreachable,
             .inferred_alloc_mut => unreachable,
-            .generic_poison => unreachable,
         }
     }
 
@@ -2641,8 +2413,7 @@ pub const Type = struct {
             .i64,
             .u128,
             .i128,
-            .bool,
-            .void,
+
             .manyptr_u8,
             .manyptr_const_u8,
             .manyptr_const_u8_sentinel_0,
@@ -2662,32 +2433,11 @@ pub const Type = struct {
             .optional_single_const_pointer,
             => true,
 
-            .anyopaque,
-            .anyerror,
-            .noreturn,
-            .null,
-            .@"anyframe",
-            .undefined,
-            .atomic_order,
-            .atomic_rmw_op,
-            .calling_convention,
-            .address_space,
-            .float_mode,
-            .reduce_op,
-            .modifier,
-            .prefetch_options,
-            .export_options,
-            .extern_options,
             .error_set,
             .error_set_single,
             .error_set_inferred,
             .error_set_merged,
             .@"opaque",
-            .generic_poison,
-            .type,
-            .comptime_int,
-            .enum_literal,
-            .type_info,
             // These are function bodies, not function pointers.
             .function,
             .const_slice_u8,
@@ -2773,7 +2523,6 @@ pub const Type = struct {
             else => return false,
 
             @enumToInt(InternPool.Index.none) => switch (ty.tag()) {
-                .noreturn => return true,
                 .error_set => {
                     const err_set_obj = ty.castTag(.error_set).?.data;
                     const names = err_set_obj.names.keys();
@@ -3003,21 +2752,10 @@ pub const Type = struct {
             .u1,
             .u8,
             .i8,
-            .bool,
+
             .array_u8_sentinel_0,
             .array_u8,
-            .atomic_order,
-            .atomic_rmw_op,
-            .calling_convention,
-            .address_space,
-            .float_mode,
-            .reduce_op,
-            .modifier,
-            .prefetch_options,
-            .export_options,
-            .extern_options,
             .@"opaque",
-            .anyopaque,
             => return AbiAlignmentAdvanced{ .scalar = 1 },
 
             // represents machine code; not a pointer
@@ -3044,13 +2782,11 @@ pub const Type = struct {
             .manyptr_u8,
             .manyptr_const_u8,
             .manyptr_const_u8_sentinel_0,
-            .@"anyframe",
             .anyframe_T,
             => return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) },
 
             // TODO revisit this when we have the concept of the error tag type
             .anyerror_void_error_union,
-            .anyerror,
             .error_set_inferred,
             .error_set_single,
             .error_set,
@@ -3229,22 +2965,12 @@ pub const Type = struct {
             },
 
             .empty_struct,
-            .void,
             .empty_struct_literal,
-            .type,
-            .comptime_int,
-            .null,
-            .undefined,
-            .enum_literal,
-            .type_info,
             => return AbiAlignmentAdvanced{ .scalar = 0 },
 
-            .noreturn,
             .inferred_alloc_const,
             .inferred_alloc_mut,
             => unreachable,
-
-            .generic_poison => unreachable,
         }
     }
 
@@ -3422,26 +3148,12 @@ pub const Type = struct {
         switch (ty.tag()) {
             .function => unreachable, // represents machine code; not a pointer
             .@"opaque" => unreachable, // no size available
-            .noreturn => unreachable,
             .inferred_alloc_const => unreachable,
             .inferred_alloc_mut => unreachable,
-            .generic_poison => unreachable,
-            .modifier => unreachable, // missing call to resolveTypeFields
-            .prefetch_options => unreachable, // missing call to resolveTypeFields
-            .export_options => unreachable, // missing call to resolveTypeFields
-            .extern_options => unreachable, // missing call to resolveTypeFields
-            .type_info => unreachable, // missing call to resolveTypeFields
-
-            .anyopaque,
-            .type,
-            .comptime_int,
-            .null,
-            .undefined,
-            .enum_literal,
+
             .single_const_pointer_to_comptime_int,
             .empty_struct_literal,
             .empty_struct,
-            .void,
             => return AbiSizeAdvanced{ .scalar = 0 },
 
             .@"struct", .tuple, .anon_struct => switch (ty.containerLayout()) {
@@ -3496,13 +3208,6 @@ pub const Type = struct {
             .u1,
             .u8,
             .i8,
-            .bool,
-            .atomic_order,
-            .atomic_rmw_op,
-            .calling_convention,
-            .address_space,
-            .float_mode,
-            .reduce_op,
             => return AbiSizeAdvanced{ .scalar = 1 },
 
             .array_u8 => return AbiSizeAdvanced{ .scalar = ty.castTag(.array_u8).?.data },
@@ -3552,7 +3257,6 @@ pub const Type = struct {
                 return AbiSizeAdvanced{ .scalar = result };
             },
 
-            .@"anyframe",
             .anyframe_T,
             .optional_single_const_pointer,
             .optional_single_mut_pointer,
@@ -3580,7 +3284,6 @@ pub const Type = struct {
 
             // TODO revisit this when we have the concept of the error tag type
             .anyerror_void_error_union,
-            .anyerror,
             .error_set_inferred,
             .error_set,
             .error_set_merged,
@@ -3758,6 +3461,7 @@ pub const Type = struct {
                 .undefined => unreachable,
                 .enum_literal => unreachable,
                 .generic_poison => unreachable,
+                .var_args_param => unreachable,
 
                 .atomic_order => unreachable, // missing call to resolveTypeFields
                 .atomic_rmw_op => unreachable, // missing call to resolveTypeFields
@@ -3770,7 +3474,6 @@ pub const Type = struct {
                 .export_options => unreachable, // missing call to resolveTypeFields
                 .extern_options => unreachable, // missing call to resolveTypeFields
                 .type_info => unreachable, // missing call to resolveTypeFields
-                .var_args_param => unreachable,
             },
             .struct_type => @panic("TODO"),
             .union_type => @panic("TODO"),
@@ -3784,23 +3487,14 @@ pub const Type = struct {
 
         switch (ty.tag()) {
             .function => unreachable, // represents machine code; not a pointer
-            .anyopaque => unreachable,
-            .type => unreachable,
-            .comptime_int => unreachable,
-            .noreturn => unreachable,
-            .null => unreachable,
-            .undefined => unreachable,
-            .enum_literal => unreachable,
             .single_const_pointer_to_comptime_int => unreachable,
             .empty_struct => unreachable,
             .empty_struct_literal => unreachable,
             .inferred_alloc_const => unreachable,
             .inferred_alloc_mut => unreachable,
             .@"opaque" => unreachable,
-            .generic_poison => unreachable,
 
-            .void => return 0,
-            .bool, .u1 => return 1,
+            .u1 => return 1,
             .u8, .i8 => return 8,
             .i16, .u16 => return 16,
             .u29 => return 29,
@@ -3875,9 +3569,7 @@ pub const Type = struct {
                 return payload.len * 8 * elem_size + elem_bit_size;
             },
 
-            .@"anyframe",
-            .anyframe_T,
-            => return target.ptrBitWidth(),
+            .anyframe_T => return target.ptrBitWidth(),
 
             .const_slice,
             .mut_slice,
@@ -3916,7 +3608,6 @@ pub const Type = struct {
             .error_set,
             .error_set_single,
             .anyerror_void_error_union,
-            .anyerror,
             .error_set_inferred,
             .error_set_merged,
             => return 16, // TODO revisit this when we have the concept of the error tag type
@@ -3926,19 +3617,6 @@ pub const Type = struct {
                 // includes padding bits.
                 return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;
             },
-
-            .atomic_order,
-            .atomic_rmw_op,
-            .calling_convention,
-            .address_space,
-            .float_mode,
-            .reduce_op,
-            .modifier,
-            .prefetch_options,
-            .export_options,
-            .extern_options,
-            .type_info,
-            => @panic("TODO at some point we gotta resolve builtin types"),
         }
     }
 
@@ -4326,7 +4004,7 @@ pub const Type = struct {
             .manyptr_const_u8_sentinel_0,
             => Type.u8,
 
-            .single_const_pointer_to_comptime_int => Type.initTag(.comptime_int),
+            .single_const_pointer_to_comptime_int => Type.comptime_int,
             .pointer => ty.castTag(.pointer).?.data.pointee_type,
 
             else => unreachable,
@@ -4372,7 +4050,7 @@ pub const Type = struct {
             .manyptr_const_u8_sentinel_0,
             => Type.u8,
 
-            .single_const_pointer_to_comptime_int => Type.initTag(.comptime_int),
+            .single_const_pointer_to_comptime_int => Type.comptime_int,
             .pointer => {
                 const info = ty.castTag(.pointer).?.data;
                 const child_ty = info.pointee_type;
@@ -4387,7 +4065,6 @@ pub const Type = struct {
             .optional_single_const_pointer => ty.castPointer().?.data,
 
             .anyframe_T => ty.castTag(.anyframe_T).?.data,
-            .@"anyframe" => Type.void,
 
             else => unreachable,
         };
@@ -4468,19 +4145,6 @@ pub const Type = struct {
                 return union_obj.tag_ty;
             },
 
-            .atomic_order,
-            .atomic_rmw_op,
-            .calling_convention,
-            .address_space,
-            .float_mode,
-            .reduce_op,
-            .modifier,
-            .prefetch_options,
-            .export_options,
-            .extern_options,
-            .type_info,
-            => unreachable, // needed to call resolveTypeFields first
-
             else => null,
         };
     }
@@ -4495,19 +4159,6 @@ pub const Type = struct {
                 return union_obj.tag_ty;
             },
 
-            .atomic_order,
-            .atomic_rmw_op,
-            .calling_convention,
-            .address_space,
-            .float_mode,
-            .reduce_op,
-            .modifier,
-            .prefetch_options,
-            .export_options,
-            .extern_options,
-            .type_info,
-            => unreachable, // needed to call resolveTypeFields first
-
             else => null,
         };
     }
@@ -4572,7 +4223,7 @@ pub const Type = struct {
     /// Asserts that the type is an error union.
     pub fn errorUnionPayload(self: Type) Type {
         return switch (self.tag()) {
-            .anyerror_void_error_union => Type.initTag(.void),
+            .anyerror_void_error_union => Type.void,
             .error_union => self.castTag(.error_union).?.data.payload,
             else => unreachable,
         };
@@ -4580,33 +4231,38 @@ pub const Type = struct {
 
     pub fn errorUnionSet(self: Type) Type {
         return switch (self.tag()) {
-            .anyerror_void_error_union => Type.initTag(.anyerror),
+            .anyerror_void_error_union => Type.anyerror,
             .error_union => self.castTag(.error_union).?.data.error_set,
             else => unreachable,
         };
     }
 
     /// Returns false for unresolved inferred error sets.
-    pub fn errorSetIsEmpty(ty: Type) bool {
-        switch (ty.tag()) {
-            .anyerror => return false,
-            .error_set_inferred => {
-                const inferred_error_set = ty.castTag(.error_set_inferred).?.data;
-                // Can't know for sure.
-                if (!inferred_error_set.is_resolved) return false;
-                if (inferred_error_set.is_anyerror) return false;
-                return inferred_error_set.errors.count() == 0;
-            },
-            .error_set_single => return false,
-            .error_set => {
-                const err_set_obj = ty.castTag(.error_set).?.data;
-                return err_set_obj.names.count() == 0;
+    pub fn errorSetIsEmpty(ty: Type, mod: *const Module) bool {
+        switch (ty.ip_index) {
+            .none => switch (ty.tag()) {
+                .error_set_inferred => {
+                    const inferred_error_set = ty.castTag(.error_set_inferred).?.data;
+                    // Can't know for sure.
+                    if (!inferred_error_set.is_resolved) return false;
+                    if (inferred_error_set.is_anyerror) return false;
+                    return inferred_error_set.errors.count() == 0;
+                },
+                .error_set_single => return false,
+                .error_set => {
+                    const err_set_obj = ty.castTag(.error_set).?.data;
+                    return err_set_obj.names.count() == 0;
+                },
+                .error_set_merged => {
+                    const name_map = ty.castTag(.error_set_merged).?.data;
+                    return name_map.count() == 0;
+                },
+                else => unreachable,
             },
-            .error_set_merged => {
-                const name_map = ty.castTag(.error_set_merged).?.data;
-                return name_map.count() == 0;
+            .anyerror_type => return false,
+            else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
+                else => @panic("TODO"),
             },
-            else => unreachable,
         }
     }
 
@@ -4614,9 +4270,13 @@ pub const Type = struct {
     /// Note that the result may be a false negative if the type did not get error set
     /// resolution prior to this call.
     pub fn isAnyError(ty: Type) bool {
-        return switch (ty.tag()) {
-            .anyerror => true,
-            .error_set_inferred => ty.castTag(.error_set_inferred).?.data.is_anyerror,
+        return switch (ty.ip_index) {
+            .none => switch (ty.tag()) {
+                .error_set_inferred => ty.castTag(.error_set_inferred).?.data.is_anyerror,
+                else => false,
+            },
+            .anyerror_type => true,
+            // TODO handle error_set_inferred here
             else => false,
         };
     }
@@ -4788,72 +4448,75 @@ pub const Type = struct {
         const target = mod.getTarget();
         var ty = starting_ty;
 
-        if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
-            .int_type => |int_type| return int_type,
-            .ptr_type => unreachable,
-            .array_type => unreachable,
-            .vector_type => @panic("TODO"),
-            .optional_type => unreachable,
-            .error_union_type => unreachable,
-            .simple_type => |t| switch (t) {
-                .usize => return .{ .signedness = .unsigned, .bits = target.ptrBitWidth() },
-                .isize => return .{ .signedness = .signed, .bits = target.ptrBitWidth() },
-                .c_char => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.char) },
-                .c_short => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.short) },
-                .c_ushort => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ushort) },
-                .c_int => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.int) },
-                .c_uint => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.uint) },
-                .c_long => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.long) },
-                .c_ulong => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ulong) },
-                .c_longlong => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.longlong) },
-                .c_ulonglong => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ulonglong) },
-                else => unreachable,
-            },
-            .struct_type => @panic("TODO"),
-            .union_type => unreachable,
-            .simple_value => unreachable,
-            .extern_func => unreachable,
-            .int => unreachable,
-            .enum_tag => unreachable, // it's a value, not a type
-        };
+        while (true) switch (ty.ip_index) {
+            .none => switch (ty.tag()) {
+                .u1 => return .{ .signedness = .unsigned, .bits = 1 },
+                .u8 => return .{ .signedness = .unsigned, .bits = 8 },
+                .i8 => return .{ .signedness = .signed, .bits = 8 },
+                .u16 => return .{ .signedness = .unsigned, .bits = 16 },
+                .i16 => return .{ .signedness = .signed, .bits = 16 },
+                .u29 => return .{ .signedness = .unsigned, .bits = 29 },
+                .u32 => return .{ .signedness = .unsigned, .bits = 32 },
+                .i32 => return .{ .signedness = .signed, .bits = 32 },
+                .u64 => return .{ .signedness = .unsigned, .bits = 64 },
+                .i64 => return .{ .signedness = .signed, .bits = 64 },
+                .u128 => return .{ .signedness = .unsigned, .bits = 128 },
+                .i128 => return .{ .signedness = .signed, .bits = 128 },
+
+                .enum_full, .enum_nonexhaustive => ty = ty.cast(Payload.EnumFull).?.data.tag_ty,
+                .enum_numbered => ty = ty.castTag(.enum_numbered).?.data.tag_ty,
+                .enum_simple => {
+                    const enum_obj = ty.castTag(.enum_simple).?.data;
+                    const field_count = enum_obj.fields.count();
+                    if (field_count == 0) return .{ .signedness = .unsigned, .bits = 0 };
+                    return .{ .signedness = .unsigned, .bits = smallestUnsignedBits(field_count - 1) };
+                },
 
-        while (true) switch (ty.tag()) {
-            .u1 => return .{ .signedness = .unsigned, .bits = 1 },
-            .u8 => return .{ .signedness = .unsigned, .bits = 8 },
-            .i8 => return .{ .signedness = .signed, .bits = 8 },
-            .u16 => return .{ .signedness = .unsigned, .bits = 16 },
-            .i16 => return .{ .signedness = .signed, .bits = 16 },
-            .u29 => return .{ .signedness = .unsigned, .bits = 29 },
-            .u32 => return .{ .signedness = .unsigned, .bits = 32 },
-            .i32 => return .{ .signedness = .signed, .bits = 32 },
-            .u64 => return .{ .signedness = .unsigned, .bits = 64 },
-            .i64 => return .{ .signedness = .signed, .bits = 64 },
-            .u128 => return .{ .signedness = .unsigned, .bits = 128 },
-            .i128 => return .{ .signedness = .signed, .bits = 128 },
-
-            .enum_full, .enum_nonexhaustive => ty = ty.cast(Payload.EnumFull).?.data.tag_ty,
-            .enum_numbered => ty = ty.castTag(.enum_numbered).?.data.tag_ty,
-            .enum_simple => {
-                const enum_obj = ty.castTag(.enum_simple).?.data;
-                const field_count = enum_obj.fields.count();
-                if (field_count == 0) return .{ .signedness = .unsigned, .bits = 0 };
-                return .{ .signedness = .unsigned, .bits = smallestUnsignedBits(field_count - 1) };
-            },
+                .error_set, .error_set_single, .error_set_inferred, .error_set_merged => {
+                    // TODO revisit this when error sets support custom int types
+                    return .{ .signedness = .unsigned, .bits = 16 };
+                },
+
+                .vector => ty = ty.castTag(.vector).?.data.elem_type,
+
+                .@"struct" => {
+                    const struct_obj = ty.castTag(.@"struct").?.data;
+                    assert(struct_obj.layout == .Packed);
+                    ty = struct_obj.backing_int_ty;
+                },
 
-            .error_set, .error_set_single, .anyerror, .error_set_inferred, .error_set_merged => {
+                else => unreachable,
+            },
+            .anyerror_type => {
                 // TODO revisit this when error sets support custom int types
                 return .{ .signedness = .unsigned, .bits = 16 };
             },
-
-            .vector => ty = ty.castTag(.vector).?.data.elem_type,
-
-            .@"struct" => {
-                const struct_obj = ty.castTag(.@"struct").?.data;
-                assert(struct_obj.layout == .Packed);
-                ty = struct_obj.backing_int_ty;
+            .usize_type => return .{ .signedness = .unsigned, .bits = target.ptrBitWidth() },
+            .isize_type => return .{ .signedness = .signed, .bits = target.ptrBitWidth() },
+            .c_char_type => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.char) },
+            .c_short_type => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.short) },
+            .c_ushort_type => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ushort) },
+            .c_int_type => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.int) },
+            .c_uint_type => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.uint) },
+            .c_long_type => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.long) },
+            .c_ulong_type => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ulong) },
+            .c_longlong_type => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.longlong) },
+            .c_ulonglong_type => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ulonglong) },
+            else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
+                .int_type => |int_type| return int_type,
+                .ptr_type => unreachable,
+                .array_type => unreachable,
+                .vector_type => @panic("TODO"),
+                .optional_type => unreachable,
+                .error_union_type => unreachable,
+                .simple_type => unreachable, // handled via Index enum tag above
+                .struct_type => @panic("TODO"),
+                .union_type => unreachable,
+                .simple_value => unreachable,
+                .extern_func => unreachable,
+                .int => unreachable,
+                .enum_tag => unreachable,
             },
-
-            else => unreachable,
         };
     }
 
@@ -5021,7 +4684,6 @@ pub const Type = struct {
             else => false,
         };
         return switch (ty.tag()) {
-            .comptime_int,
             .u1,
             .u8,
             .i8,
@@ -5114,7 +4776,6 @@ pub const Type = struct {
         };
 
         while (true) switch (ty.tag()) {
-            .comptime_int,
             .u1,
             .u8,
             .i8,
@@ -5127,9 +4788,7 @@ pub const Type = struct {
             .i64,
             .u128,
             .i128,
-            .bool,
-            .type,
-            .anyerror,
+
             .error_union,
             .error_set_single,
             .error_set,
@@ -5142,28 +4801,14 @@ pub const Type = struct {
             .const_slice_u8_sentinel_0,
             .const_slice,
             .mut_slice,
-            .anyopaque,
             .optional_single_mut_pointer,
             .optional_single_const_pointer,
-            .enum_literal,
             .anyerror_void_error_union,
             .error_set_inferred,
             .@"opaque",
             .manyptr_u8,
             .manyptr_const_u8,
             .manyptr_const_u8_sentinel_0,
-            .atomic_order,
-            .atomic_rmw_op,
-            .calling_convention,
-            .address_space,
-            .float_mode,
-            .reduce_op,
-            .modifier,
-            .prefetch_options,
-            .export_options,
-            .extern_options,
-            .type_info,
-            .@"anyframe",
             .anyframe_T,
             .many_const_pointer,
             .many_mut_pointer,
@@ -5258,10 +4903,6 @@ pub const Type = struct {
             },
 
             .empty_struct, .empty_struct_literal => return Value.initTag(.empty_struct_value),
-            .void => return Value.initTag(.void_value),
-            .noreturn => return Value.initTag(.unreachable_value),
-            .null => return Value.initTag(.null_value),
-            .undefined => return Value.initTag(.undef),
 
             .vector, .array, .array_u8 => {
                 if (ty.arrayLen() == 0)
@@ -5273,7 +4914,6 @@ pub const Type = struct {
 
             .inferred_alloc_const => unreachable,
             .inferred_alloc_mut => unreachable,
-            .generic_poison => unreachable,
         };
     }
 
@@ -5358,22 +4998,7 @@ pub const Type = struct {
             .i64,
             .u128,
             .i128,
-            .anyopaque,
-            .bool,
-            .void,
-            .anyerror,
-            .noreturn,
-            .@"anyframe",
-            .atomic_order,
-            .atomic_rmw_op,
-            .calling_convention,
-            .address_space,
-            .float_mode,
-            .reduce_op,
-            .modifier,
-            .prefetch_options,
-            .export_options,
-            .extern_options,
+
             .manyptr_u8,
             .manyptr_const_u8,
             .manyptr_const_u8_sentinel_0,
@@ -5387,21 +5012,14 @@ pub const Type = struct {
             .error_set_inferred,
             .error_set_merged,
             .@"opaque",
-            .generic_poison,
             .array_u8,
             .array_u8_sentinel_0,
             .enum_simple,
             => false,
 
             .single_const_pointer_to_comptime_int,
-            .type,
-            .comptime_int,
-            .enum_literal,
-            .type_info,
             // These are function bodies, not function pointers.
             .function,
-            .null,
-            .undefined,
             => true,
 
             .inferred_alloc_mut => unreachable,
@@ -5701,17 +5319,6 @@ pub const Type = struct {
             .enum_full, .enum_nonexhaustive => ty.cast(Payload.EnumFull).?.data.fields,
             .enum_simple => ty.castTag(.enum_simple).?.data.fields,
             .enum_numbered => ty.castTag(.enum_numbered).?.data.fields,
-            .atomic_order,
-            .atomic_rmw_op,
-            .calling_convention,
-            .address_space,
-            .float_mode,
-            .reduce_op,
-            .modifier,
-            .prefetch_options,
-            .export_options,
-            .extern_options,
-            => @panic("TODO resolve std.builtin types"),
             else => unreachable,
         };
     }
@@ -5779,17 +5386,6 @@ pub const Type = struct {
                 const tag_ty = mod.intType(.unsigned, bits) catch @panic("TODO: handle OOM here");
                 return S.fieldWithRange(tag_ty, enum_tag, fields_len, mod);
             },
-            .atomic_order,
-            .atomic_rmw_op,
-            .calling_convention,
-            .address_space,
-            .float_mode,
-            .reduce_op,
-            .modifier,
-            .prefetch_options,
-            .export_options,
-            .extern_options,
-            => @panic("TODO resolve std.builtin types"),
             else => unreachable,
         }
     }
@@ -6102,18 +5698,6 @@ pub const Type = struct {
                 const opaque_obj = ty.cast(Payload.Opaque).?.data;
                 return opaque_obj.srcLoc(mod);
             },
-            .atomic_order,
-            .atomic_rmw_op,
-            .calling_convention,
-            .address_space,
-            .float_mode,
-            .reduce_op,
-            .modifier,
-            .prefetch_options,
-            .export_options,
-            .extern_options,
-            .type_info,
-            => unreachable, // needed to call resolveTypeFields first
 
             else => return null,
         }
@@ -6150,29 +5734,17 @@ pub const Type = struct {
                 const opaque_obj = ty.cast(Payload.Opaque).?.data;
                 return opaque_obj.owner_decl;
             },
-            .atomic_order,
-            .atomic_rmw_op,
-            .calling_convention,
-            .address_space,
-            .float_mode,
-            .reduce_op,
-            .modifier,
-            .prefetch_options,
-            .export_options,
-            .extern_options,
-            .type_info,
-            => unreachable, // These need to be resolved earlier.
 
             else => return null,
         }
     }
 
     pub fn isGenericPoison(ty: Type) bool {
-        return switch (ty.ip_index) {
-            .generic_poison_type => true,
-            .none => ty.tag() == .generic_poison,
-            else => false,
-        };
+        return ty.ip_index == .generic_poison_type;
+    }
+
+    pub fn isVarArgsParam(ty: Type) bool {
+        return ty.ip_index == .none and ty.tag() == .var_args_param;
     }
 
     /// This enum does not directly correspond to `std.builtin.TypeId` because
@@ -6195,28 +5767,7 @@ pub const Type = struct {
         i64,
         u128,
         i128,
-        anyopaque,
-        bool,
-        void,
-        type,
-        anyerror,
-        comptime_int,
-        noreturn,
-        @"anyframe",
-        null,
-        undefined,
-        enum_literal,
-        atomic_order,
-        atomic_rmw_op,
-        calling_convention,
-        address_space,
-        float_mode,
-        reduce_op,
-        modifier,
-        prefetch_options,
-        export_options,
-        extern_options,
-        type_info,
+
         manyptr_u8,
         manyptr_const_u8,
         manyptr_const_u8_sentinel_0,
@@ -6224,7 +5775,6 @@ pub const Type = struct {
         const_slice_u8,
         const_slice_u8_sentinel_0,
         anyerror_void_error_union,
-        generic_poison,
         /// Same as `empty_struct` except it has an empty namespace.
         empty_struct_literal,
         /// This is a special value that tracks a set of types that have been stored
@@ -6292,39 +5842,17 @@ pub const Type = struct {
                 .i64,
                 .u128,
                 .i128,
-                .anyopaque,
-                .bool,
-                .void,
-                .type,
-                .anyerror,
-                .comptime_int,
-                .noreturn,
-                .enum_literal,
-                .null,
-                .undefined,
+
                 .single_const_pointer_to_comptime_int,
                 .anyerror_void_error_union,
                 .const_slice_u8,
                 .const_slice_u8_sentinel_0,
-                .generic_poison,
                 .inferred_alloc_const,
                 .inferred_alloc_mut,
                 .empty_struct_literal,
                 .manyptr_u8,
                 .manyptr_const_u8,
                 .manyptr_const_u8_sentinel_0,
-                .atomic_order,
-                .atomic_rmw_op,
-                .calling_convention,
-                .address_space,
-                .float_mode,
-                .reduce_op,
-                .modifier,
-                .prefetch_options,
-                .export_options,
-                .extern_options,
-                .type_info,
-                .@"anyframe",
                 => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
 
                 .array_u8,
@@ -6674,18 +6202,19 @@ pub const Type = struct {
     pub const @"f80": Type = .{ .ip_index = .f80_type, .legacy = undefined };
     pub const @"f128": Type = .{ .ip_index = .f128_type, .legacy = undefined };
 
-    pub const @"bool" = initTag(.bool);
+    pub const @"bool": Type = .{ .ip_index = .bool_type, .legacy = undefined };
     pub const @"usize": Type = .{ .ip_index = .usize_type, .legacy = undefined };
     pub const @"isize": Type = .{ .ip_index = .isize_type, .legacy = undefined };
     pub const @"comptime_int": Type = .{ .ip_index = .comptime_int_type, .legacy = undefined };
     pub const @"comptime_float": Type = .{ .ip_index = .comptime_float_type, .legacy = undefined };
-    pub const @"void" = initTag(.void);
-    pub const @"type" = initTag(.type);
-    pub const @"anyerror" = initTag(.anyerror);
-    pub const @"anyopaque" = initTag(.anyopaque);
-    pub const @"null" = initTag(.null);
-    pub const @"undefined" = initTag(.undefined);
-    pub const @"noreturn" = initTag(.noreturn);
+    pub const @"void": Type = .{ .ip_index = .void_type, .legacy = undefined };
+    pub const @"type": Type = .{ .ip_index = .type_type, .legacy = undefined };
+    pub const @"anyerror": Type = .{ .ip_index = .anyerror_type, .legacy = undefined };
+    pub const @"anyopaque": Type = .{ .ip_index = .anyopaque_type, .legacy = undefined };
+    pub const @"anyframe": Type = .{ .ip_index = .anyframe_type, .legacy = undefined };
+    pub const @"null": Type = .{ .ip_index = .null_type, .legacy = undefined };
+    pub const @"undefined": Type = .{ .ip_index = .undefined_type, .legacy = undefined };
+    pub const @"noreturn": Type = .{ .ip_index = .noreturn_type, .legacy = undefined };
 
     pub const @"c_char": Type = .{ .ip_index = .c_char_type, .legacy = undefined };
     pub const @"c_short": Type = .{ .ip_index = .c_short_type, .legacy = undefined };
@@ -6698,6 +6227,8 @@ pub const Type = struct {
     pub const @"c_ulonglong": Type = .{ .ip_index = .c_ulonglong_type, .legacy = undefined };
     pub const @"c_longdouble": Type = .{ .ip_index = .c_longdouble_type, .legacy = undefined };
 
+    pub const generic_poison: Type = .{ .ip_index = .generic_poison_type, .legacy = undefined };
+
     pub const err_int = Type.u16;
 
     pub fn ptr(arena: Allocator, mod: *Module, data: Payload.Pointer.Data) !Type {
src/value.zig
@@ -991,26 +991,26 @@ pub const Value = struct {
             .null_type => Type.null,
             .undefined_type => Type.undefined,
             .single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int),
-            .anyframe_type => Type.initTag(.@"anyframe"),
+            .anyframe_type => Type.@"anyframe",
             .const_slice_u8_type => Type.initTag(.const_slice_u8),
             .const_slice_u8_sentinel_0_type => Type.initTag(.const_slice_u8_sentinel_0),
             .anyerror_void_error_union_type => Type.initTag(.anyerror_void_error_union),
-            .generic_poison_type => Type.initTag(.generic_poison),
-            .enum_literal_type => Type.initTag(.enum_literal),
+            .generic_poison_type => .{ .ip_index = .generic_poison_type, .legacy = undefined },
+            .enum_literal_type => .{ .ip_index = .enum_literal_type, .legacy = undefined },
             .manyptr_u8_type => Type.initTag(.manyptr_u8),
             .manyptr_const_u8_type => Type.initTag(.manyptr_const_u8),
             .manyptr_const_u8_sentinel_0_type => Type.initTag(.manyptr_const_u8_sentinel_0),
-            .atomic_order_type => Type.initTag(.atomic_order),
-            .atomic_rmw_op_type => Type.initTag(.atomic_rmw_op),
-            .calling_convention_type => Type.initTag(.calling_convention),
-            .address_space_type => Type.initTag(.address_space),
-            .float_mode_type => Type.initTag(.float_mode),
-            .reduce_op_type => Type.initTag(.reduce_op),
-            .modifier_type => Type.initTag(.modifier),
-            .prefetch_options_type => Type.initTag(.prefetch_options),
-            .export_options_type => Type.initTag(.export_options),
-            .extern_options_type => Type.initTag(.extern_options),
-            .type_info_type => Type.initTag(.type_info),
+            .atomic_order_type => .{ .ip_index = .atomic_order_type, .legacy = undefined },
+            .atomic_rmw_op_type => .{ .ip_index = .atomic_rmw_op_type, .legacy = undefined },
+            .calling_convention_type => .{ .ip_index = .calling_convention_type, .legacy = undefined },
+            .address_space_type => .{ .ip_index = .address_space_type, .legacy = undefined },
+            .float_mode_type => .{ .ip_index = .float_mode_type, .legacy = undefined },
+            .reduce_op_type => .{ .ip_index = .reduce_op_type, .legacy = undefined },
+            .modifier_type => .{ .ip_index = .call_modifier_type, .legacy = undefined },
+            .prefetch_options_type => .{ .ip_index = .prefetch_options_type, .legacy = undefined },
+            .export_options_type => .{ .ip_index = .export_options_type, .legacy = undefined },
+            .extern_options_type => .{ .ip_index = .extern_options_type, .legacy = undefined },
+            .type_info_type => .{ .ip_index = .type_info_type, .legacy = undefined },
 
             else => unreachable,
         };