Commit 9d9e22e716

Veikka Tuominen <git@vexu.eu>
2023-10-21 11:56:05
remove uses of non-configurable `err_int`
1 parent bf61c5c
doc/langref.html.in
@@ -8373,7 +8373,7 @@ test "main" {
       {#header_close#}
 
       {#header_open|@errorFromInt#}
-      <pre>{#syntax#}@errorFromInt(value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)) anyerror{#endsyntax#}</pre>
+      <pre>{#syntax#}@errorFromInt(value: std.meta.Int(.unsigned, @bitSizeOf(anyerror))) anyerror{#endsyntax#}</pre>
       <p>
       Converts from the integer representation of an error into {#link|The Global Error Set#} type.
       </p>
@@ -8694,7 +8694,7 @@ test "integer cast panic" {
       {#header_close#}
 
       {#header_open|@intFromError#}
-      <pre>{#syntax#}@intFromError(err: anytype) std.meta.Int(.unsigned, @sizeOf(anyerror) * 8){#endsyntax#}</pre>
+      <pre>{#syntax#}@intFromError(err: anytype) std.meta.Int(.unsigned, @bitSizeOf(anyerror)){#endsyntax#}</pre>
       <p>
       Supports the following types:
       </p>
src/arch/wasm/CodeGen.zig
@@ -3296,6 +3296,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
             return WValue{ .imm32 = int };
         },
         .error_union => |error_union| {
+            const err_int_ty = try mod.errorIntType();
             const err_tv: TypedValue = switch (error_union.val) {
                 .err_name => |err_name| .{
                     .ty = ty.errorUnionSet(mod),
@@ -3305,8 +3306,8 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
                     } })).toValue(),
                 },
                 .payload => .{
-                    .ty = Type.err_int,
-                    .val = try mod.intValue(Type.err_int, 0),
+                    .ty = err_int_ty,
+                    .val = try mod.intValue(err_int_ty, 0),
                 },
             };
             const payload_type = ty.errorUnionPayload(mod);
@@ -3705,8 +3706,10 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
     const errors_len = WValue{ .memory = sym_index };
 
     try func.emitWValue(operand);
-    const errors_len_val = try func.load(errors_len, Type.err_int, 0);
-    const result = try func.cmp(.stack, errors_len_val, Type.err_int, .lt);
+    const mod = func.bin_file.base.options.module.?;
+    const err_int_ty = try mod.errorIntType();
+    const errors_len_val = try func.load(errors_len, err_int_ty, 0);
+    const result = try func.cmp(.stack, errors_len_val, err_int_ty, .lt);
 
     return func.finishAir(inst, try result.toLocal(func, Type.bool), &.{un_op});
 }
src/codegen/llvm/Builder.zig
@@ -159,7 +159,6 @@ pub const Type = enum(u32) {
     none = std.math.maxInt(u32),
     _,
 
-    pub const err_int = Type.i16;
     pub const ptr_amdgpu_constant =
         @field(Type, std.fmt.comptimePrint("ptr{ }", .{AddrSpace.amdgpu.constant}));
 
src/codegen/c.zig
@@ -1021,6 +1021,7 @@ pub const DeclGen = struct {
             .error_union => |error_union| {
                 const payload_ty = ty.errorUnionPayload(mod);
                 const error_ty = ty.errorUnionSet(mod);
+                const err_int_ty = try mod.errorIntType();
                 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
                     switch (error_union.val) {
                         .err_name => |err_name| return dg.renderValue(
@@ -1034,8 +1035,8 @@ pub const DeclGen = struct {
                         ),
                         .payload => return dg.renderValue(
                             writer,
-                            Type.err_int,
-                            try mod.intValue(Type.err_int, 0),
+                            err_int_ty,
+                            try mod.intValue(err_int_ty, 0),
                             location,
                         ),
                     }
@@ -1070,8 +1071,8 @@ pub const DeclGen = struct {
                     ),
                     .payload => try dg.renderValue(
                         writer,
-                        Type.err_int,
-                        try mod.intValue(Type.err_int, 0),
+                        err_int_ty,
+                        try mod.intValue(err_int_ty, 0),
                         location,
                     ),
                 }
@@ -1227,7 +1228,7 @@ pub const DeclGen = struct {
                     payload_ty,
                     switch (opt.val) {
                         .none => switch (payload_ty.zigTypeTag(mod)) {
-                            .ErrorSet => try mod.intValue(Type.err_int, 0),
+                            .ErrorSet => try mod.intValue(try mod.errorIntType(), 0),
                             .Pointer => try mod.getCoerced(val, payload_ty),
                             else => unreachable,
                         },
@@ -5179,6 +5180,7 @@ fn airIsNull(
     const operand_ty = f.typeOf(un_op);
     const optional_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty;
     const payload_ty = optional_ty.optionalChild(mod);
+    const err_int_ty = try mod.errorIntType();
 
     const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))
         TypedValue{ .ty = Type.bool, .val = Value.true }
@@ -5186,7 +5188,7 @@ fn airIsNull(
         // operand is a regular pointer, test `operand !=/== NULL`
         TypedValue{ .ty = optional_ty, .val = try mod.getCoerced(Value.null, optional_ty) }
     else if (payload_ty.zigTypeTag(mod) == .ErrorSet)
-        TypedValue{ .ty = Type.err_int, .val = try mod.intValue(Type.err_int, 0) }
+        TypedValue{ .ty = err_int_ty, .val = try mod.intValue(err_int_ty, 0) }
     else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: {
         try writer.writeAll(".ptr");
         const slice_ptr_ty = payload_ty.slicePtrFieldType(mod);
@@ -5672,8 +5674,10 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
                 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })
             else
                 try f.writeCValueMember(writer, operand, .{ .identifier = "error" })
-        else
-            try f.object.dg.renderValue(writer, Type.err_int, try mod.intValue(Type.err_int, 0), .Initializer);
+        else {
+            const err_int_ty = try mod.errorIntType();
+            try f.object.dg.renderValue(writer, err_int_ty, try mod.intValue(err_int_ty, 0), .Initializer);
+        }
     }
     try writer.writeAll(";\n");
     return local;
@@ -5794,12 +5798,13 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
     const error_union_ty = f.typeOf(ty_op.operand).childType(mod);
 
     const payload_ty = error_union_ty.errorUnionPayload(mod);
+    const err_int_ty = try mod.errorIntType();
 
     // First, set the non-error value.
     if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
         try f.writeCValueDeref(writer, operand);
         try writer.writeAll(" = ");
-        try f.object.dg.renderValue(writer, Type.err_int, try mod.intValue(Type.err_int, 0), .Other);
+        try f.object.dg.renderValue(writer, err_int_ty, try mod.intValue(err_int_ty, 0), .Other);
         try writer.writeAll(";\n ");
 
         return operand;
@@ -5807,7 +5812,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
     try reap(f, inst, &.{ty_op.operand});
     try f.writeCValueDeref(writer, operand);
     try writer.writeAll(".error = ");
-    try f.object.dg.renderValue(writer, Type.err_int, try mod.intValue(Type.err_int, 0), .Other);
+    try f.object.dg.renderValue(writer, err_int_ty, try mod.intValue(err_int_ty, 0), .Other);
     try writer.writeAll(";\n");
 
     // Then return the payload pointer (only if it is used)
@@ -5863,7 +5868,8 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
         else
             try f.writeCValueMember(writer, local, .{ .identifier = "error" });
         try a.assign(f, writer);
-        try f.object.dg.renderValue(writer, Type.err_int, try mod.intValue(Type.err_int, 0), .Other);
+        const err_int_ty = try mod.errorIntType();
+        try f.object.dg.renderValue(writer, err_int_ty, try mod.intValue(err_int_ty, 0), .Other);
         try a.end(f, writer);
     }
     return local;
@@ -5885,6 +5891,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
     try f.writeCValue(writer, local, .Other);
     try writer.writeAll(" = ");
 
+    const err_int_ty = try mod.errorIntType();
     if (!error_ty.errorSetIsEmpty(mod))
         if (payload_ty.hasRuntimeBits(mod))
             if (is_ptr)
@@ -5894,11 +5901,11 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
         else
             try f.writeCValue(writer, operand, .Other)
     else
-        try f.object.dg.renderValue(writer, Type.err_int, try mod.intValue(Type.err_int, 0), .Other);
+        try f.object.dg.renderValue(writer, err_int_ty, try mod.intValue(err_int_ty, 0), .Other);
     try writer.writeByte(' ');
     try writer.writeAll(operator);
     try writer.writeByte(' ');
-    try f.object.dg.renderValue(writer, Type.err_int, try mod.intValue(Type.err_int, 0), .Other);
+    try f.object.dg.renderValue(writer, err_int_ty, try mod.intValue(err_int_ty, 0), .Other);
     try writer.writeAll(";\n");
     return local;
 }
src/codegen/llvm.zig
@@ -1111,7 +1111,7 @@ pub const Object = struct {
         // }
 
         const lhs = wip.arg(0);
-        const rhs = try o.builder.intValue(Builder.Type.err_int, errors_len);
+        const rhs = try o.builder.intValue(try o.errorIntType(), errors_len);
         const is_lt = try wip.icmp(.ult, lhs, rhs, "");
         _ = try wip.ret(is_lt);
         try wip.finish();
@@ -3111,6 +3111,10 @@ pub const Object = struct {
         return variable_index;
     }
 
+    fn errorIntType(o: *Object) Allocator.Error!Builder.Type {
+        return o.builder.intType(o.module.errorSetBits());
+    }
+
     fn lowerType(o: *Object, t: Type) Allocator.Error!Builder.Type {
         const ty = try o.lowerTypeInner(t);
         const mod = o.module;
@@ -3182,7 +3186,7 @@ pub const Object = struct {
             .bool_type => .i1,
             .void_type => .void,
             .type_type => unreachable,
-            .anyerror_type => Builder.Type.err_int,
+            .anyerror_type => try o.errorIntType(),
             .comptime_int_type,
             .comptime_float_type,
             .noreturn_type,
@@ -3203,7 +3207,7 @@ pub const Object = struct {
             .optional_noreturn_type => unreachable,
             .anyerror_void_error_union_type,
             .adhoc_inferred_error_set_type,
-            => Builder.Type.err_int,
+            => try o.errorIntType(),
             .generic_poison_type,
             .empty_struct_type,
             => unreachable,
@@ -3272,16 +3276,17 @@ pub const Object = struct {
                 },
                 .anyframe_type => @panic("TODO implement lowerType for AnyFrame types"),
                 .error_union_type => |error_union_type| {
-                    const error_type = Builder.Type.err_int;
+                    const error_type = try o.errorIntType();
                     if (!error_union_type.payload_type.toType().hasRuntimeBitsIgnoreComptime(mod))
                         return error_type;
                     const payload_type = try o.lowerType(error_union_type.payload_type.toType());
+                    const err_int_ty = try mod.errorIntType();
 
                     const payload_align = error_union_type.payload_type.toType().abiAlignment(mod);
-                    const error_align = Type.err_int.abiAlignment(mod);
+                    const error_align = err_int_ty.abiAlignment(mod);
 
                     const payload_size = error_union_type.payload_type.toType().abiSize(mod);
-                    const error_size = Type.err_int.abiSize(mod);
+                    const error_size = err_int_ty.abiSize(mod);
 
                     var fields: [3]Builder.Type = undefined;
                     var fields_len: usize = 2;
@@ -3542,7 +3547,7 @@ pub const Object = struct {
                 },
                 .enum_type => |enum_type| try o.lowerType(enum_type.tag_ty.toType()),
                 .func_type => |func_type| try o.lowerTypeFn(func_type),
-                .error_set_type, .inferred_error_set_type => Builder.Type.err_int,
+                .error_set_type, .inferred_error_set_type => try o.errorIntType(),
                 // values, not types
                 .undef,
                 .runtime_value,
@@ -3725,7 +3730,7 @@ pub const Object = struct {
             },
             .err => |err| {
                 const int = try mod.getErrorValue(err.name);
-                const llvm_int = try o.builder.intConst(Builder.Type.err_int, int);
+                const llvm_int = try o.builder.intConst(try o.errorIntType(), int);
                 return llvm_int;
             },
             .error_union => |error_union| {
@@ -3734,8 +3739,9 @@ pub const Object = struct {
                         .ty = ty.errorUnionSet(mod).toIntern(),
                         .name = err_name,
                     } }),
-                    .payload => (try mod.intValue(Type.err_int, 0)).toIntern(),
+                    .payload => (try mod.intValue(try mod.errorIntType(), 0)).toIntern(),
                 };
+                const err_int_ty = try mod.errorIntType();
                 const payload_type = ty.errorUnionPayload(mod);
                 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
                     // We use the error type directly as the type.
@@ -3743,7 +3749,7 @@ pub const Object = struct {
                 }
 
                 const payload_align = payload_type.abiAlignment(mod);
-                const error_align = Type.err_int.abiAlignment(mod);
+                const error_align = err_int_ty.abiAlignment(mod);
                 const llvm_error_value = try o.lowerValue(err_val);
                 const llvm_payload_value = try o.lowerValue(switch (error_union.val) {
                     .err_name => try mod.intern(.{ .undef = payload_type.toIntern() }),
@@ -4285,8 +4291,9 @@ pub const Object = struct {
                     return parent_ptr;
                 }
 
+                const err_int_ty = try mod.errorIntType();
                 const payload_align = payload_ty.abiAlignment(mod);
-                const err_align = Type.err_int.abiAlignment(mod);
+                const err_align = err_int_ty.abiAlignment(mod);
                 const index: u32 = if (payload_align.compare(.gt, err_align)) 2 else 1;
                 return o.builder.gepConst(.inbounds, try o.lowerType(eu_ty), parent_ptr, null, &.{
                     try o.builder.intConst(.i32, 0), try o.builder.intConst(.i32, index),
@@ -5399,7 +5406,7 @@ pub const FuncGen = struct {
                 // Functions with an empty error set are emitted with an error code
                 // return type and return zero so they can be function pointers coerced
                 // to functions that return anyerror.
-                _ = try self.wip.ret(try o.builder.intValue(Builder.Type.err_int, 0));
+                _ = try self.wip.ret(try o.builder.intValue(try o.errorIntType(), 0));
             } else {
                 _ = try self.wip.retVoid();
             }
@@ -5441,7 +5448,7 @@ pub const FuncGen = struct {
                 // Functions with an empty error set are emitted with an error code
                 // return type and return zero so they can be function pointers coerced
                 // to functions that return anyerror.
-                _ = try self.wip.ret(try o.builder.intValue(Builder.Type.err_int, 0));
+                _ = try self.wip.ret(try o.builder.intValue(try o.errorIntType(), 0));
             } else {
                 _ = try self.wip.retVoid();
             }
@@ -5788,24 +5795,25 @@ pub const FuncGen = struct {
         const payload_ty = err_union_ty.errorUnionPayload(mod);
         const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);
         const err_union_llvm_ty = try o.lowerType(err_union_ty);
+        const error_type = try o.errorIntType();
 
         if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
             const loaded = loaded: {
                 if (!payload_has_bits) {
                     // TODO add alignment to this load
                     break :loaded if (operand_is_ptr)
-                        try fg.wip.load(.normal, Builder.Type.err_int, err_union, .default, "")
+                        try fg.wip.load(.normal, error_type, err_union, .default, "")
                     else
                         err_union;
                 }
-                const err_field_index = errUnionErrorOffset(payload_ty, mod);
+                const err_field_index = try errUnionErrorOffset(payload_ty, mod);
                 if (operand_is_ptr or isByRef(err_union_ty, mod)) {
                     const err_field_ptr =
                         try fg.wip.gepStruct(err_union_llvm_ty, err_union, err_field_index, "");
                     // TODO add alignment to this load
                     break :loaded try fg.wip.load(
                         .normal,
-                        Builder.Type.err_int,
+                        error_type,
                         err_field_ptr,
                         .default,
                         "",
@@ -5813,7 +5821,7 @@ pub const FuncGen = struct {
                 }
                 break :loaded try fg.wip.extractValue(err_union, &.{err_field_index}, "");
             };
-            const zero = try o.builder.intValue(Builder.Type.err_int, 0);
+            const zero = try o.builder.intValue(error_type, 0);
             const is_err = try fg.wip.icmp(.ne, loaded, zero, "");
 
             const return_block = try fg.wip.block(1, "TryRet");
@@ -5827,7 +5835,7 @@ pub const FuncGen = struct {
         }
         if (is_unused) return .none;
         if (!payload_has_bits) return if (operand_is_ptr) err_union else .none;
-        const offset = errUnionPayloadOffset(payload_ty, mod);
+        const offset = try errUnionPayloadOffset(payload_ty, mod);
         if (operand_is_ptr) {
             return fg.wip.gepStruct(err_union_llvm_ty, err_union, offset, "");
         } else if (isByRef(err_union_ty, mod)) {
@@ -7053,7 +7061,8 @@ pub const FuncGen = struct {
         const operand_ty = self.typeOf(un_op);
         const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
         const payload_ty = err_union_ty.errorUnionPayload(mod);
-        const zero = try o.builder.intValue(Builder.Type.err_int, 0);
+        const error_type = try o.errorIntType();
+        const zero = try o.builder.intValue(error_type, 0);
 
         if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
             const val: Builder.Constant = switch (cond) {
@@ -7072,13 +7081,13 @@ pub const FuncGen = struct {
             return self.wip.icmp(cond, loaded, zero, "");
         }
 
-        const err_field_index = errUnionErrorOffset(payload_ty, mod);
+        const err_field_index = try errUnionErrorOffset(payload_ty, mod);
 
         const loaded = if (operand_is_ptr or isByRef(err_union_ty, mod)) loaded: {
             const err_union_llvm_ty = try o.lowerType(err_union_ty);
             const err_field_ptr =
                 try self.wip.gepStruct(err_union_llvm_ty, operand, err_field_index, "");
-            break :loaded try self.wip.load(.normal, Builder.Type.err_int, err_field_ptr, .default, "");
+            break :loaded try self.wip.load(.normal, error_type, err_field_ptr, .default, "");
         } else try self.wip.extractValue(operand, &.{err_field_index}, "");
         return self.wip.icmp(cond, loaded, zero, "");
     }
@@ -7173,7 +7182,7 @@ pub const FuncGen = struct {
         if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
             return if (operand_is_ptr) operand else .none;
         }
-        const offset = errUnionPayloadOffset(payload_ty, mod);
+        const offset = try errUnionPayloadOffset(payload_ty, mod);
         const err_union_llvm_ty = try o.lowerType(err_union_ty);
         if (operand_is_ptr) {
             return self.wip.gepStruct(err_union_llvm_ty, operand, offset, "");
@@ -7200,27 +7209,28 @@ pub const FuncGen = struct {
         const ty_op = self.air.instructions.items(.data)[inst].ty_op;
         const operand = try self.resolveInst(ty_op.operand);
         const operand_ty = self.typeOf(ty_op.operand);
+        const error_type = try o.errorIntType();
         const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
         if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
             if (operand_is_ptr) {
                 return operand;
             } else {
-                return o.builder.intValue(Builder.Type.err_int, 0);
+                return o.builder.intValue(error_type, 0);
             }
         }
 
         const payload_ty = err_union_ty.errorUnionPayload(mod);
         if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
             if (!operand_is_ptr) return operand;
-            return self.wip.load(.normal, Builder.Type.err_int, operand, .default, "");
+            return self.wip.load(.normal, error_type, operand, .default, "");
         }
 
-        const offset = errUnionErrorOffset(payload_ty, mod);
+        const offset = try errUnionErrorOffset(payload_ty, mod);
 
         if (operand_is_ptr or isByRef(err_union_ty, mod)) {
             const err_union_llvm_ty = try o.lowerType(err_union_ty);
             const err_field_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, "");
-            return self.wip.load(.normal, Builder.Type.err_int, err_field_ptr, .default, "");
+            return self.wip.load(.normal, error_type, err_field_ptr, .default, "");
         }
 
         return self.wip.extractValue(operand, &.{offset}, "");
@@ -7234,15 +7244,16 @@ pub const FuncGen = struct {
         const err_union_ty = self.typeOf(ty_op.operand).childType(mod);
 
         const payload_ty = err_union_ty.errorUnionPayload(mod);
-        const non_error_val = try o.builder.intValue(Builder.Type.err_int, 0);
+        const non_error_val = try o.builder.intValue(try o.errorIntType(), 0);
         if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
             _ = try self.wip.store(.normal, non_error_val, operand, .default);
             return operand;
         }
         const err_union_llvm_ty = try o.lowerType(err_union_ty);
         {
-            const error_alignment = Type.err_int.abiAlignment(mod).toLlvm();
-            const error_offset = errUnionErrorOffset(payload_ty, mod);
+            const err_int_ty = try mod.errorIntType();
+            const error_alignment = err_int_ty.abiAlignment(mod).toLlvm();
+            const error_offset = try errUnionErrorOffset(payload_ty, mod);
             // First set the non-error value.
             const non_null_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, error_offset, "");
             _ = try self.wip.store(.normal, non_error_val, non_null_ptr, error_alignment);
@@ -7250,7 +7261,7 @@ pub const FuncGen = struct {
         // Then return the payload pointer (only if it is used).
         if (self.liveness.isUnused(inst)) return .none;
 
-        const payload_offset = errUnionPayloadOffset(payload_ty, mod);
+        const payload_offset = try errUnionPayloadOffset(payload_ty, mod);
         return self.wip.gepStruct(err_union_llvm_ty, operand, payload_offset, "");
     }
 
@@ -7353,11 +7364,11 @@ pub const FuncGen = struct {
         if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
             return operand;
         }
-        const ok_err_code = try o.builder.intValue(Builder.Type.err_int, 0);
+        const ok_err_code = try o.builder.intValue(try o.errorIntType(), 0);
         const err_un_llvm_ty = try o.lowerType(err_un_ty);
 
-        const payload_offset = errUnionPayloadOffset(payload_ty, mod);
-        const error_offset = errUnionErrorOffset(payload_ty, mod);
+        const payload_offset = try errUnionPayloadOffset(payload_ty, mod);
+        const error_offset = try errUnionErrorOffset(payload_ty, mod);
         if (isByRef(err_un_ty, mod)) {
             const directReturn = self.isNextRet(body_tail);
             const result_ptr = if (directReturn)
@@ -7369,7 +7380,8 @@ pub const FuncGen = struct {
             };
 
             const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, "");
-            const error_alignment = Type.err_int.abiAlignment(mod).toLlvm();
+            const err_int_ty = try mod.errorIntType();
+            const error_alignment = err_int_ty.abiAlignment(mod).toLlvm();
             _ = try self.wip.store(.normal, ok_err_code, err_ptr, error_alignment);
             const payload_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, payload_offset, "");
             const payload_ptr_ty = try mod.singleMutPtrType(payload_ty);
@@ -7393,8 +7405,8 @@ pub const FuncGen = struct {
         if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return operand;
         const err_un_llvm_ty = try o.lowerType(err_un_ty);
 
-        const payload_offset = errUnionPayloadOffset(payload_ty, mod);
-        const error_offset = errUnionErrorOffset(payload_ty, mod);
+        const payload_offset = try errUnionPayloadOffset(payload_ty, mod);
+        const error_offset = try errUnionErrorOffset(payload_ty, mod);
         if (isByRef(err_un_ty, mod)) {
             const directReturn = self.isNextRet(body_tail);
             const result_ptr = if (directReturn)
@@ -7406,7 +7418,8 @@ pub const FuncGen = struct {
             };
 
             const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, "");
-            const error_alignment = Type.err_int.abiAlignment(mod).toLlvm();
+            const err_int_ty = try mod.errorIntType();
+            const error_alignment = err_int_ty.abiAlignment(mod).toLlvm();
             _ = try self.wip.store(.normal, operand, err_ptr, error_alignment);
             const payload_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, payload_offset, "");
             const payload_ptr_ty = try mod.singleMutPtrType(payload_ty);
@@ -9363,7 +9376,7 @@ pub const FuncGen = struct {
 
         for (names) |name| {
             const err_int = mod.global_error_set.getIndex(name).?;
-            const this_tag_int_value = try o.builder.intConst(Builder.Type.err_int, err_int);
+            const this_tag_int_value = try o.builder.intConst(try o.errorIntType(), err_int);
             try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip);
         }
         self.wip.cursor = .{ .block = valid_block };
@@ -9545,7 +9558,7 @@ pub const FuncGen = struct {
         if (o.builder.getGlobal(name)) |llvm_fn| return llvm_fn.ptrConst(&o.builder).kind.function;
 
         const function_index = try o.builder.addFunction(
-            try o.builder.fnType(.i1, &.{Builder.Type.err_int}, .normal),
+            try o.builder.fnType(.i1, &.{try o.errorIntType()}, .normal),
             name,
             toLlvmAddressSpace(.generic, o.module.getTarget()),
         );
@@ -10880,7 +10893,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu
         // If the return type is an error set or an error union, then we make this
         // anyerror return type instead, so that it can be coerced into a function
         // pointer type which has anyerror as the return type.
-        return if (return_type.isError(mod)) Builder.Type.err_int else .void;
+        return if (return_type.isError(mod)) try o.errorIntType() else .void;
     }
     const target = mod.getTarget();
     switch (fn_info.cc) {
@@ -11633,12 +11646,14 @@ fn buildAllocaInner(
     return wip.conv(.unneeded, alloca, .ptr, "");
 }
 
-fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) u1 {
-    return @intFromBool(Type.err_int.abiAlignment(mod).compare(.gt, payload_ty.abiAlignment(mod)));
+fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) !u1 {
+    const err_int_ty = try mod.errorIntType();
+    return @intFromBool(err_int_ty.abiAlignment(mod).compare(.gt, payload_ty.abiAlignment(mod)));
 }
 
-fn errUnionErrorOffset(payload_ty: Type, mod: *Module) u1 {
-    return @intFromBool(Type.err_int.abiAlignment(mod).compare(.lte, payload_ty.abiAlignment(mod)));
+fn errUnionErrorOffset(payload_ty: Type, mod: *Module) !u1 {
+    const err_int_ty = try mod.errorIntType();
+    return @intFromBool(err_int_ty.abiAlignment(mod).compare(.lte, payload_ty.abiAlignment(mod)));
 }
 
 /// Returns true for asm constraint (e.g. "=*m", "=r") if it accepts a memory location
src/codegen/spirv.zig
@@ -742,16 +742,17 @@ const DeclGen = struct {
             .error_union => |error_union| {
                 // TODO: Error unions may be constructed with constant instructions if the payload type
                 // allows it. For now, just generate it here regardless.
+                const err_int_ty = try mod.errorIntType();
                 const err_ty = switch (error_union.val) {
                     .err_name => ty.errorUnionSet(mod),
-                    .payload => Type.err_int,
+                    .payload => err_int_ty,
                 };
                 const err_val = switch (error_union.val) {
                     .err_name => |err_name| (try mod.intern(.{ .err = .{
                         .ty = ty.errorUnionSet(mod).toIntern(),
                         .name = err_name,
                     } })).toValue(),
-                    .payload => try mod.intValue(Type.err_int, 0),
+                    .payload => try mod.intValue(err_int_ty, 0),
                 };
                 const payload_ty = ty.errorUnionPayload(mod);
                 const eu_layout = self.errorUnionLayout(payload_ty);
src/AstGen.zig
@@ -8430,7 +8430,7 @@ fn builtinCall(
             return rvalue(gz, ri, result, node);
         },
         .error_from_int => {
-            const operand = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, params[0]);
+            const operand = try expr(gz, scope, .{ .rl = .none }, params[0]);
             const result = try gz.addExtendedPayload(.error_from_int, Zir.Inst.UnNode{
                 .node = gz.nodeIndexToRelative(node),
                 .operand = operand,
src/codegen.zig
@@ -1052,6 +1052,7 @@ pub fn genTypedValue(
             const payload_type = typed_value.ty.errorUnionPayload(mod);
             if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
                 // We use the error type directly as the type.
+                const err_int_ty = try mod.errorIntType();
                 switch (mod.intern_pool.indexToKey(typed_value.val.toIntern()).error_union.val) {
                     .err_name => |err_name| return genTypedValue(bin_file, src_loc, .{
                         .ty = err_type,
@@ -1061,8 +1062,8 @@ pub fn genTypedValue(
                         } })).toValue(),
                     }, owner_decl_index),
                     .payload => return genTypedValue(bin_file, src_loc, .{
-                        .ty = Type.err_int,
-                        .val = try mod.intValue(Type.err_int, 0),
+                        .ty = err_int_ty,
+                        .val = try mod.intValue(err_int_ty, 0),
                     }, owner_decl_index),
                 }
             }
src/Module.zig
@@ -5906,6 +5906,10 @@ pub fn intType(mod: *Module, signedness: std.builtin.Signedness, bits: u16) Allo
     } })).toType();
 }
 
+pub fn errorIntType(mod: *Module) std.mem.Allocator.Error!Type {
+    return mod.intType(.unsigned, mod.errorSetBits());
+}
+
 pub fn arrayType(mod: *Module, info: InternPool.Key.ArrayType) Allocator.Error!Type {
     const i = try intern(mod, .{ .array_type = info });
     return i.toType();
src/Sema.zig
@@ -8384,14 +8384,15 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
     const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
     const uncasted_operand = try sema.resolveInst(extra.operand);
     const operand = try sema.coerce(block, Type.anyerror, uncasted_operand, operand_src);
+    const err_int_ty = try mod.errorIntType();
 
     if (try sema.resolveMaybeUndefVal(operand)) |val| {
         if (val.isUndef(mod)) {
-            return mod.undefRef(Type.err_int);
+            return mod.undefRef(err_int_ty);
         }
         const err_name = ip.indexToKey(val.toIntern()).err.name;
         return Air.internedToRef((try mod.intValue(
-            Type.err_int,
+            err_int_ty,
             try mod.getErrorValue(err_name),
         )).toIntern());
     }
@@ -8402,10 +8403,10 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
         else => |err_set_ty_index| {
             const names = ip.indexToKey(err_set_ty_index).error_set_type.names;
             switch (names.len) {
-                0 => return Air.internedToRef((try mod.intValue(Type.err_int, 0)).toIntern()),
+                0 => return Air.internedToRef((try mod.intValue(err_int_ty, 0)).toIntern()),
                 1 => {
                     const int: Module.ErrorInt = @intCast(mod.global_error_set.getIndex(names.get(ip)[0]).?);
-                    return mod.intRef(Type.err_int, int);
+                    return mod.intRef(err_int_ty, int);
                 },
                 else => {},
             }
@@ -8413,7 +8414,7 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
     }
 
     try sema.requireRuntimeBlock(block, src, operand_src);
-    return block.addBitCast(Type.err_int, operand);
+    return block.addBitCast(err_int_ty, operand);
 }
 
 fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
@@ -8425,7 +8426,8 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
     const src = LazySrcLoc.nodeOffset(extra.node);
     const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
     const uncasted_operand = try sema.resolveInst(extra.operand);
-    const operand = try sema.coerce(block, Type.err_int, uncasted_operand, operand_src);
+    const err_int_ty = try mod.errorIntType();
+    const operand = try sema.coerce(block, err_int_ty, uncasted_operand, operand_src);
 
     if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {
         const int = try sema.usizeCast(block, operand_src, value.toUnsignedInt(mod));
@@ -8439,7 +8441,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
     try sema.requireRuntimeBlock(block, src, operand_src);
     if (block.wantSafety()) {
         const is_lt_len = try block.addUnOp(.cmp_lt_errors_len, operand);
-        const zero_val = Air.internedToRef((try mod.intValue(Type.err_int, 0)).toIntern());
+        const zero_val = Air.internedToRef((try mod.intValue(err_int_ty, 0)).toIntern());
         const is_non_zero = try block.addBinOp(.cmp_neq, operand, zero_val);
         const ok = try block.addBinOp(.bool_and, is_lt_len, is_non_zero);
         try sema.addSafetyCheck(block, src, ok, .invalid_error_code);
@@ -21899,10 +21901,11 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
     }
 
     try sema.requireRuntimeBlock(block, src, operand_src);
+    const err_int_ty = try mod.errorIntType();
     if (block.wantSafety() and !dest_ty.isAnyError(mod) and sema.mod.backendSupportsFeature(.error_set_has_value)) {
         if (dest_tag == .ErrorUnion) {
             const err_code = try sema.analyzeErrUnionCode(block, operand_src, operand);
-            const err_int = try block.addBitCast(Type.err_int, err_code);
+            const err_int = try block.addBitCast(err_int_ty, err_code);
             const zero_u16 = Air.internedToRef(try mod.intern(.{
                 .int = .{ .ty = .u16_type, .storage = .{ .u64 = 0 } },
             }));
@@ -21918,7 +21921,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
                 try sema.addSafetyCheck(block, src, ok, .invalid_error_code);
             }
         } else {
-            const err_int_inst = try block.addBitCast(Type.err_int, operand);
+            const err_int_inst = try block.addBitCast(err_int_ty, operand);
             const ok = try block.addTyOp(.error_set_has_value, dest_ty, err_int_inst);
             try sema.addSafetyCheck(block, src, ok, .invalid_error_code);
         }
src/type.zig
@@ -3309,8 +3309,6 @@ pub const Type = struct {
 
     pub const generic_poison: Type = .{ .ip_index = .generic_poison_type };
 
-    pub const err_int = Type.u16;
-
     pub fn smallestUnsignedBits(max: u64) u16 {
         if (max == 0) return 0;
         const base = std.math.log2(max);