authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-10-21 12:56:05+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-10-22 14:29:26+03:00
log9d9e22e716a4b6de9a26f2553ea5c980efc79d4a
tree7f66f1f1026ab48ca42836ef95a86c9edf2416a0
parentbf61c5c0656e3b2198fb009fe5cc59f55263ceae

remove uses of non-configurable `err_int`


11 files changed, 111 insertions(+), 80 deletions(-)

doc/langref.html.in+2-2
...@@ -8373,7 +8373,7 @@ test "main" {...@@ -8373,7 +8373,7 @@ test "main" {
8373 {#header_close#}8373 {#header_close#}
83748374
8375 {#header_open|@errorFromInt#}8375 {#header_open|@errorFromInt#}
8376 <pre>{#syntax#}@errorFromInt(value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)) anyerror{#endsyntax#}</pre>8376 <pre>{#syntax#}@errorFromInt(value: std.meta.Int(.unsigned, @bitSizeOf(anyerror))) anyerror{#endsyntax#}</pre>
8377 <p>8377 <p>
8378 Converts from the integer representation of an error into {#link|The Global Error Set#} type.8378 Converts from the integer representation of an error into {#link|The Global Error Set#} type.
8379 </p>8379 </p>
...@@ -8694,7 +8694,7 @@ test "integer cast panic" {...@@ -8694,7 +8694,7 @@ test "integer cast panic" {
8694 {#header_close#}8694 {#header_close#}
86958695
8696 {#header_open|@intFromError#}8696 {#header_open|@intFromError#}
8697 <pre>{#syntax#}@intFromError(err: anytype) std.meta.Int(.unsigned, @sizeOf(anyerror) * 8){#endsyntax#}</pre>8697 <pre>{#syntax#}@intFromError(err: anytype) std.meta.Int(.unsigned, @bitSizeOf(anyerror)){#endsyntax#}</pre>
8698 <p>8698 <p>
8699 Supports the following types:8699 Supports the following types:
8700 </p>8700 </p>
src/AstGen.zig+1-1
...@@ -8430,7 +8430,7 @@ fn builtinCall(...@@ -8430,7 +8430,7 @@ fn builtinCall(
8430 return rvalue(gz, ri, result, node);8430 return rvalue(gz, ri, result, node);
8431 },8431 },
8432 .error_from_int => {8432 .error_from_int => {
8433 const operand = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, params[0]);8433 const operand = try expr(gz, scope, .{ .rl = .none }, params[0]);
8434 const result = try gz.addExtendedPayload(.error_from_int, Zir.Inst.UnNode{8434 const result = try gz.addExtendedPayload(.error_from_int, Zir.Inst.UnNode{
8435 .node = gz.nodeIndexToRelative(node),8435 .node = gz.nodeIndexToRelative(node),
8436 .operand = operand,8436 .operand = operand,
src/Module.zig+4
...@@ -5906,6 +5906,10 @@ pub fn intType(mod: *Module, signedness: std.builtin.Signedness, bits: u16) Allo...@@ -5906,6 +5906,10 @@ pub fn intType(mod: *Module, signedness: std.builtin.Signedness, bits: u16) Allo
5906 } })).toType();5906 } })).toType();
5907}5907}
59085908
5909pub fn errorIntType(mod: *Module) std.mem.Allocator.Error!Type {
5910 return mod.intType(.unsigned, mod.errorSetBits());
5911}
5912
5909pub fn arrayType(mod: *Module, info: InternPool.Key.ArrayType) Allocator.Error!Type {5913pub fn arrayType(mod: *Module, info: InternPool.Key.ArrayType) Allocator.Error!Type {
5910 const i = try intern(mod, .{ .array_type = info });5914 const i = try intern(mod, .{ .array_type = info });
5911 return i.toType();5915 return i.toType();
src/Sema.zig+12-9
...@@ -8384,14 +8384,15 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8384,14 +8384,15 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8384 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };8384 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
8385 const uncasted_operand = try sema.resolveInst(extra.operand);8385 const uncasted_operand = try sema.resolveInst(extra.operand);
8386 const operand = try sema.coerce(block, Type.anyerror, uncasted_operand, operand_src);8386 const operand = try sema.coerce(block, Type.anyerror, uncasted_operand, operand_src);
8387 const err_int_ty = try mod.errorIntType();
83878388
8388 if (try sema.resolveMaybeUndefVal(operand)) |val| {8389 if (try sema.resolveMaybeUndefVal(operand)) |val| {
8389 if (val.isUndef(mod)) {8390 if (val.isUndef(mod)) {
8390 return mod.undefRef(Type.err_int);8391 return mod.undefRef(err_int_ty);
8391 }8392 }
8392 const err_name = ip.indexToKey(val.toIntern()).err.name;8393 const err_name = ip.indexToKey(val.toIntern()).err.name;
8393 return Air.internedToRef((try mod.intValue(8394 return Air.internedToRef((try mod.intValue(
8394 Type.err_int,8395 err_int_ty,
8395 try mod.getErrorValue(err_name),8396 try mod.getErrorValue(err_name),
8396 )).toIntern());8397 )).toIntern());
8397 }8398 }
...@@ -8402,10 +8403,10 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8402,10 +8403,10 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8402 else => |err_set_ty_index| {8403 else => |err_set_ty_index| {
8403 const names = ip.indexToKey(err_set_ty_index).error_set_type.names;8404 const names = ip.indexToKey(err_set_ty_index).error_set_type.names;
8404 switch (names.len) {8405 switch (names.len) {
8405 0 => return Air.internedToRef((try mod.intValue(Type.err_int, 0)).toIntern()),8406 0 => return Air.internedToRef((try mod.intValue(err_int_ty, 0)).toIntern()),
8406 1 => {8407 1 => {
8407 const int: Module.ErrorInt = @intCast(mod.global_error_set.getIndex(names.get(ip)[0]).?);8408 const int: Module.ErrorInt = @intCast(mod.global_error_set.getIndex(names.get(ip)[0]).?);
8408 return mod.intRef(Type.err_int, int);8409 return mod.intRef(err_int_ty, int);
8409 },8410 },
8410 else => {},8411 else => {},
8411 }8412 }
...@@ -8413,7 +8414,7 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8413,7 +8414,7 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8413 }8414 }
84148415
8415 try sema.requireRuntimeBlock(block, src, operand_src);8416 try sema.requireRuntimeBlock(block, src, operand_src);
8416 return block.addBitCast(Type.err_int, operand);8417 return block.addBitCast(err_int_ty, operand);
8417}8418}
84188419
8419fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {8420fn 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...@@ -8425,7 +8426,8 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8425 const src = LazySrcLoc.nodeOffset(extra.node);8426 const src = LazySrcLoc.nodeOffset(extra.node);
8426 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };8427 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
8427 const uncasted_operand = try sema.resolveInst(extra.operand);8428 const uncasted_operand = try sema.resolveInst(extra.operand);
8428 const operand = try sema.coerce(block, Type.err_int, uncasted_operand, operand_src);8429 const err_int_ty = try mod.errorIntType();
8430 const operand = try sema.coerce(block, err_int_ty, uncasted_operand, operand_src);
84298431
8430 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {8432 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {
8431 const int = try sema.usizeCast(block, operand_src, value.toUnsignedInt(mod));8433 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...@@ -8439,7 +8441,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8439 try sema.requireRuntimeBlock(block, src, operand_src);8441 try sema.requireRuntimeBlock(block, src, operand_src);
8440 if (block.wantSafety()) {8442 if (block.wantSafety()) {
8441 const is_lt_len = try block.addUnOp(.cmp_lt_errors_len, operand);8443 const is_lt_len = try block.addUnOp(.cmp_lt_errors_len, operand);
8442 const zero_val = Air.internedToRef((try mod.intValue(Type.err_int, 0)).toIntern());8444 const zero_val = Air.internedToRef((try mod.intValue(err_int_ty, 0)).toIntern());
8443 const is_non_zero = try block.addBinOp(.cmp_neq, operand, zero_val);8445 const is_non_zero = try block.addBinOp(.cmp_neq, operand, zero_val);
8444 const ok = try block.addBinOp(.bool_and, is_lt_len, is_non_zero);8446 const ok = try block.addBinOp(.bool_and, is_lt_len, is_non_zero);
8445 try sema.addSafetyCheck(block, src, ok, .invalid_error_code);8447 try sema.addSafetyCheck(block, src, ok, .invalid_error_code);
...@@ -21899,10 +21901,11 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData...@@ -21899,10 +21901,11 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
21899 }21901 }
2190021902
21901 try sema.requireRuntimeBlock(block, src, operand_src);21903 try sema.requireRuntimeBlock(block, src, operand_src);
21904 const err_int_ty = try mod.errorIntType();
21902 if (block.wantSafety() and !dest_ty.isAnyError(mod) and sema.mod.backendSupportsFeature(.error_set_has_value)) {21905 if (block.wantSafety() and !dest_ty.isAnyError(mod) and sema.mod.backendSupportsFeature(.error_set_has_value)) {
21903 if (dest_tag == .ErrorUnion) {21906 if (dest_tag == .ErrorUnion) {
21904 const err_code = try sema.analyzeErrUnionCode(block, operand_src, operand);21907 const err_code = try sema.analyzeErrUnionCode(block, operand_src, operand);
21905 const err_int = try block.addBitCast(Type.err_int, err_code);21908 const err_int = try block.addBitCast(err_int_ty, err_code);
21906 const zero_u16 = Air.internedToRef(try mod.intern(.{21909 const zero_u16 = Air.internedToRef(try mod.intern(.{
21907 .int = .{ .ty = .u16_type, .storage = .{ .u64 = 0 } },21910 .int = .{ .ty = .u16_type, .storage = .{ .u64 = 0 } },
21908 }));21911 }));
...@@ -21918,7 +21921,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData...@@ -21918,7 +21921,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
21918 try sema.addSafetyCheck(block, src, ok, .invalid_error_code);21921 try sema.addSafetyCheck(block, src, ok, .invalid_error_code);
21919 }21922 }
21920 } else {21923 } else {
21921 const err_int_inst = try block.addBitCast(Type.err_int, operand);21924 const err_int_inst = try block.addBitCast(err_int_ty, operand);
21922 const ok = try block.addTyOp(.error_set_has_value, dest_ty, err_int_inst);21925 const ok = try block.addTyOp(.error_set_has_value, dest_ty, err_int_inst);
21923 try sema.addSafetyCheck(block, src, ok, .invalid_error_code);21926 try sema.addSafetyCheck(block, src, ok, .invalid_error_code);
21924 }21927 }
src/arch/wasm/CodeGen.zig+7-4
...@@ -3296,6 +3296,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {...@@ -3296,6 +3296,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3296 return WValue{ .imm32 = int };3296 return WValue{ .imm32 = int };
3297 },3297 },
3298 .error_union => |error_union| {3298 .error_union => |error_union| {
3299 const err_int_ty = try mod.errorIntType();
3299 const err_tv: TypedValue = switch (error_union.val) {3300 const err_tv: TypedValue = switch (error_union.val) {
3300 .err_name => |err_name| .{3301 .err_name => |err_name| .{
3301 .ty = ty.errorUnionSet(mod),3302 .ty = ty.errorUnionSet(mod),
...@@ -3305,8 +3306,8 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {...@@ -3305,8 +3306,8 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue {
3305 } })).toValue(),3306 } })).toValue(),
3306 },3307 },
3307 .payload => .{3308 .payload => .{
3308 .ty = Type.err_int,3309 .ty = err_int_ty,
3309 .val = try mod.intValue(Type.err_int, 0),3310 .val = try mod.intValue(err_int_ty, 0),
3310 },3311 },
3311 };3312 };
3312 const payload_type = ty.errorUnionPayload(mod);3313 const payload_type = ty.errorUnionPayload(mod);
...@@ -3705,8 +3706,10 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3705,8 +3706,10 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3705 const errors_len = WValue{ .memory = sym_index };3706 const errors_len = WValue{ .memory = sym_index };
37063707
3707 try func.emitWValue(operand);3708 try func.emitWValue(operand);
3708 const errors_len_val = try func.load(errors_len, Type.err_int, 0);3709 const mod = func.bin_file.base.options.module.?;
3709 const result = try func.cmp(.stack, errors_len_val, Type.err_int, .lt);3710 const err_int_ty = try mod.errorIntType();
3711 const errors_len_val = try func.load(errors_len, err_int_ty, 0);
3712 const result = try func.cmp(.stack, errors_len_val, err_int_ty, .lt);
37103713
3711 return func.finishAir(inst, try result.toLocal(func, Type.bool), &.{un_op});3714 return func.finishAir(inst, try result.toLocal(func, Type.bool), &.{un_op});
3712}3715}
src/codegen.zig+3-2
...@@ -1052,6 +1052,7 @@ pub fn genTypedValue(...@@ -1052,6 +1052,7 @@ pub fn genTypedValue(
1052 const payload_type = typed_value.ty.errorUnionPayload(mod);1052 const payload_type = typed_value.ty.errorUnionPayload(mod);
1053 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {1053 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
1054 // We use the error type directly as the type.1054 // We use the error type directly as the type.
1055 const err_int_ty = try mod.errorIntType();
1055 switch (mod.intern_pool.indexToKey(typed_value.val.toIntern()).error_union.val) {1056 switch (mod.intern_pool.indexToKey(typed_value.val.toIntern()).error_union.val) {
1056 .err_name => |err_name| return genTypedValue(bin_file, src_loc, .{1057 .err_name => |err_name| return genTypedValue(bin_file, src_loc, .{
1057 .ty = err_type,1058 .ty = err_type,
...@@ -1061,8 +1062,8 @@ pub fn genTypedValue(...@@ -1061,8 +1062,8 @@ pub fn genTypedValue(
1061 } })).toValue(),1062 } })).toValue(),
1062 }, owner_decl_index),1063 }, owner_decl_index),
1063 .payload => return genTypedValue(bin_file, src_loc, .{1064 .payload => return genTypedValue(bin_file, src_loc, .{
1064 .ty = Type.err_int,1065 .ty = err_int_ty,
1065 .val = try mod.intValue(Type.err_int, 0),1066 .val = try mod.intValue(err_int_ty, 0),
1066 }, owner_decl_index),1067 }, owner_decl_index),
1067 }1068 }
1068 }1069 }
src/codegen/c.zig+20-13
...@@ -1021,6 +1021,7 @@ pub const DeclGen = struct {...@@ -1021,6 +1021,7 @@ pub const DeclGen = struct {
1021 .error_union => |error_union| {1021 .error_union => |error_union| {
1022 const payload_ty = ty.errorUnionPayload(mod);1022 const payload_ty = ty.errorUnionPayload(mod);
1023 const error_ty = ty.errorUnionSet(mod);1023 const error_ty = ty.errorUnionSet(mod);
1024 const err_int_ty = try mod.errorIntType();
1024 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {1025 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
1025 switch (error_union.val) {1026 switch (error_union.val) {
1026 .err_name => |err_name| return dg.renderValue(1027 .err_name => |err_name| return dg.renderValue(
...@@ -1034,8 +1035,8 @@ pub const DeclGen = struct {...@@ -1034,8 +1035,8 @@ pub const DeclGen = struct {
1034 ),1035 ),
1035 .payload => return dg.renderValue(1036 .payload => return dg.renderValue(
1036 writer,1037 writer,
1037 Type.err_int,1038 err_int_ty,
1038 try mod.intValue(Type.err_int, 0),1039 try mod.intValue(err_int_ty, 0),
1039 location,1040 location,
1040 ),1041 ),
1041 }1042 }
...@@ -1070,8 +1071,8 @@ pub const DeclGen = struct {...@@ -1070,8 +1071,8 @@ pub const DeclGen = struct {
1070 ),1071 ),
1071 .payload => try dg.renderValue(1072 .payload => try dg.renderValue(
1072 writer,1073 writer,
1073 Type.err_int,1074 err_int_ty,
1074 try mod.intValue(Type.err_int, 0),1075 try mod.intValue(err_int_ty, 0),
1075 location,1076 location,
1076 ),1077 ),
1077 }1078 }
...@@ -1227,7 +1228,7 @@ pub const DeclGen = struct {...@@ -1227,7 +1228,7 @@ pub const DeclGen = struct {
1227 payload_ty,1228 payload_ty,
1228 switch (opt.val) {1229 switch (opt.val) {
1229 .none => switch (payload_ty.zigTypeTag(mod)) {1230 .none => switch (payload_ty.zigTypeTag(mod)) {
1230 .ErrorSet => try mod.intValue(Type.err_int, 0),1231 .ErrorSet => try mod.intValue(try mod.errorIntType(), 0),
1231 .Pointer => try mod.getCoerced(val, payload_ty),1232 .Pointer => try mod.getCoerced(val, payload_ty),
1232 else => unreachable,1233 else => unreachable,
1233 },1234 },
...@@ -5179,6 +5180,7 @@ fn airIsNull(...@@ -5179,6 +5180,7 @@ fn airIsNull(
5179 const operand_ty = f.typeOf(un_op);5180 const operand_ty = f.typeOf(un_op);
5180 const optional_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty;5181 const optional_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty;
5181 const payload_ty = optional_ty.optionalChild(mod);5182 const payload_ty = optional_ty.optionalChild(mod);
5183 const err_int_ty = try mod.errorIntType();
51825184
5183 const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))5185 const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))
5184 TypedValue{ .ty = Type.bool, .val = Value.true }5186 TypedValue{ .ty = Type.bool, .val = Value.true }
...@@ -5186,7 +5188,7 @@ fn airIsNull(...@@ -5186,7 +5188,7 @@ fn airIsNull(
5186 // operand is a regular pointer, test `operand !=/== NULL`5188 // operand is a regular pointer, test `operand !=/== NULL`
5187 TypedValue{ .ty = optional_ty, .val = try mod.getCoerced(Value.null, optional_ty) }5189 TypedValue{ .ty = optional_ty, .val = try mod.getCoerced(Value.null, optional_ty) }
5188 else if (payload_ty.zigTypeTag(mod) == .ErrorSet)5190 else if (payload_ty.zigTypeTag(mod) == .ErrorSet)
5189 TypedValue{ .ty = Type.err_int, .val = try mod.intValue(Type.err_int, 0) }5191 TypedValue{ .ty = err_int_ty, .val = try mod.intValue(err_int_ty, 0) }
5190 else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: {5192 else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: {
5191 try writer.writeAll(".ptr");5193 try writer.writeAll(".ptr");
5192 const slice_ptr_ty = payload_ty.slicePtrFieldType(mod);5194 const slice_ptr_ty = payload_ty.slicePtrFieldType(mod);
...@@ -5672,8 +5674,10 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5672,8 +5674,10 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue {
5672 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })5674 try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" })
5673 else5675 else
5674 try f.writeCValueMember(writer, operand, .{ .identifier = "error" })5676 try f.writeCValueMember(writer, operand, .{ .identifier = "error" })
5675 else5677 else {
5676 try f.object.dg.renderValue(writer, Type.err_int, try mod.intValue(Type.err_int, 0), .Initializer);5678 const err_int_ty = try mod.errorIntType();
5679 try f.object.dg.renderValue(writer, err_int_ty, try mod.intValue(err_int_ty, 0), .Initializer);
5680 }
5677 }5681 }
5678 try writer.writeAll(";\n");5682 try writer.writeAll(";\n");
5679 return local;5683 return local;
...@@ -5794,12 +5798,13 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5794,12 +5798,13 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5794 const error_union_ty = f.typeOf(ty_op.operand).childType(mod);5798 const error_union_ty = f.typeOf(ty_op.operand).childType(mod);
57955799
5796 const payload_ty = error_union_ty.errorUnionPayload(mod);5800 const payload_ty = error_union_ty.errorUnionPayload(mod);
5801 const err_int_ty = try mod.errorIntType();
57975802
5798 // First, set the non-error value.5803 // First, set the non-error value.
5799 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {5804 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
5800 try f.writeCValueDeref(writer, operand);5805 try f.writeCValueDeref(writer, operand);
5801 try writer.writeAll(" = ");5806 try writer.writeAll(" = ");
5802 try f.object.dg.renderValue(writer, Type.err_int, try mod.intValue(Type.err_int, 0), .Other);5807 try f.object.dg.renderValue(writer, err_int_ty, try mod.intValue(err_int_ty, 0), .Other);
5803 try writer.writeAll(";\n ");5808 try writer.writeAll(";\n ");
58045809
5805 return operand;5810 return operand;
...@@ -5807,7 +5812,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5807,7 +5812,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue {
5807 try reap(f, inst, &.{ty_op.operand});5812 try reap(f, inst, &.{ty_op.operand});
5808 try f.writeCValueDeref(writer, operand);5813 try f.writeCValueDeref(writer, operand);
5809 try writer.writeAll(".error = ");5814 try writer.writeAll(".error = ");
5810 try f.object.dg.renderValue(writer, Type.err_int, try mod.intValue(Type.err_int, 0), .Other);5815 try f.object.dg.renderValue(writer, err_int_ty, try mod.intValue(err_int_ty, 0), .Other);
5811 try writer.writeAll(";\n");5816 try writer.writeAll(";\n");
58125817
5813 // Then return the payload pointer (only if it is used)5818 // Then return the payload pointer (only if it is used)
...@@ -5863,7 +5868,8 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -5863,7 +5868,8 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
5863 else5868 else
5864 try f.writeCValueMember(writer, local, .{ .identifier = "error" });5869 try f.writeCValueMember(writer, local, .{ .identifier = "error" });
5865 try a.assign(f, writer);5870 try a.assign(f, writer);
5866 try f.object.dg.renderValue(writer, Type.err_int, try mod.intValue(Type.err_int, 0), .Other);5871 const err_int_ty = try mod.errorIntType();
5872 try f.object.dg.renderValue(writer, err_int_ty, try mod.intValue(err_int_ty, 0), .Other);
5867 try a.end(f, writer);5873 try a.end(f, writer);
5868 }5874 }
5869 return local;5875 return local;
...@@ -5885,6 +5891,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const...@@ -5885,6 +5891,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
5885 try f.writeCValue(writer, local, .Other);5891 try f.writeCValue(writer, local, .Other);
5886 try writer.writeAll(" = ");5892 try writer.writeAll(" = ");
58875893
5894 const err_int_ty = try mod.errorIntType();
5888 if (!error_ty.errorSetIsEmpty(mod))5895 if (!error_ty.errorSetIsEmpty(mod))
5889 if (payload_ty.hasRuntimeBits(mod))5896 if (payload_ty.hasRuntimeBits(mod))
5890 if (is_ptr)5897 if (is_ptr)
...@@ -5894,11 +5901,11 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const...@@ -5894,11 +5901,11 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const
5894 else5901 else
5895 try f.writeCValue(writer, operand, .Other)5902 try f.writeCValue(writer, operand, .Other)
5896 else5903 else
5897 try f.object.dg.renderValue(writer, Type.err_int, try mod.intValue(Type.err_int, 0), .Other);5904 try f.object.dg.renderValue(writer, err_int_ty, try mod.intValue(err_int_ty, 0), .Other);
5898 try writer.writeByte(' ');5905 try writer.writeByte(' ');
5899 try writer.writeAll(operator);5906 try writer.writeAll(operator);
5900 try writer.writeByte(' ');5907 try writer.writeByte(' ');
5901 try f.object.dg.renderValue(writer, Type.err_int, try mod.intValue(Type.err_int, 0), .Other);5908 try f.object.dg.renderValue(writer, err_int_ty, try mod.intValue(err_int_ty, 0), .Other);
5902 try writer.writeAll(";\n");5909 try writer.writeAll(";\n");
5903 return local;5910 return local;
5904}5911}
src/codegen/llvm.zig+59-44
...@@ -1111,7 +1111,7 @@ pub const Object = struct {...@@ -1111,7 +1111,7 @@ pub const Object = struct {
1111 // }1111 // }
11121112
1113 const lhs = wip.arg(0);1113 const lhs = wip.arg(0);
1114 const rhs = try o.builder.intValue(Builder.Type.err_int, errors_len);1114 const rhs = try o.builder.intValue(try o.errorIntType(), errors_len);
1115 const is_lt = try wip.icmp(.ult, lhs, rhs, "");1115 const is_lt = try wip.icmp(.ult, lhs, rhs, "");
1116 _ = try wip.ret(is_lt);1116 _ = try wip.ret(is_lt);
1117 try wip.finish();1117 try wip.finish();
...@@ -3111,6 +3111,10 @@ pub const Object = struct {...@@ -3111,6 +3111,10 @@ pub const Object = struct {
3111 return variable_index;3111 return variable_index;
3112 }3112 }
31133113
3114 fn errorIntType(o: *Object) Allocator.Error!Builder.Type {
3115 return o.builder.intType(o.module.errorSetBits());
3116 }
3117
3114 fn lowerType(o: *Object, t: Type) Allocator.Error!Builder.Type {3118 fn lowerType(o: *Object, t: Type) Allocator.Error!Builder.Type {
3115 const ty = try o.lowerTypeInner(t);3119 const ty = try o.lowerTypeInner(t);
3116 const mod = o.module;3120 const mod = o.module;
...@@ -3182,7 +3186,7 @@ pub const Object = struct {...@@ -3182,7 +3186,7 @@ pub const Object = struct {
3182 .bool_type => .i1,3186 .bool_type => .i1,
3183 .void_type => .void,3187 .void_type => .void,
3184 .type_type => unreachable,3188 .type_type => unreachable,
3185 .anyerror_type => Builder.Type.err_int,3189 .anyerror_type => try o.errorIntType(),
3186 .comptime_int_type,3190 .comptime_int_type,
3187 .comptime_float_type,3191 .comptime_float_type,
3188 .noreturn_type,3192 .noreturn_type,
...@@ -3203,7 +3207,7 @@ pub const Object = struct {...@@ -3203,7 +3207,7 @@ pub const Object = struct {
3203 .optional_noreturn_type => unreachable,3207 .optional_noreturn_type => unreachable,
3204 .anyerror_void_error_union_type,3208 .anyerror_void_error_union_type,
3205 .adhoc_inferred_error_set_type,3209 .adhoc_inferred_error_set_type,
3206 => Builder.Type.err_int,3210 => try o.errorIntType(),
3207 .generic_poison_type,3211 .generic_poison_type,
3208 .empty_struct_type,3212 .empty_struct_type,
3209 => unreachable,3213 => unreachable,
...@@ -3272,16 +3276,17 @@ pub const Object = struct {...@@ -3272,16 +3276,17 @@ pub const Object = struct {
3272 },3276 },
3273 .anyframe_type => @panic("TODO implement lowerType for AnyFrame types"),3277 .anyframe_type => @panic("TODO implement lowerType for AnyFrame types"),
3274 .error_union_type => |error_union_type| {3278 .error_union_type => |error_union_type| {
3275 const error_type = Builder.Type.err_int;3279 const error_type = try o.errorIntType();
3276 if (!error_union_type.payload_type.toType().hasRuntimeBitsIgnoreComptime(mod))3280 if (!error_union_type.payload_type.toType().hasRuntimeBitsIgnoreComptime(mod))
3277 return error_type;3281 return error_type;
3278 const payload_type = try o.lowerType(error_union_type.payload_type.toType());3282 const payload_type = try o.lowerType(error_union_type.payload_type.toType());
3283 const err_int_ty = try mod.errorIntType();
32793284
3280 const payload_align = error_union_type.payload_type.toType().abiAlignment(mod);3285 const payload_align = error_union_type.payload_type.toType().abiAlignment(mod);
3281 const error_align = Type.err_int.abiAlignment(mod);3286 const error_align = err_int_ty.abiAlignment(mod);
32823287
3283 const payload_size = error_union_type.payload_type.toType().abiSize(mod);3288 const payload_size = error_union_type.payload_type.toType().abiSize(mod);
3284 const error_size = Type.err_int.abiSize(mod);3289 const error_size = err_int_ty.abiSize(mod);
32853290
3286 var fields: [3]Builder.Type = undefined;3291 var fields: [3]Builder.Type = undefined;
3287 var fields_len: usize = 2;3292 var fields_len: usize = 2;
...@@ -3542,7 +3547,7 @@ pub const Object = struct {...@@ -3542,7 +3547,7 @@ pub const Object = struct {
3542 },3547 },
3543 .enum_type => |enum_type| try o.lowerType(enum_type.tag_ty.toType()),3548 .enum_type => |enum_type| try o.lowerType(enum_type.tag_ty.toType()),
3544 .func_type => |func_type| try o.lowerTypeFn(func_type),3549 .func_type => |func_type| try o.lowerTypeFn(func_type),
3545 .error_set_type, .inferred_error_set_type => Builder.Type.err_int,3550 .error_set_type, .inferred_error_set_type => try o.errorIntType(),
3546 // values, not types3551 // values, not types
3547 .undef,3552 .undef,
3548 .runtime_value,3553 .runtime_value,
...@@ -3725,7 +3730,7 @@ pub const Object = struct {...@@ -3725,7 +3730,7 @@ pub const Object = struct {
3725 },3730 },
3726 .err => |err| {3731 .err => |err| {
3727 const int = try mod.getErrorValue(err.name);3732 const int = try mod.getErrorValue(err.name);
3728 const llvm_int = try o.builder.intConst(Builder.Type.err_int, int);3733 const llvm_int = try o.builder.intConst(try o.errorIntType(), int);
3729 return llvm_int;3734 return llvm_int;
3730 },3735 },
3731 .error_union => |error_union| {3736 .error_union => |error_union| {
...@@ -3734,8 +3739,9 @@ pub const Object = struct {...@@ -3734,8 +3739,9 @@ pub const Object = struct {
3734 .ty = ty.errorUnionSet(mod).toIntern(),3739 .ty = ty.errorUnionSet(mod).toIntern(),
3735 .name = err_name,3740 .name = err_name,
3736 } }),3741 } }),
3737 .payload => (try mod.intValue(Type.err_int, 0)).toIntern(),3742 .payload => (try mod.intValue(try mod.errorIntType(), 0)).toIntern(),
3738 };3743 };
3744 const err_int_ty = try mod.errorIntType();
3739 const payload_type = ty.errorUnionPayload(mod);3745 const payload_type = ty.errorUnionPayload(mod);
3740 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {3746 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
3741 // We use the error type directly as the type.3747 // We use the error type directly as the type.
...@@ -3743,7 +3749,7 @@ pub const Object = struct {...@@ -3743,7 +3749,7 @@ pub const Object = struct {
3743 }3749 }
37443750
3745 const payload_align = payload_type.abiAlignment(mod);3751 const payload_align = payload_type.abiAlignment(mod);
3746 const error_align = Type.err_int.abiAlignment(mod);3752 const error_align = err_int_ty.abiAlignment(mod);
3747 const llvm_error_value = try o.lowerValue(err_val);3753 const llvm_error_value = try o.lowerValue(err_val);
3748 const llvm_payload_value = try o.lowerValue(switch (error_union.val) {3754 const llvm_payload_value = try o.lowerValue(switch (error_union.val) {
3749 .err_name => try mod.intern(.{ .undef = payload_type.toIntern() }),3755 .err_name => try mod.intern(.{ .undef = payload_type.toIntern() }),
...@@ -4285,8 +4291,9 @@ pub const Object = struct {...@@ -4285,8 +4291,9 @@ pub const Object = struct {
4285 return parent_ptr;4291 return parent_ptr;
4286 }4292 }
42874293
4294 const err_int_ty = try mod.errorIntType();
4288 const payload_align = payload_ty.abiAlignment(mod);4295 const payload_align = payload_ty.abiAlignment(mod);
4289 const err_align = Type.err_int.abiAlignment(mod);4296 const err_align = err_int_ty.abiAlignment(mod);
4290 const index: u32 = if (payload_align.compare(.gt, err_align)) 2 else 1;4297 const index: u32 = if (payload_align.compare(.gt, err_align)) 2 else 1;
4291 return o.builder.gepConst(.inbounds, try o.lowerType(eu_ty), parent_ptr, null, &.{4298 return o.builder.gepConst(.inbounds, try o.lowerType(eu_ty), parent_ptr, null, &.{
4292 try o.builder.intConst(.i32, 0), try o.builder.intConst(.i32, index),4299 try o.builder.intConst(.i32, 0), try o.builder.intConst(.i32, index),
...@@ -5399,7 +5406,7 @@ pub const FuncGen = struct {...@@ -5399,7 +5406,7 @@ pub const FuncGen = struct {
5399 // Functions with an empty error set are emitted with an error code5406 // Functions with an empty error set are emitted with an error code
5400 // return type and return zero so they can be function pointers coerced5407 // return type and return zero so they can be function pointers coerced
5401 // to functions that return anyerror.5408 // to functions that return anyerror.
5402 _ = try self.wip.ret(try o.builder.intValue(Builder.Type.err_int, 0));5409 _ = try self.wip.ret(try o.builder.intValue(try o.errorIntType(), 0));
5403 } else {5410 } else {
5404 _ = try self.wip.retVoid();5411 _ = try self.wip.retVoid();
5405 }5412 }
...@@ -5441,7 +5448,7 @@ pub const FuncGen = struct {...@@ -5441,7 +5448,7 @@ pub const FuncGen = struct {
5441 // Functions with an empty error set are emitted with an error code5448 // Functions with an empty error set are emitted with an error code
5442 // return type and return zero so they can be function pointers coerced5449 // return type and return zero so they can be function pointers coerced
5443 // to functions that return anyerror.5450 // to functions that return anyerror.
5444 _ = try self.wip.ret(try o.builder.intValue(Builder.Type.err_int, 0));5451 _ = try self.wip.ret(try o.builder.intValue(try o.errorIntType(), 0));
5445 } else {5452 } else {
5446 _ = try self.wip.retVoid();5453 _ = try self.wip.retVoid();
5447 }5454 }
...@@ -5788,24 +5795,25 @@ pub const FuncGen = struct {...@@ -5788,24 +5795,25 @@ pub const FuncGen = struct {
5788 const payload_ty = err_union_ty.errorUnionPayload(mod);5795 const payload_ty = err_union_ty.errorUnionPayload(mod);
5789 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);5796 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);
5790 const err_union_llvm_ty = try o.lowerType(err_union_ty);5797 const err_union_llvm_ty = try o.lowerType(err_union_ty);
5798 const error_type = try o.errorIntType();
57915799
5792 if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {5800 if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
5793 const loaded = loaded: {5801 const loaded = loaded: {
5794 if (!payload_has_bits) {5802 if (!payload_has_bits) {
5795 // TODO add alignment to this load5803 // TODO add alignment to this load
5796 break :loaded if (operand_is_ptr)5804 break :loaded if (operand_is_ptr)
5797 try fg.wip.load(.normal, Builder.Type.err_int, err_union, .default, "")5805 try fg.wip.load(.normal, error_type, err_union, .default, "")
5798 else5806 else
5799 err_union;5807 err_union;
5800 }5808 }
5801 const err_field_index = errUnionErrorOffset(payload_ty, mod);5809 const err_field_index = try errUnionErrorOffset(payload_ty, mod);
5802 if (operand_is_ptr or isByRef(err_union_ty, mod)) {5810 if (operand_is_ptr or isByRef(err_union_ty, mod)) {
5803 const err_field_ptr =5811 const err_field_ptr =
5804 try fg.wip.gepStruct(err_union_llvm_ty, err_union, err_field_index, "");5812 try fg.wip.gepStruct(err_union_llvm_ty, err_union, err_field_index, "");
5805 // TODO add alignment to this load5813 // TODO add alignment to this load
5806 break :loaded try fg.wip.load(5814 break :loaded try fg.wip.load(
5807 .normal,5815 .normal,
5808 Builder.Type.err_int,5816 error_type,
5809 err_field_ptr,5817 err_field_ptr,
5810 .default,5818 .default,
5811 "",5819 "",
...@@ -5813,7 +5821,7 @@ pub const FuncGen = struct {...@@ -5813,7 +5821,7 @@ pub const FuncGen = struct {
5813 }5821 }
5814 break :loaded try fg.wip.extractValue(err_union, &.{err_field_index}, "");5822 break :loaded try fg.wip.extractValue(err_union, &.{err_field_index}, "");
5815 };5823 };
5816 const zero = try o.builder.intValue(Builder.Type.err_int, 0);5824 const zero = try o.builder.intValue(error_type, 0);
5817 const is_err = try fg.wip.icmp(.ne, loaded, zero, "");5825 const is_err = try fg.wip.icmp(.ne, loaded, zero, "");
58185826
5819 const return_block = try fg.wip.block(1, "TryRet");5827 const return_block = try fg.wip.block(1, "TryRet");
...@@ -5827,7 +5835,7 @@ pub const FuncGen = struct {...@@ -5827,7 +5835,7 @@ pub const FuncGen = struct {
5827 }5835 }
5828 if (is_unused) return .none;5836 if (is_unused) return .none;
5829 if (!payload_has_bits) return if (operand_is_ptr) err_union else .none;5837 if (!payload_has_bits) return if (operand_is_ptr) err_union else .none;
5830 const offset = errUnionPayloadOffset(payload_ty, mod);5838 const offset = try errUnionPayloadOffset(payload_ty, mod);
5831 if (operand_is_ptr) {5839 if (operand_is_ptr) {
5832 return fg.wip.gepStruct(err_union_llvm_ty, err_union, offset, "");5840 return fg.wip.gepStruct(err_union_llvm_ty, err_union, offset, "");
5833 } else if (isByRef(err_union_ty, mod)) {5841 } else if (isByRef(err_union_ty, mod)) {
...@@ -7053,7 +7061,8 @@ pub const FuncGen = struct {...@@ -7053,7 +7061,8 @@ pub const FuncGen = struct {
7053 const operand_ty = self.typeOf(un_op);7061 const operand_ty = self.typeOf(un_op);
7054 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;7062 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
7055 const payload_ty = err_union_ty.errorUnionPayload(mod);7063 const payload_ty = err_union_ty.errorUnionPayload(mod);
7056 const zero = try o.builder.intValue(Builder.Type.err_int, 0);7064 const error_type = try o.errorIntType();
7065 const zero = try o.builder.intValue(error_type, 0);
70577066
7058 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {7067 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
7059 const val: Builder.Constant = switch (cond) {7068 const val: Builder.Constant = switch (cond) {
...@@ -7072,13 +7081,13 @@ pub const FuncGen = struct {...@@ -7072,13 +7081,13 @@ pub const FuncGen = struct {
7072 return self.wip.icmp(cond, loaded, zero, "");7081 return self.wip.icmp(cond, loaded, zero, "");
7073 }7082 }
70747083
7075 const err_field_index = errUnionErrorOffset(payload_ty, mod);7084 const err_field_index = try errUnionErrorOffset(payload_ty, mod);
70767085
7077 const loaded = if (operand_is_ptr or isByRef(err_union_ty, mod)) loaded: {7086 const loaded = if (operand_is_ptr or isByRef(err_union_ty, mod)) loaded: {
7078 const err_union_llvm_ty = try o.lowerType(err_union_ty);7087 const err_union_llvm_ty = try o.lowerType(err_union_ty);
7079 const err_field_ptr =7088 const err_field_ptr =
7080 try self.wip.gepStruct(err_union_llvm_ty, operand, err_field_index, "");7089 try self.wip.gepStruct(err_union_llvm_ty, operand, err_field_index, "");
7081 break :loaded try self.wip.load(.normal, Builder.Type.err_int, err_field_ptr, .default, "");7090 break :loaded try self.wip.load(.normal, error_type, err_field_ptr, .default, "");
7082 } else try self.wip.extractValue(operand, &.{err_field_index}, "");7091 } else try self.wip.extractValue(operand, &.{err_field_index}, "");
7083 return self.wip.icmp(cond, loaded, zero, "");7092 return self.wip.icmp(cond, loaded, zero, "");
7084 }7093 }
...@@ -7173,7 +7182,7 @@ pub const FuncGen = struct {...@@ -7173,7 +7182,7 @@ pub const FuncGen = struct {
7173 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7182 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
7174 return if (operand_is_ptr) operand else .none;7183 return if (operand_is_ptr) operand else .none;
7175 }7184 }
7176 const offset = errUnionPayloadOffset(payload_ty, mod);7185 const offset = try errUnionPayloadOffset(payload_ty, mod);
7177 const err_union_llvm_ty = try o.lowerType(err_union_ty);7186 const err_union_llvm_ty = try o.lowerType(err_union_ty);
7178 if (operand_is_ptr) {7187 if (operand_is_ptr) {
7179 return self.wip.gepStruct(err_union_llvm_ty, operand, offset, "");7188 return self.wip.gepStruct(err_union_llvm_ty, operand, offset, "");
...@@ -7200,27 +7209,28 @@ pub const FuncGen = struct {...@@ -7200,27 +7209,28 @@ pub const FuncGen = struct {
7200 const ty_op = self.air.instructions.items(.data)[inst].ty_op;7209 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
7201 const operand = try self.resolveInst(ty_op.operand);7210 const operand = try self.resolveInst(ty_op.operand);
7202 const operand_ty = self.typeOf(ty_op.operand);7211 const operand_ty = self.typeOf(ty_op.operand);
7212 const error_type = try o.errorIntType();
7203 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;7213 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
7204 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {7214 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
7205 if (operand_is_ptr) {7215 if (operand_is_ptr) {
7206 return operand;7216 return operand;
7207 } else {7217 } else {
7208 return o.builder.intValue(Builder.Type.err_int, 0);7218 return o.builder.intValue(error_type, 0);
7209 }7219 }
7210 }7220 }
72117221
7212 const payload_ty = err_union_ty.errorUnionPayload(mod);7222 const payload_ty = err_union_ty.errorUnionPayload(mod);
7213 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7223 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
7214 if (!operand_is_ptr) return operand;7224 if (!operand_is_ptr) return operand;
7215 return self.wip.load(.normal, Builder.Type.err_int, operand, .default, "");7225 return self.wip.load(.normal, error_type, operand, .default, "");
7216 }7226 }
72177227
7218 const offset = errUnionErrorOffset(payload_ty, mod);7228 const offset = try errUnionErrorOffset(payload_ty, mod);
72197229
7220 if (operand_is_ptr or isByRef(err_union_ty, mod)) {7230 if (operand_is_ptr or isByRef(err_union_ty, mod)) {
7221 const err_union_llvm_ty = try o.lowerType(err_union_ty);7231 const err_union_llvm_ty = try o.lowerType(err_union_ty);
7222 const err_field_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, "");7232 const err_field_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, "");
7223 return self.wip.load(.normal, Builder.Type.err_int, err_field_ptr, .default, "");7233 return self.wip.load(.normal, error_type, err_field_ptr, .default, "");
7224 }7234 }
72257235
7226 return self.wip.extractValue(operand, &.{offset}, "");7236 return self.wip.extractValue(operand, &.{offset}, "");
...@@ -7234,15 +7244,16 @@ pub const FuncGen = struct {...@@ -7234,15 +7244,16 @@ pub const FuncGen = struct {
7234 const err_union_ty = self.typeOf(ty_op.operand).childType(mod);7244 const err_union_ty = self.typeOf(ty_op.operand).childType(mod);
72357245
7236 const payload_ty = err_union_ty.errorUnionPayload(mod);7246 const payload_ty = err_union_ty.errorUnionPayload(mod);
7237 const non_error_val = try o.builder.intValue(Builder.Type.err_int, 0);7247 const non_error_val = try o.builder.intValue(try o.errorIntType(), 0);
7238 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7248 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
7239 _ = try self.wip.store(.normal, non_error_val, operand, .default);7249 _ = try self.wip.store(.normal, non_error_val, operand, .default);
7240 return operand;7250 return operand;
7241 }7251 }
7242 const err_union_llvm_ty = try o.lowerType(err_union_ty);7252 const err_union_llvm_ty = try o.lowerType(err_union_ty);
7243 {7253 {
7244 const error_alignment = Type.err_int.abiAlignment(mod).toLlvm();7254 const err_int_ty = try mod.errorIntType();
7245 const error_offset = errUnionErrorOffset(payload_ty, mod);7255 const error_alignment = err_int_ty.abiAlignment(mod).toLlvm();
7256 const error_offset = try errUnionErrorOffset(payload_ty, mod);
7246 // First set the non-error value.7257 // First set the non-error value.
7247 const non_null_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, error_offset, "");7258 const non_null_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, error_offset, "");
7248 _ = try self.wip.store(.normal, non_error_val, non_null_ptr, error_alignment);7259 _ = try self.wip.store(.normal, non_error_val, non_null_ptr, error_alignment);
...@@ -7250,7 +7261,7 @@ pub const FuncGen = struct {...@@ -7250,7 +7261,7 @@ pub const FuncGen = struct {
7250 // Then return the payload pointer (only if it is used).7261 // Then return the payload pointer (only if it is used).
7251 if (self.liveness.isUnused(inst)) return .none;7262 if (self.liveness.isUnused(inst)) return .none;
72527263
7253 const payload_offset = errUnionPayloadOffset(payload_ty, mod);7264 const payload_offset = try errUnionPayloadOffset(payload_ty, mod);
7254 return self.wip.gepStruct(err_union_llvm_ty, operand, payload_offset, "");7265 return self.wip.gepStruct(err_union_llvm_ty, operand, payload_offset, "");
7255 }7266 }
72567267
...@@ -7353,11 +7364,11 @@ pub const FuncGen = struct {...@@ -7353,11 +7364,11 @@ pub const FuncGen = struct {
7353 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {7364 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
7354 return operand;7365 return operand;
7355 }7366 }
7356 const ok_err_code = try o.builder.intValue(Builder.Type.err_int, 0);7367 const ok_err_code = try o.builder.intValue(try o.errorIntType(), 0);
7357 const err_un_llvm_ty = try o.lowerType(err_un_ty);7368 const err_un_llvm_ty = try o.lowerType(err_un_ty);
73587369
7359 const payload_offset = errUnionPayloadOffset(payload_ty, mod);7370 const payload_offset = try errUnionPayloadOffset(payload_ty, mod);
7360 const error_offset = errUnionErrorOffset(payload_ty, mod);7371 const error_offset = try errUnionErrorOffset(payload_ty, mod);
7361 if (isByRef(err_un_ty, mod)) {7372 if (isByRef(err_un_ty, mod)) {
7362 const directReturn = self.isNextRet(body_tail);7373 const directReturn = self.isNextRet(body_tail);
7363 const result_ptr = if (directReturn)7374 const result_ptr = if (directReturn)
...@@ -7369,7 +7380,8 @@ pub const FuncGen = struct {...@@ -7369,7 +7380,8 @@ pub const FuncGen = struct {
7369 };7380 };
73707381
7371 const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, "");7382 const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, "");
7372 const error_alignment = Type.err_int.abiAlignment(mod).toLlvm();7383 const err_int_ty = try mod.errorIntType();
7384 const error_alignment = err_int_ty.abiAlignment(mod).toLlvm();
7373 _ = try self.wip.store(.normal, ok_err_code, err_ptr, error_alignment);7385 _ = try self.wip.store(.normal, ok_err_code, err_ptr, error_alignment);
7374 const payload_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, payload_offset, "");7386 const payload_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, payload_offset, "");
7375 const payload_ptr_ty = try mod.singleMutPtrType(payload_ty);7387 const payload_ptr_ty = try mod.singleMutPtrType(payload_ty);
...@@ -7393,8 +7405,8 @@ pub const FuncGen = struct {...@@ -7393,8 +7405,8 @@ pub const FuncGen = struct {
7393 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return operand;7405 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) return operand;
7394 const err_un_llvm_ty = try o.lowerType(err_un_ty);7406 const err_un_llvm_ty = try o.lowerType(err_un_ty);
73957407
7396 const payload_offset = errUnionPayloadOffset(payload_ty, mod);7408 const payload_offset = try errUnionPayloadOffset(payload_ty, mod);
7397 const error_offset = errUnionErrorOffset(payload_ty, mod);7409 const error_offset = try errUnionErrorOffset(payload_ty, mod);
7398 if (isByRef(err_un_ty, mod)) {7410 if (isByRef(err_un_ty, mod)) {
7399 const directReturn = self.isNextRet(body_tail);7411 const directReturn = self.isNextRet(body_tail);
7400 const result_ptr = if (directReturn)7412 const result_ptr = if (directReturn)
...@@ -7406,7 +7418,8 @@ pub const FuncGen = struct {...@@ -7406,7 +7418,8 @@ pub const FuncGen = struct {
7406 };7418 };
74077419
7408 const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, "");7420 const err_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, error_offset, "");
7409 const error_alignment = Type.err_int.abiAlignment(mod).toLlvm();7421 const err_int_ty = try mod.errorIntType();
7422 const error_alignment = err_int_ty.abiAlignment(mod).toLlvm();
7410 _ = try self.wip.store(.normal, operand, err_ptr, error_alignment);7423 _ = try self.wip.store(.normal, operand, err_ptr, error_alignment);
7411 const payload_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, payload_offset, "");7424 const payload_ptr = try self.wip.gepStruct(err_un_llvm_ty, result_ptr, payload_offset, "");
7412 const payload_ptr_ty = try mod.singleMutPtrType(payload_ty);7425 const payload_ptr_ty = try mod.singleMutPtrType(payload_ty);
...@@ -9363,7 +9376,7 @@ pub const FuncGen = struct {...@@ -9363,7 +9376,7 @@ pub const FuncGen = struct {
93639376
9364 for (names) |name| {9377 for (names) |name| {
9365 const err_int = mod.global_error_set.getIndex(name).?;9378 const err_int = mod.global_error_set.getIndex(name).?;
9366 const this_tag_int_value = try o.builder.intConst(Builder.Type.err_int, err_int);9379 const this_tag_int_value = try o.builder.intConst(try o.errorIntType(), err_int);
9367 try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip);9380 try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip);
9368 }9381 }
9369 self.wip.cursor = .{ .block = valid_block };9382 self.wip.cursor = .{ .block = valid_block };
...@@ -9545,7 +9558,7 @@ pub const FuncGen = struct {...@@ -9545,7 +9558,7 @@ pub const FuncGen = struct {
9545 if (o.builder.getGlobal(name)) |llvm_fn| return llvm_fn.ptrConst(&o.builder).kind.function;9558 if (o.builder.getGlobal(name)) |llvm_fn| return llvm_fn.ptrConst(&o.builder).kind.function;
95469559
9547 const function_index = try o.builder.addFunction(9560 const function_index = try o.builder.addFunction(
9548 try o.builder.fnType(.i1, &.{Builder.Type.err_int}, .normal),9561 try o.builder.fnType(.i1, &.{try o.errorIntType()}, .normal),
9549 name,9562 name,
9550 toLlvmAddressSpace(.generic, o.module.getTarget()),9563 toLlvmAddressSpace(.generic, o.module.getTarget()),
9551 );9564 );
...@@ -10880,7 +10893,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu...@@ -10880,7 +10893,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu
10880 // If the return type is an error set or an error union, then we make this10893 // If the return type is an error set or an error union, then we make this
10881 // anyerror return type instead, so that it can be coerced into a function10894 // anyerror return type instead, so that it can be coerced into a function
10882 // pointer type which has anyerror as the return type.10895 // pointer type which has anyerror as the return type.
10883 return if (return_type.isError(mod)) Builder.Type.err_int else .void;10896 return if (return_type.isError(mod)) try o.errorIntType() else .void;
10884 }10897 }
10885 const target = mod.getTarget();10898 const target = mod.getTarget();
10886 switch (fn_info.cc) {10899 switch (fn_info.cc) {
...@@ -11633,12 +11646,14 @@ fn buildAllocaInner(...@@ -11633,12 +11646,14 @@ fn buildAllocaInner(
11633 return wip.conv(.unneeded, alloca, .ptr, "");11646 return wip.conv(.unneeded, alloca, .ptr, "");
11634}11647}
1163511648
11636fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) u1 {11649fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) !u1 {
11637 return @intFromBool(Type.err_int.abiAlignment(mod).compare(.gt, payload_ty.abiAlignment(mod)));11650 const err_int_ty = try mod.errorIntType();
11651 return @intFromBool(err_int_ty.abiAlignment(mod).compare(.gt, payload_ty.abiAlignment(mod)));
11638}11652}
1163911653
11640fn errUnionErrorOffset(payload_ty: Type, mod: *Module) u1 {11654fn errUnionErrorOffset(payload_ty: Type, mod: *Module) !u1 {
11641 return @intFromBool(Type.err_int.abiAlignment(mod).compare(.lte, payload_ty.abiAlignment(mod)));11655 const err_int_ty = try mod.errorIntType();
11656 return @intFromBool(err_int_ty.abiAlignment(mod).compare(.lte, payload_ty.abiAlignment(mod)));
11642}11657}
1164311658
11644/// Returns true for asm constraint (e.g. "=*m", "=r") if it accepts a memory location11659/// Returns true for asm constraint (e.g. "=*m", "=r") if it accepts a memory location
src/codegen/llvm/Builder.zig-1
...@@ -159,7 +159,6 @@ pub const Type = enum(u32) {...@@ -159,7 +159,6 @@ pub const Type = enum(u32) {
159 none = std.math.maxInt(u32),159 none = std.math.maxInt(u32),
160 _,160 _,
161161
162 pub const err_int = Type.i16;
163 pub const ptr_amdgpu_constant =162 pub const ptr_amdgpu_constant =
164 @field(Type, std.fmt.comptimePrint("ptr{ }", .{AddrSpace.amdgpu.constant}));163 @field(Type, std.fmt.comptimePrint("ptr{ }", .{AddrSpace.amdgpu.constant}));
165164
src/codegen/spirv.zig+3-2
...@@ -742,16 +742,17 @@ const DeclGen = struct {...@@ -742,16 +742,17 @@ const DeclGen = struct {
742 .error_union => |error_union| {742 .error_union => |error_union| {
743 // TODO: Error unions may be constructed with constant instructions if the payload type743 // TODO: Error unions may be constructed with constant instructions if the payload type
744 // allows it. For now, just generate it here regardless.744 // allows it. For now, just generate it here regardless.
745 const err_int_ty = try mod.errorIntType();
745 const err_ty = switch (error_union.val) {746 const err_ty = switch (error_union.val) {
746 .err_name => ty.errorUnionSet(mod),747 .err_name => ty.errorUnionSet(mod),
747 .payload => Type.err_int,748 .payload => err_int_ty,
748 };749 };
749 const err_val = switch (error_union.val) {750 const err_val = switch (error_union.val) {
750 .err_name => |err_name| (try mod.intern(.{ .err = .{751 .err_name => |err_name| (try mod.intern(.{ .err = .{
751 .ty = ty.errorUnionSet(mod).toIntern(),752 .ty = ty.errorUnionSet(mod).toIntern(),
752 .name = err_name,753 .name = err_name,
753 } })).toValue(),754 } })).toValue(),
754 .payload => try mod.intValue(Type.err_int, 0),755 .payload => try mod.intValue(err_int_ty, 0),
755 };756 };
756 const payload_ty = ty.errorUnionPayload(mod);757 const payload_ty = ty.errorUnionPayload(mod);
757 const eu_layout = self.errorUnionLayout(payload_ty);758 const eu_layout = self.errorUnionLayout(payload_ty);
src/type.zig-2
...@@ -3309,8 +3309,6 @@ pub const Type = struct {...@@ -3309,8 +3309,6 @@ pub const Type = struct {
33093309
3310 pub const generic_poison: Type = .{ .ip_index = .generic_poison_type };3310 pub const generic_poison: Type = .{ .ip_index = .generic_poison_type };
33113311
3312 pub const err_int = Type.u16;
3313
3314 pub fn smallestUnsignedBits(max: u64) u16 {3312 pub fn smallestUnsignedBits(max: u64) u16 {
3315 if (max == 0) return 0;3313 if (max == 0) return 0;
3316 const base = std.math.log2(max);3314 const base = std.math.log2(max);