| ... | ... | @@ -360,6 +360,12 @@ pub const DeclGen = struct { |
| 360 | 360 | const error_type = t.errorUnionSet(); |
| 361 | 361 | const payload_type = t.errorUnionChild(); |
| 362 | 362 | const data = val.castTag(.error_union).?.data; |
| 363 | |
| 364 | if (!payload_type.hasCodeGenBits()) { |
| 365 | // We use the error type directly as the type. |
| 366 | return dg.renderValue(writer, error_type, data); |
| 367 | } |
| 368 | |
| 363 | 369 | try writer.writeByte('('); |
| 364 | 370 | try dg.renderType(writer, t); |
| 365 | 371 | try writer.writeAll("){"); |
| ... | ... | @@ -604,6 +610,10 @@ pub const DeclGen = struct { |
| 604 | 610 | const child_type = t.errorUnionChild(); |
| 605 | 611 | const err_set_type = t.errorUnionSet(); |
| 606 | 612 | |
| 613 | if (!child_type.hasCodeGenBits()) { |
| 614 | return dg.renderType(w, err_set_type); |
| 615 | } |
| 616 | |
| 607 | 617 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 608 | 618 | defer buffer.deinit(); |
| 609 | 619 | const bw = buffer.writer(); |
| ... | ... | @@ -613,7 +623,7 @@ pub const DeclGen = struct { |
| 613 | 623 | try bw.writeAll(" payload; uint16_t error; } "); |
| 614 | 624 | const name_index = buffer.items.len; |
| 615 | 625 | if (err_set_type.castTag(.error_set_inferred)) |inf_err_set_payload| { |
| 616 | | const func = inf_err_set_payload.data; |
| 626 | const func = inf_err_set_payload.data.func; |
| 617 | 627 | try bw.print("zig_E_{s};\n", .{func.owner_decl.name}); |
| 618 | 628 | } else { |
| 619 | 629 | try bw.print("zig_E_{s}_{s};\n", .{ |
| ... | ... | @@ -895,10 +905,10 @@ pub fn genBody(o: *Object, body: ir.Body) error{ AnalysisFail, OutOfMemory }!voi |
| 895 | 905 | .ref => try genRef(o, inst.castTag(.ref).?), |
| 896 | 906 | .struct_field_ptr => try genStructFieldPtr(o, inst.castTag(.struct_field_ptr).?), |
| 897 | 907 | |
| 898 | | .is_err => try genIsErr(o, inst.castTag(.is_err).?, "", "!="), |
| 899 | | .is_non_err => try genIsErr(o, inst.castTag(.is_non_err).?, "", "=="), |
| 900 | | .is_err_ptr => try genIsErr(o, inst.castTag(.is_err_ptr).?, "[0]", "!="), |
| 901 | | .is_non_err_ptr => try genIsErr(o, inst.castTag(.is_non_err_ptr).?, "[0]", "=="), |
| 908 | .is_err => try genIsErr(o, inst.castTag(.is_err).?, "", ".", "!="), |
| 909 | .is_non_err => try genIsErr(o, inst.castTag(.is_non_err).?, "", ".", "=="), |
| 910 | .is_err_ptr => try genIsErr(o, inst.castTag(.is_err_ptr).?, "*", "->", "!="), |
| 911 | .is_non_err_ptr => try genIsErr(o, inst.castTag(.is_non_err_ptr).?, "*", "->", "=="), |
| 902 | 912 | |
| 903 | 913 | .unwrap_errunion_payload => try genUnwrapErrUnionPay(o, inst.castTag(.unwrap_errunion_payload).?), |
| 904 | 914 | .unwrap_errunion_err => try genUnwrapErrUnionErr(o, inst.castTag(.unwrap_errunion_err).?), |
| ... | ... | @@ -1384,9 +1394,25 @@ fn genStructFieldPtr(o: *Object, inst: *Inst.StructFieldPtr) !CValue { |
| 1384 | 1394 | |
| 1385 | 1395 | // *(E!T) -> E NOT *E |
| 1386 | 1396 | fn genUnwrapErrUnionErr(o: *Object, inst: *Inst.UnOp) !CValue { |
| 1397 | if (inst.base.isUnused()) |
| 1398 | return CValue.none; |
| 1399 | |
| 1387 | 1400 | const writer = o.writer(); |
| 1388 | 1401 | const operand = try o.resolveInst(inst.operand); |
| 1389 | 1402 | |
| 1403 | const payload_ty = inst.operand.ty.errorUnionChild(); |
| 1404 | if (!payload_ty.hasCodeGenBits()) { |
| 1405 | if (inst.operand.ty.zigTypeTag() == .Pointer) { |
| 1406 | const local = try o.allocLocal(inst.base.ty, .Const); |
| 1407 | try writer.writeAll(" = *"); |
| 1408 | try o.writeCValue(writer, operand); |
| 1409 | try writer.writeAll(";\n"); |
| 1410 | return local; |
| 1411 | } else { |
| 1412 | return operand; |
| 1413 | } |
| 1414 | } |
| 1415 | |
| 1390 | 1416 | const maybe_deref = if (inst.operand.ty.zigTypeTag() == .Pointer) "->" else "."; |
| 1391 | 1417 | |
| 1392 | 1418 | const local = try o.allocLocal(inst.base.ty, .Const); |
| ... | ... | @@ -1396,10 +1422,19 @@ fn genUnwrapErrUnionErr(o: *Object, inst: *Inst.UnOp) !CValue { |
| 1396 | 1422 | try writer.print("){s}error;\n", .{maybe_deref}); |
| 1397 | 1423 | return local; |
| 1398 | 1424 | } |
| 1425 | |
| 1399 | 1426 | fn genUnwrapErrUnionPay(o: *Object, inst: *Inst.UnOp) !CValue { |
| 1427 | if (inst.base.isUnused()) |
| 1428 | return CValue.none; |
| 1429 | |
| 1400 | 1430 | const writer = o.writer(); |
| 1401 | 1431 | const operand = try o.resolveInst(inst.operand); |
| 1402 | 1432 | |
| 1433 | const payload_ty = inst.operand.ty.errorUnionChild(); |
| 1434 | if (!payload_ty.hasCodeGenBits()) { |
| 1435 | return CValue.none; |
| 1436 | } |
| 1437 | |
| 1403 | 1438 | const maybe_deref = if (inst.operand.ty.zigTypeTag() == .Pointer) "->" else "."; |
| 1404 | 1439 | const maybe_addrof = if (inst.base.ty.zigTypeTag() == .Pointer) "&" else ""; |
| 1405 | 1440 | |
| ... | ... | @@ -1448,14 +1483,26 @@ fn genWrapErrUnionPay(o: *Object, inst: *Inst.UnOp) !CValue { |
| 1448 | 1483 | return local; |
| 1449 | 1484 | } |
| 1450 | 1485 | |
| 1451 | | fn genIsErr(o: *Object, inst: *Inst.UnOp, deref_suffix: []const u8, op_str: []const u8) !CValue { |
| 1486 | fn genIsErr( |
| 1487 | o: *Object, |
| 1488 | inst: *Inst.UnOp, |
| 1489 | deref_prefix: [*:0]const u8, |
| 1490 | deref_suffix: [*:0]const u8, |
| 1491 | op_str: [*:0]const u8, |
| 1492 | ) !CValue { |
| 1452 | 1493 | const writer = o.writer(); |
| 1453 | 1494 | const operand = try o.resolveInst(inst.operand); |
| 1454 | | |
| 1455 | 1495 | const local = try o.allocLocal(Type.initTag(.bool), .Const); |
| 1456 | | try writer.writeAll(" = ("); |
| 1457 | | try o.writeCValue(writer, operand); |
| 1458 | | try writer.print("){s}.error {s} 0;\n", .{ deref_suffix, op_str }); |
| 1496 | const payload_ty = inst.operand.ty.errorUnionChild(); |
| 1497 | if (!payload_ty.hasCodeGenBits()) { |
| 1498 | try writer.print(" = {s}", .{deref_prefix}); |
| 1499 | try o.writeCValue(writer, operand); |
| 1500 | try writer.print(" {s} 0;\n", .{op_str}); |
| 1501 | } else { |
| 1502 | try writer.writeAll(" = "); |
| 1503 | try o.writeCValue(writer, operand); |
| 1504 | try writer.print("{s}error {s} 0;\n", .{ deref_suffix, op_str }); |
| 1505 | } |
| 1459 | 1506 | return local; |
| 1460 | 1507 | } |
| 1461 | 1508 | |