| ... | @@ -360,6 +360,12 @@ pub const DeclGen = struct { | ... | @@ -360,6 +360,12 @@ pub const DeclGen = struct { |
| 360 | const error_type = t.errorUnionSet(); | 360 | const error_type = t.errorUnionSet(); |
| 361 | const payload_type = t.errorUnionChild(); | 361 | const payload_type = t.errorUnionChild(); |
| 362 | const data = val.castTag(.error_union).?.data; | 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 | try writer.writeByte('('); | 369 | try writer.writeByte('('); |
| 364 | try dg.renderType(writer, t); | 370 | try dg.renderType(writer, t); |
| 365 | try writer.writeAll("){"); | 371 | try writer.writeAll("){"); |
| ... | @@ -604,6 +610,10 @@ pub const DeclGen = struct { | ... | @@ -604,6 +610,10 @@ pub const DeclGen = struct { |
| 604 | const child_type = t.errorUnionChild(); | 610 | const child_type = t.errorUnionChild(); |
| 605 | const err_set_type = t.errorUnionSet(); | 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 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); | 617 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 608 | defer buffer.deinit(); | 618 | defer buffer.deinit(); |
| 609 | const bw = buffer.writer(); | 619 | const bw = buffer.writer(); |
| ... | @@ -613,7 +623,7 @@ pub const DeclGen = struct { | ... | @@ -613,7 +623,7 @@ pub const DeclGen = struct { |
| 613 | try bw.writeAll(" payload; uint16_t error; } "); | 623 | try bw.writeAll(" payload; uint16_t error; } "); |
| 614 | const name_index = buffer.items.len; | 624 | const name_index = buffer.items.len; |
| 615 | if (err_set_type.castTag(.error_set_inferred)) |inf_err_set_payload| { | 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 | try bw.print("zig_E_{s};\n", .{func.owner_decl.name}); | 627 | try bw.print("zig_E_{s};\n", .{func.owner_decl.name}); |
| 618 | } else { | 628 | } else { |
| 619 | try bw.print("zig_E_{s}_{s};\n", .{ | 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,10 +905,10 @@ pub fn genBody(o: *Object, body: ir.Body) error{ AnalysisFail, OutOfMemory }!voi |
| 895 | .ref => try genRef(o, inst.castTag(.ref).?), | 905 | .ref => try genRef(o, inst.castTag(.ref).?), |
| 896 | .struct_field_ptr => try genStructFieldPtr(o, inst.castTag(.struct_field_ptr).?), | 906 | .struct_field_ptr => try genStructFieldPtr(o, inst.castTag(.struct_field_ptr).?), |
| 897 | | 907 | |
| 898 | .is_err => try genIsErr(o, inst.castTag(.is_err).?, "", "!="), | 908 | .is_err => try genIsErr(o, inst.castTag(.is_err).?, "", ".", "!="), |
| 899 | .is_non_err => try genIsErr(o, inst.castTag(.is_non_err).?, "", "=="), | 909 | .is_non_err => try genIsErr(o, inst.castTag(.is_non_err).?, "", ".", "=="), |
| 900 | .is_err_ptr => try genIsErr(o, inst.castTag(.is_err_ptr).?, "[0]", "!="), | 910 | .is_err_ptr => try genIsErr(o, inst.castTag(.is_err_ptr).?, "*", "->", "!="), |
| 901 | .is_non_err_ptr => try genIsErr(o, inst.castTag(.is_non_err_ptr).?, "[0]", "=="), | 911 | .is_non_err_ptr => try genIsErr(o, inst.castTag(.is_non_err_ptr).?, "*", "->", "=="), |
| 902 | | 912 | |
| 903 | .unwrap_errunion_payload => try genUnwrapErrUnionPay(o, inst.castTag(.unwrap_errunion_payload).?), | 913 | .unwrap_errunion_payload => try genUnwrapErrUnionPay(o, inst.castTag(.unwrap_errunion_payload).?), |
| 904 | .unwrap_errunion_err => try genUnwrapErrUnionErr(o, inst.castTag(.unwrap_errunion_err).?), | 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,9 +1394,25 @@ fn genStructFieldPtr(o: *Object, inst: *Inst.StructFieldPtr) !CValue { |
| 1384 | | 1394 | |
| 1385 | // *(E!T) -> E NOT *E | 1395 | // *(E!T) -> E NOT *E |
| 1386 | fn genUnwrapErrUnionErr(o: *Object, inst: *Inst.UnOp) !CValue { | 1396 | fn genUnwrapErrUnionErr(o: *Object, inst: *Inst.UnOp) !CValue { |
| | 1397 | if (inst.base.isUnused()) |
| | 1398 | return CValue.none; |
| | 1399 | |
| 1387 | const writer = o.writer(); | 1400 | const writer = o.writer(); |
| 1388 | const operand = try o.resolveInst(inst.operand); | 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 | const maybe_deref = if (inst.operand.ty.zigTypeTag() == .Pointer) "->" else "."; | 1416 | const maybe_deref = if (inst.operand.ty.zigTypeTag() == .Pointer) "->" else "."; |
| 1391 | | 1417 | |
| 1392 | const local = try o.allocLocal(inst.base.ty, .Const); | 1418 | const local = try o.allocLocal(inst.base.ty, .Const); |
| ... | @@ -1396,10 +1422,19 @@ fn genUnwrapErrUnionErr(o: *Object, inst: *Inst.UnOp) !CValue { | ... | @@ -1396,10 +1422,19 @@ fn genUnwrapErrUnionErr(o: *Object, inst: *Inst.UnOp) !CValue { |
| 1396 | try writer.print("){s}error;\n", .{maybe_deref}); | 1422 | try writer.print("){s}error;\n", .{maybe_deref}); |
| 1397 | return local; | 1423 | return local; |
| 1398 | } | 1424 | } |
| | 1425 | |
| 1399 | fn genUnwrapErrUnionPay(o: *Object, inst: *Inst.UnOp) !CValue { | 1426 | fn genUnwrapErrUnionPay(o: *Object, inst: *Inst.UnOp) !CValue { |
| | 1427 | if (inst.base.isUnused()) |
| | 1428 | return CValue.none; |
| | 1429 | |
| 1400 | const writer = o.writer(); | 1430 | const writer = o.writer(); |
| 1401 | const operand = try o.resolveInst(inst.operand); | 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 | const maybe_deref = if (inst.operand.ty.zigTypeTag() == .Pointer) "->" else "."; | 1438 | const maybe_deref = if (inst.operand.ty.zigTypeTag() == .Pointer) "->" else "."; |
| 1404 | const maybe_addrof = if (inst.base.ty.zigTypeTag() == .Pointer) "&" else ""; | 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,14 +1483,26 @@ fn genWrapErrUnionPay(o: *Object, inst: *Inst.UnOp) !CValue { |
| 1448 | return local; | 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 | const writer = o.writer(); | 1493 | const writer = o.writer(); |
| 1453 | const operand = try o.resolveInst(inst.operand); | 1494 | const operand = try o.resolveInst(inst.operand); |
| 1454 | | | |
| 1455 | const local = try o.allocLocal(Type.initTag(.bool), .Const); | 1495 | const local = try o.allocLocal(Type.initTag(.bool), .Const); |
| 1456 | try writer.writeAll(" = ("); | 1496 | const payload_ty = inst.operand.ty.errorUnionChild(); |
| 1457 | try o.writeCValue(writer, operand); | 1497 | if (!payload_ty.hasCodeGenBits()) { |
| 1458 | try writer.print("){s}.error {s} 0;\n", .{ deref_suffix, op_str }); | 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 | return local; | 1506 | return local; |
| 1460 | } | 1507 | } |
| 1461 | | 1508 | |