| ... | @@ -749,6 +749,12 @@ pub const DeclGen = struct { | ... | @@ -749,6 +749,12 @@ pub const DeclGen = struct { |
| 749 | const error_type = ty.errorUnionSet(); | 749 | const error_type = ty.errorUnionSet(); |
| 750 | const payload_type = ty.errorUnionPayload(); | 750 | const payload_type = ty.errorUnionPayload(); |
| 751 | | 751 | |
| | 752 | if (error_type.errorSetCardinality() == .zero) { |
| | 753 | // We use the payload directly as the type. |
| | 754 | const payload_val = val.castTag(.eu_payload).?.data; |
| | 755 | return dg.renderValue(writer, payload_type, payload_val, location); |
| | 756 | } |
| | 757 | |
| 752 | if (!payload_type.hasRuntimeBits()) { | 758 | if (!payload_type.hasRuntimeBits()) { |
| 753 | // We use the error type directly as the type. | 759 | // We use the error type directly as the type. |
| 754 | const err_val = if (val.errorUnionIsPayload()) Value.initTag(.zero) else val; | 760 | const err_val = if (val.errorUnionIsPayload()) Value.initTag(.zero) else val; |
| ... | @@ -894,10 +900,12 @@ pub const DeclGen = struct { | ... | @@ -894,10 +900,12 @@ pub const DeclGen = struct { |
| 894 | try w.writeAll("ZIG_COLD "); | 900 | try w.writeAll("ZIG_COLD "); |
| 895 | } | 901 | } |
| 896 | } | 902 | } |
| 897 | const return_ty = dg.decl.ty.fnReturnType(); | 903 | const fn_info = dg.decl.ty.fnInfo(); |
| 898 | if (return_ty.hasRuntimeBits()) { | 904 | if (fn_info.return_type.hasRuntimeBits()) { |
| 899 | try dg.renderType(w, return_ty); | 905 | try dg.renderType(w, fn_info.return_type); |
| 900 | } else if (return_ty.zigTypeTag() == .NoReturn) { | 906 | } else if (fn_info.return_type.isError()) { |
| | 907 | try dg.renderType(w, Type.anyerror); |
| | 908 | } else if (fn_info.return_type.zigTypeTag() == .NoReturn) { |
| 901 | try w.writeAll("zig_noreturn void"); | 909 | try w.writeAll("zig_noreturn void"); |
| 902 | } else { | 910 | } else { |
| 903 | try w.writeAll("void"); | 911 | try w.writeAll("void"); |
| ... | @@ -905,22 +913,19 @@ pub const DeclGen = struct { | ... | @@ -905,22 +913,19 @@ pub const DeclGen = struct { |
| 905 | try w.writeAll(" "); | 913 | try w.writeAll(" "); |
| 906 | try dg.renderDeclName(w, dg.decl_index); | 914 | try dg.renderDeclName(w, dg.decl_index); |
| 907 | try w.writeAll("("); | 915 | try w.writeAll("("); |
| 908 | const param_len = dg.decl.ty.fnParamLen(); | | |
| 909 | | 916 | |
| 910 | var index: usize = 0; | | |
| 911 | var params_written: usize = 0; | 917 | var params_written: usize = 0; |
| 912 | while (index < param_len) : (index += 1) { | 918 | for (fn_info.param_types) |param_type, index| { |
| 913 | const param_type = dg.decl.ty.fnParamType(index); | | |
| 914 | if (!param_type.hasRuntimeBitsIgnoreComptime()) continue; | 919 | if (!param_type.hasRuntimeBitsIgnoreComptime()) continue; |
| 915 | if (params_written > 0) { | 920 | if (params_written > 0) { |
| 916 | try w.writeAll(", "); | 921 | try w.writeAll(", "); |
| 917 | } | 922 | } |
| 918 | const name = CValue{ .arg = index }; | 923 | const name = CValue{ .arg = index }; |
| 919 | try dg.renderTypeAndName(w, dg.decl.ty.fnParamType(index), name, .Mut, 0); | 924 | try dg.renderTypeAndName(w, param_type, name, .Mut, 0); |
| 920 | params_written += 1; | 925 | params_written += 1; |
| 921 | } | 926 | } |
| 922 | | 927 | |
| 923 | if (dg.decl.ty.fnIsVarArgs()) { | 928 | if (fn_info.is_var_args) { |
| 924 | if (params_written != 0) try w.writeAll(", "); | 929 | if (params_written != 0) try w.writeAll(", "); |
| 925 | try w.writeAll("..."); | 930 | try w.writeAll("..."); |
| 926 | } else if (params_written == 0) { | 931 | } else if (params_written == 0) { |
| ... | @@ -1156,26 +1161,36 @@ pub const DeclGen = struct { | ... | @@ -1156,26 +1161,36 @@ pub const DeclGen = struct { |
| 1156 | } | 1161 | } |
| 1157 | | 1162 | |
| 1158 | fn renderErrorUnionTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { | 1163 | fn renderErrorUnionTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 1159 | const child_type = t.errorUnionPayload(); | 1164 | const payload_ty = t.errorUnionPayload(); |
| 1160 | const err_set_type = t.errorUnionSet(); | 1165 | const error_ty = t.errorUnionSet(); |
| 1161 | | 1166 | |
| 1162 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); | 1167 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 1163 | defer buffer.deinit(); | 1168 | defer buffer.deinit(); |
| 1164 | const bw = buffer.writer(); | 1169 | const bw = buffer.writer(); |
| 1165 | | 1170 | |
| 1166 | try bw.writeAll("typedef struct { "); | | |
| 1167 | const payload_name = CValue{ .bytes = "payload" }; | 1171 | const payload_name = CValue{ .bytes = "payload" }; |
| 1168 | try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0); | 1172 | const target = dg.module.getTarget(); |
| 1169 | try bw.writeAll("; uint16_t error; } "); | 1173 | const payload_align = payload_ty.abiAlignment(target); |
| | 1174 | const error_align = Type.anyerror.abiAlignment(target); |
| | 1175 | if (error_align > payload_align) { |
| | 1176 | try bw.writeAll("typedef struct { "); |
| | 1177 | try dg.renderTypeAndName(bw, payload_ty, payload_name, .Mut, 0); |
| | 1178 | try bw.writeAll("; uint16_t error; } "); |
| | 1179 | } else { |
| | 1180 | try bw.writeAll("typedef struct { uint16_t error; "); |
| | 1181 | try dg.renderTypeAndName(bw, payload_ty, payload_name, .Mut, 0); |
| | 1182 | try bw.writeAll("; } "); |
| | 1183 | } |
| | 1184 | |
| 1170 | const name_index = buffer.items.len; | 1185 | const name_index = buffer.items.len; |
| 1171 | if (err_set_type.castTag(.error_set_inferred)) |inf_err_set_payload| { | 1186 | if (error_ty.castTag(.error_set_inferred)) |inf_err_set_payload| { |
| 1172 | const func = inf_err_set_payload.data.func; | 1187 | const func = inf_err_set_payload.data.func; |
| 1173 | try bw.writeAll("zig_E_"); | 1188 | try bw.writeAll("zig_E_"); |
| 1174 | try dg.renderDeclName(bw, func.owner_decl); | 1189 | try dg.renderDeclName(bw, func.owner_decl); |
| 1175 | try bw.writeAll(";\n"); | 1190 | try bw.writeAll(";\n"); |
| 1176 | } else { | 1191 | } else { |
| 1177 | try bw.print("zig_E_{s}_{s};\n", .{ | 1192 | try bw.print("zig_E_{s}_{s};\n", .{ |
| 1178 | typeToCIdentifier(err_set_type, dg.module), typeToCIdentifier(child_type, dg.module), | 1193 | typeToCIdentifier(error_ty, dg.module), typeToCIdentifier(payload_ty, dg.module), |
| 1179 | }); | 1194 | }); |
| 1180 | } | 1195 | } |
| 1181 | | 1196 | |
| ... | @@ -1359,12 +1374,19 @@ pub const DeclGen = struct { | ... | @@ -1359,12 +1374,19 @@ pub const DeclGen = struct { |
| 1359 | return w.writeAll(name); | 1374 | return w.writeAll(name); |
| 1360 | }, | 1375 | }, |
| 1361 | .ErrorSet => { | 1376 | .ErrorSet => { |
| 1362 | comptime assert(Type.initTag(.anyerror).abiSize(builtin.target) == 2); | 1377 | comptime assert(Type.anyerror.abiSize(builtin.target) == 2); |
| 1363 | return w.writeAll("uint16_t"); | 1378 | return w.writeAll("uint16_t"); |
| 1364 | }, | 1379 | }, |
| 1365 | .ErrorUnion => { | 1380 | .ErrorUnion => { |
| 1366 | if (t.errorUnionPayload().abiSize(target) == 0) { | 1381 | const error_ty = t.errorUnionSet(); |
| 1367 | return dg.renderType(w, t.errorUnionSet()); | 1382 | const payload_ty = t.errorUnionPayload(); |
| | 1383 | |
| | 1384 | if (error_ty.errorSetCardinality() == .zero) { |
| | 1385 | return dg.renderType(w, payload_ty); |
| | 1386 | } |
| | 1387 | |
| | 1388 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| | 1389 | return dg.renderType(w, Type.anyerror); |
| 1368 | } | 1390 | } |
| 1369 | | 1391 | |
| 1370 | const name = dg.getTypedefName(t) orelse | 1392 | const name = dg.getTypedefName(t) orelse |
| ... | @@ -1901,8 +1923,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO | ... | @@ -1901,8 +1923,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1901 | .array_elem_val => try airArrayElemVal(f, inst), | 1923 | .array_elem_val => try airArrayElemVal(f, inst), |
| 1902 | | 1924 | |
| 1903 | .unwrap_errunion_payload => try airUnwrapErrUnionPay(f, inst, ""), | 1925 | .unwrap_errunion_payload => try airUnwrapErrUnionPay(f, inst, ""), |
| 1904 | .unwrap_errunion_err => try airUnwrapErrUnionErr(f, inst), | | |
| 1905 | .unwrap_errunion_payload_ptr => try airUnwrapErrUnionPay(f, inst, "&"), | 1926 | .unwrap_errunion_payload_ptr => try airUnwrapErrUnionPay(f, inst, "&"), |
| | 1927 | .unwrap_errunion_err => try airUnwrapErrUnionErr(f, inst), |
| 1906 | .unwrap_errunion_err_ptr => try airUnwrapErrUnionErr(f, inst), | 1928 | .unwrap_errunion_err_ptr => try airUnwrapErrUnionErr(f, inst), |
| 1907 | .wrap_errunion_payload => try airWrapErrUnionPay(f, inst), | 1929 | .wrap_errunion_payload => try airWrapErrUnionPay(f, inst), |
| 1908 | .wrap_errunion_err => try airWrapErrUnionErr(f, inst), | 1930 | .wrap_errunion_err => try airWrapErrUnionErr(f, inst), |
| ... | @@ -2120,11 +2142,14 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2120,11 +2142,14 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2120 | fn airRet(f: *Function, inst: Air.Inst.Index) !CValue { | 2142 | fn airRet(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2121 | const un_op = f.air.instructions.items(.data)[inst].un_op; | 2143 | const un_op = f.air.instructions.items(.data)[inst].un_op; |
| 2122 | const writer = f.object.writer(); | 2144 | const writer = f.object.writer(); |
| 2123 | if (f.air.typeOf(un_op).isFnOrHasRuntimeBitsIgnoreComptime()) { | 2145 | const ret_ty = f.air.typeOf(un_op); |
| | 2146 | if (ret_ty.isFnOrHasRuntimeBitsIgnoreComptime()) { |
| 2124 | const operand = try f.resolveInst(un_op); | 2147 | const operand = try f.resolveInst(un_op); |
| 2125 | try writer.writeAll("return "); | 2148 | try writer.writeAll("return "); |
| 2126 | try f.writeCValue(writer, operand); | 2149 | try f.writeCValue(writer, operand); |
| 2127 | try writer.writeAll(";\n"); | 2150 | try writer.writeAll(";\n"); |
| | 2151 | } else if (ret_ty.isError()) { |
| | 2152 | try writer.writeAll("return 0;"); |
| 2128 | } else { | 2153 | } else { |
| 2129 | try writer.writeAll("return;\n"); | 2154 | try writer.writeAll("return;\n"); |
| 2130 | } | 2155 | } |
| ... | @@ -2136,13 +2161,16 @@ fn airRetLoad(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2136,13 +2161,16 @@ fn airRetLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2136 | const writer = f.object.writer(); | 2161 | const writer = f.object.writer(); |
| 2137 | const ptr_ty = f.air.typeOf(un_op); | 2162 | const ptr_ty = f.air.typeOf(un_op); |
| 2138 | const ret_ty = ptr_ty.childType(); | 2163 | const ret_ty = ptr_ty.childType(); |
| 2139 | if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime()) { | 2164 | if (ret_ty.isFnOrHasRuntimeBitsIgnoreComptime()) { |
| | 2165 | const ptr = try f.resolveInst(un_op); |
| | 2166 | try writer.writeAll("return *"); |
| | 2167 | try f.writeCValue(writer, ptr); |
| | 2168 | try writer.writeAll(";\n"); |
| | 2169 | } else if (ret_ty.isError()) { |
| | 2170 | try writer.writeAll("return 0;\n"); |
| | 2171 | } else { |
| 2140 | try writer.writeAll("return;\n"); | 2172 | try writer.writeAll("return;\n"); |
| 2141 | } | 2173 | } |
| 2142 | const ptr = try f.resolveInst(un_op); | | |
| 2143 | try writer.writeAll("return *"); | | |
| 2144 | try f.writeCValue(writer, ptr); | | |
| 2145 | try writer.writeAll(";\n"); | | |
| 2146 | return CValue.none; | 2174 | return CValue.none; |
| 2147 | } | 2175 | } |
| 2148 | | 2176 | |
| ... | @@ -2713,19 +2741,20 @@ fn airCall( | ... | @@ -2713,19 +2741,20 @@ fn airCall( |
| 2713 | .Pointer => callee_ty.childType(), | 2741 | .Pointer => callee_ty.childType(), |
| 2714 | else => unreachable, | 2742 | else => unreachable, |
| 2715 | }; | 2743 | }; |
| 2716 | const ret_ty = fn_ty.fnReturnType(); | | |
| 2717 | const unused_result = f.liveness.isUnused(inst); | | |
| 2718 | const writer = f.object.writer(); | 2744 | const writer = f.object.writer(); |
| 2719 | | 2745 | |
| 2720 | var result_local: CValue = .none; | 2746 | const result_local: CValue = r: { |
| 2721 | if (unused_result) { | 2747 | if (f.liveness.isUnused(inst)) { |
| 2722 | if (ret_ty.hasRuntimeBits()) { | 2748 | if (loweredFnRetTyHasBits(fn_ty)) { |
| 2723 | try writer.print("(void)", .{}); | 2749 | try writer.print("(void)", .{}); |
| | 2750 | } |
| | 2751 | break :r .none; |
| | 2752 | } else { |
| | 2753 | const local = try f.allocLocal(fn_ty.fnReturnType(), .Const); |
| | 2754 | try writer.writeAll(" = "); |
| | 2755 | break :r local; |
| 2724 | } | 2756 | } |
| 2725 | } else { | 2757 | }; |
| 2726 | result_local = try f.allocLocal(ret_ty, .Const); | | |
| 2727 | try writer.writeAll(" = "); | | |
| 2728 | } | | |
| 2729 | | 2758 | |
| 2730 | callee: { | 2759 | callee: { |
| 2731 | known: { | 2760 | known: { |
| ... | @@ -3307,7 +3336,8 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3307,7 +3336,8 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3307 | return local; | 3336 | return local; |
| 3308 | } | 3337 | } |
| 3309 | | 3338 | |
| 3310 | // *(E!T) -> E NOT *E | 3339 | /// *(E!T) -> E |
| | 3340 | /// Note that the result is never a pointer. |
| 3311 | fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | 3341 | fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3312 | if (f.liveness.isUnused(inst)) | 3342 | if (f.liveness.isUnused(inst)) |
| 3313 | return CValue.none; | 3343 | return CValue.none; |
| ... | @@ -3319,7 +3349,11 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3319,7 +3349,11 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3319 | const operand_ty = f.air.typeOf(ty_op.operand); | 3349 | const operand_ty = f.air.typeOf(ty_op.operand); |
| 3320 | | 3350 | |
| 3321 | if (operand_ty.zigTypeTag() == .Pointer) { | 3351 | if (operand_ty.zigTypeTag() == .Pointer) { |
| 3322 | if (!operand_ty.childType().errorUnionPayload().hasRuntimeBits()) { | 3352 | const err_union_ty = operand_ty.childType(); |
| | 3353 | if (err_union_ty.errorUnionSet().errorSetCardinality() == .zero) { |
| | 3354 | return CValue{ .bytes = "0" }; |
| | 3355 | } |
| | 3356 | if (!err_union_ty.errorUnionPayload().hasRuntimeBits()) { |
| 3323 | return operand; | 3357 | return operand; |
| 3324 | } | 3358 | } |
| 3325 | const local = try f.allocLocal(inst_ty, .Const); | 3359 | const local = try f.allocLocal(inst_ty, .Const); |
| ... | @@ -3328,6 +3362,9 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3328,6 +3362,9 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3328 | try writer.writeAll(";\n"); | 3362 | try writer.writeAll(";\n"); |
| 3329 | return local; | 3363 | return local; |
| 3330 | } | 3364 | } |
| | 3365 | if (operand_ty.errorUnionSet().errorSetCardinality() == .zero) { |
| | 3366 | return CValue{ .bytes = "0" }; |
| | 3367 | } |
| 3331 | if (!operand_ty.errorUnionPayload().hasRuntimeBits()) { | 3368 | if (!operand_ty.errorUnionPayload().hasRuntimeBits()) { |
| 3332 | return operand; | 3369 | return operand; |
| 3333 | } | 3370 | } |
| ... | @@ -3343,7 +3380,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3343,7 +3380,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3343 | return local; | 3380 | return local; |
| 3344 | } | 3381 | } |
| 3345 | | 3382 | |
| 3346 | fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, maybe_addrof: []const u8) !CValue { | 3383 | fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, maybe_addrof: [*:0]const u8) !CValue { |
| 3347 | if (f.liveness.isUnused(inst)) | 3384 | if (f.liveness.isUnused(inst)) |
| 3348 | return CValue.none; | 3385 | return CValue.none; |
| 3349 | | 3386 | |
| ... | @@ -3351,17 +3388,19 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, maybe_addrof: []cons | ... | @@ -3351,17 +3388,19 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, maybe_addrof: []cons |
| 3351 | const writer = f.object.writer(); | 3388 | const writer = f.object.writer(); |
| 3352 | const operand = try f.resolveInst(ty_op.operand); | 3389 | const operand = try f.resolveInst(ty_op.operand); |
| 3353 | const operand_ty = f.air.typeOf(ty_op.operand); | 3390 | const operand_ty = f.air.typeOf(ty_op.operand); |
| | 3391 | const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer; |
| | 3392 | const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; |
| | 3393 | |
| | 3394 | if (error_union_ty.errorUnionSet().errorSetCardinality() == .zero) { |
| | 3395 | return operand; |
| | 3396 | } |
| 3354 | | 3397 | |
| 3355 | const error_union_ty = if (operand_ty.zigTypeTag() == .Pointer) | | |
| 3356 | operand_ty.childType() | | |
| 3357 | else | | |
| 3358 | operand_ty; | | |
| 3359 | if (!error_union_ty.errorUnionPayload().hasRuntimeBits()) { | 3398 | if (!error_union_ty.errorUnionPayload().hasRuntimeBits()) { |
| 3360 | return CValue.none; | 3399 | return CValue.none; |
| 3361 | } | 3400 | } |
| 3362 | | 3401 | |
| 3363 | const inst_ty = f.air.typeOfIndex(inst); | 3402 | const inst_ty = f.air.typeOfIndex(inst); |
| 3364 | const maybe_deref = if (operand_ty.zigTypeTag() == .Pointer) "->" else "."; | 3403 | const maybe_deref = if (operand_is_ptr) "->" else "."; |
| 3365 | | 3404 | |
| 3366 | const local = try f.allocLocal(inst_ty, .Const); | 3405 | const local = try f.allocLocal(inst_ty, .Const); |
| 3367 | try writer.print(" = {s}(", .{maybe_addrof}); | 3406 | try writer.print(" = {s}(", .{maybe_addrof}); |
| ... | @@ -3421,6 +3460,11 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3421,6 +3460,11 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3421 | const error_ty = error_union_ty.errorUnionSet(); | 3460 | const error_ty = error_union_ty.errorUnionSet(); |
| 3422 | const payload_ty = error_union_ty.errorUnionPayload(); | 3461 | const payload_ty = error_union_ty.errorUnionPayload(); |
| 3423 | | 3462 | |
| | 3463 | if (error_ty.errorSetCardinality() == .zero) { |
| | 3464 | // TODO: write undefined bytes through the pointer here |
| | 3465 | return operand; |
| | 3466 | } |
| | 3467 | |
| 3424 | // First, set the non-error value. | 3468 | // First, set the non-error value. |
| 3425 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 3469 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 3426 | try f.writeCValueDeref(writer, operand); | 3470 | try f.writeCValueDeref(writer, operand); |
| ... | @@ -3464,6 +3508,9 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3464,6 +3508,9 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3464 | const operand = try f.resolveInst(ty_op.operand); | 3508 | const operand = try f.resolveInst(ty_op.operand); |
| 3465 | | 3509 | |
| 3466 | const inst_ty = f.air.typeOfIndex(inst); | 3510 | const inst_ty = f.air.typeOfIndex(inst); |
| | 3511 | if (inst_ty.errorUnionSet().errorSetCardinality() == .zero) { |
| | 3512 | return operand; |
| | 3513 | } |
| 3467 | const local = try f.allocLocal(inst_ty, .Const); | 3514 | const local = try f.allocLocal(inst_ty, .Const); |
| 3468 | try writer.writeAll(" = { .error = 0, .payload = "); | 3515 | try writer.writeAll(" = { .error = 0, .payload = "); |
| 3469 | try f.writeCValue(writer, operand); | 3516 | try f.writeCValue(writer, operand); |
| ... | @@ -3486,16 +3533,23 @@ fn airIsErr( | ... | @@ -3486,16 +3533,23 @@ fn airIsErr( |
| 3486 | const operand_ty = f.air.typeOf(un_op); | 3533 | const operand_ty = f.air.typeOf(un_op); |
| 3487 | const local = try f.allocLocal(Type.initTag(.bool), .Const); | 3534 | const local = try f.allocLocal(Type.initTag(.bool), .Const); |
| 3488 | const payload_ty = operand_ty.errorUnionPayload(); | 3535 | const payload_ty = operand_ty.errorUnionPayload(); |
| | 3536 | const error_ty = operand_ty.errorUnionSet(); |
| | 3537 | |
| 3489 | try writer.writeAll(" = "); | 3538 | try writer.writeAll(" = "); |
| 3490 | if (is_ptr) { | 3539 | |
| 3491 | try f.writeCValueDeref(writer, operand); | 3540 | if (error_ty.errorSetCardinality() == .zero) { |
| | 3541 | try writer.print("0 {s} 0;\n", .{op_str}); |
| 3492 | } else { | 3542 | } else { |
| 3493 | try f.writeCValue(writer, operand); | 3543 | if (is_ptr) { |
| 3494 | } | 3544 | try f.writeCValueDeref(writer, operand); |
| 3495 | if (payload_ty.hasRuntimeBits()) { | 3545 | } else { |
| 3496 | try writer.writeAll(".error"); | 3546 | try f.writeCValue(writer, operand); |
| | 3547 | } |
| | 3548 | if (payload_ty.hasRuntimeBits()) { |
| | 3549 | try writer.writeAll(".error"); |
| | 3550 | } |
| | 3551 | try writer.print(" {s} 0;\n", .{op_str}); |
| 3497 | } | 3552 | } |
| 3498 | try writer.print(" {s} 0;\n", .{op_str}); | | |
| 3499 | return local; | 3553 | return local; |
| 3500 | } | 3554 | } |
| 3501 | | 3555 | |
| ... | @@ -4129,3 +4183,14 @@ fn intMin(ty: Type, target: std.Target, buf: []u8) []const u8 { | ... | @@ -4129,3 +4183,14 @@ fn intMin(ty: Type, target: std.Target, buf: []u8) []const u8 { |
| 4129 | }, | 4183 | }, |
| 4130 | } | 4184 | } |
| 4131 | } | 4185 | } |
| | 4186 | |
| | 4187 | fn loweredFnRetTyHasBits(fn_ty: Type) bool { |
| | 4188 | const ret_ty = fn_ty.fnReturnType(); |
| | 4189 | if (ret_ty.hasRuntimeBitsIgnoreComptime()) { |
| | 4190 | return true; |
| | 4191 | } |
| | 4192 | if (ret_ty.isError()) { |
| | 4193 | return true; |
| | 4194 | } |
| | 4195 | return false; |
| | 4196 | } |