| ... | ... | @@ -1470,16 +1470,25 @@ pub const Object = struct { |
| 1470 | 1470 | return full_di_ty; |
| 1471 | 1471 | }, |
| 1472 | 1472 | .ErrorUnion => { |
| 1473 | | const err_set_ty = ty.errorUnionSet(); |
| 1474 | 1473 | const payload_ty = ty.errorUnionPayload(); |
| 1475 | | if (err_set_ty.errorSetCardinality() == .zero) { |
| 1476 | | const payload_di_ty = try o.lowerDebugType(payload_ty, .full); |
| 1477 | | // The recursive call to `lowerDebugType` means we can't use `gop` anymore. |
| 1478 | | try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(payload_di_ty), .{ .mod = o.module }); |
| 1479 | | return payload_di_ty; |
| 1474 | switch (ty.errorUnionSet().errorSetCardinality()) { |
| 1475 | .zero => { |
| 1476 | const payload_di_ty = try o.lowerDebugType(payload_ty, .full); |
| 1477 | // The recursive call to `lowerDebugType` means we can't use `gop` anymore. |
| 1478 | try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(payload_di_ty), .{ .mod = o.module }); |
| 1479 | return payload_di_ty; |
| 1480 | }, |
| 1481 | .one => { |
| 1482 | if (payload_ty.isNoReturn()) { |
| 1483 | const di_type = dib.createBasicType("void", 0, DW.ATE.signed); |
| 1484 | gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type); |
| 1485 | return di_type; |
| 1486 | } |
| 1487 | }, |
| 1488 | .many => {}, |
| 1480 | 1489 | } |
| 1481 | 1490 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 1482 | | const err_set_di_ty = try o.lowerDebugType(err_set_ty, .full); |
| 1491 | const err_set_di_ty = try o.lowerDebugType(Type.anyerror, .full); |
| 1483 | 1492 | // The recursive call to `lowerDebugType` means we can't use `gop` anymore. |
| 1484 | 1493 | try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(err_set_di_ty), .{ .mod = o.module }); |
| 1485 | 1494 | return err_set_di_ty; |
| ... | ... | @@ -1502,56 +1511,51 @@ pub const Object = struct { |
| 1502 | 1511 | break :blk fwd_decl; |
| 1503 | 1512 | }; |
| 1504 | 1513 | |
| 1505 | | const err_set_size = err_set_ty.abiSize(target); |
| 1506 | | const err_set_align = err_set_ty.abiAlignment(target); |
| 1514 | const error_size = Type.anyerror.abiSize(target); |
| 1515 | const error_align = Type.anyerror.abiAlignment(target); |
| 1507 | 1516 | const payload_size = payload_ty.abiSize(target); |
| 1508 | 1517 | const payload_align = payload_ty.abiAlignment(target); |
| 1509 | 1518 | |
| 1510 | | var offset: u64 = 0; |
| 1511 | | offset += err_set_size; |
| 1512 | | offset = std.mem.alignForwardGeneric(u64, offset, payload_align); |
| 1513 | | const payload_offset = offset; |
| 1514 | | |
| 1515 | | var len: u8 = 2; |
| 1516 | | var fields: [3]*llvm.DIType = .{ |
| 1517 | | dib.createMemberType( |
| 1518 | | fwd_decl.toScope(), |
| 1519 | | "tag", |
| 1520 | | di_file, |
| 1521 | | line, |
| 1522 | | err_set_size * 8, // size in bits |
| 1523 | | err_set_align * 8, // align in bits |
| 1524 | | 0, // offset in bits |
| 1525 | | 0, // flags |
| 1526 | | try o.lowerDebugType(err_set_ty, .full), |
| 1527 | | ), |
| 1528 | | dib.createMemberType( |
| 1529 | | fwd_decl.toScope(), |
| 1530 | | "value", |
| 1531 | | di_file, |
| 1532 | | line, |
| 1533 | | payload_size * 8, // size in bits |
| 1534 | | payload_align * 8, // align in bits |
| 1535 | | payload_offset * 8, // offset in bits |
| 1536 | | 0, // flags |
| 1537 | | try o.lowerDebugType(payload_ty, .full), |
| 1538 | | ), |
| 1539 | | undefined, |
| 1540 | | }; |
| 1541 | | |
| 1542 | | const error_size = Type.anyerror.abiSize(target); |
| 1543 | | if (payload_align > error_size) { |
| 1544 | | fields[2] = fields[1]; |
| 1545 | | const pad_len = @intCast(u32, payload_align - error_size); |
| 1546 | | fields[1] = dib.createArrayType( |
| 1547 | | pad_len * 8, |
| 1548 | | 8, |
| 1549 | | try o.lowerDebugType(Type.u8, .full), |
| 1550 | | @intCast(c_int, pad_len), |
| 1551 | | ); |
| 1552 | | len += 1; |
| 1519 | var error_index: u32 = undefined; |
| 1520 | var payload_index: u32 = undefined; |
| 1521 | var error_offset: u64 = undefined; |
| 1522 | var payload_offset: u64 = undefined; |
| 1523 | if (error_align > payload_align) { |
| 1524 | error_index = 0; |
| 1525 | payload_index = 1; |
| 1526 | error_offset = 0; |
| 1527 | payload_offset = std.mem.alignForwardGeneric(u64, error_size, payload_align); |
| 1528 | } else { |
| 1529 | payload_index = 0; |
| 1530 | error_index = 1; |
| 1531 | payload_offset = 0; |
| 1532 | error_offset = std.mem.alignForwardGeneric(u64, payload_size, error_align); |
| 1553 | 1533 | } |
| 1554 | 1534 | |
| 1535 | var fields: [2]*llvm.DIType = undefined; |
| 1536 | fields[error_index] = dib.createMemberType( |
| 1537 | fwd_decl.toScope(), |
| 1538 | "tag", |
| 1539 | di_file, |
| 1540 | line, |
| 1541 | error_size * 8, // size in bits |
| 1542 | error_align * 8, // align in bits |
| 1543 | error_offset * 8, // offset in bits |
| 1544 | 0, // flags |
| 1545 | try o.lowerDebugType(Type.anyerror, .full), |
| 1546 | ); |
| 1547 | fields[payload_index] = dib.createMemberType( |
| 1548 | fwd_decl.toScope(), |
| 1549 | "value", |
| 1550 | di_file, |
| 1551 | line, |
| 1552 | payload_size * 8, // size in bits |
| 1553 | payload_align * 8, // align in bits |
| 1554 | payload_offset * 8, // offset in bits |
| 1555 | 0, // flags |
| 1556 | try o.lowerDebugType(payload_ty, .full), |
| 1557 | ); |
| 1558 | |
| 1555 | 1559 | const full_di_ty = dib.createStructType( |
| 1556 | 1560 | compile_unit_scope, |
| 1557 | 1561 | name.ptr, |
| ... | ... | @@ -1562,7 +1566,7 @@ pub const Object = struct { |
| 1562 | 1566 | 0, // flags |
| 1563 | 1567 | null, // derived from |
| 1564 | 1568 | &fields, |
| 1565 | | len, |
| 1569 | fields.len, |
| 1566 | 1570 | 0, // run time lang |
| 1567 | 1571 | null, // vtable holder |
| 1568 | 1572 | "", // unique id |
| ... | ... | @@ -2455,18 +2459,23 @@ pub const DeclGen = struct { |
| 2455 | 2459 | return dg.context.structType(&fields, fields.len, .False); |
| 2456 | 2460 | }, |
| 2457 | 2461 | .ErrorUnion => { |
| 2458 | | const error_type = t.errorUnionSet(); |
| 2459 | | const payload_type = t.errorUnionPayload(); |
| 2460 | | if (error_type.errorSetCardinality() == .zero) { |
| 2461 | | return dg.lowerType(payload_type); |
| 2462 | const payload_ty = t.errorUnionPayload(); |
| 2463 | switch (t.errorUnionSet().errorSetCardinality()) { |
| 2464 | .zero => return dg.lowerType(payload_ty), |
| 2465 | .one => { |
| 2466 | if (payload_ty.isNoReturn()) { |
| 2467 | return dg.context.voidType(); |
| 2468 | } |
| 2469 | }, |
| 2470 | .many => {}, |
| 2462 | 2471 | } |
| 2463 | | if (!payload_type.hasRuntimeBitsIgnoreComptime()) { |
| 2472 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 2464 | 2473 | return try dg.lowerType(Type.anyerror); |
| 2465 | 2474 | } |
| 2466 | | const llvm_error_type = try dg.lowerType(error_type); |
| 2467 | | const llvm_payload_type = try dg.lowerType(payload_type); |
| 2475 | const llvm_error_type = try dg.lowerType(Type.anyerror); |
| 2476 | const llvm_payload_type = try dg.lowerType(payload_ty); |
| 2468 | 2477 | |
| 2469 | | const payload_align = payload_type.abiAlignment(target); |
| 2478 | const payload_align = payload_ty.abiAlignment(target); |
| 2470 | 2479 | const error_align = Type.anyerror.abiAlignment(target); |
| 2471 | 2480 | if (error_align > payload_align) { |
| 2472 | 2481 | const fields: [2]*const llvm.Type = .{ llvm_error_type, llvm_payload_type }; |
| ... | ... | @@ -2476,9 +2485,7 @@ pub const DeclGen = struct { |
| 2476 | 2485 | return dg.context.structType(&fields, fields.len, .False); |
| 2477 | 2486 | } |
| 2478 | 2487 | }, |
| 2479 | | .ErrorSet => { |
| 2480 | | return dg.context.intType(16); |
| 2481 | | }, |
| 2488 | .ErrorSet => return dg.context.intType(16), |
| 2482 | 2489 | .Struct => { |
| 2483 | 2490 | const gop = try dg.object.type_map.getOrPutContext(gpa, t, .{ .mod = dg.module }); |
| 2484 | 2491 | if (gop.found_existing) return gop.value_ptr.*; |
| ... | ... | @@ -3095,7 +3102,7 @@ pub const DeclGen = struct { |
| 3095 | 3102 | return dg.resolveLlvmFunction(fn_decl_index); |
| 3096 | 3103 | }, |
| 3097 | 3104 | .ErrorSet => { |
| 3098 | | const llvm_ty = try dg.lowerType(tv.ty); |
| 3105 | const llvm_ty = try dg.lowerType(Type.anyerror); |
| 3099 | 3106 | switch (tv.val.tag()) { |
| 3100 | 3107 | .@"error" => { |
| 3101 | 3108 | const err_name = tv.val.castTag(.@"error").?.data.name; |
| ... | ... | @@ -3109,9 +3116,8 @@ pub const DeclGen = struct { |
| 3109 | 3116 | } |
| 3110 | 3117 | }, |
| 3111 | 3118 | .ErrorUnion => { |
| 3112 | | const error_type = tv.ty.errorUnionSet(); |
| 3113 | 3119 | const payload_type = tv.ty.errorUnionPayload(); |
| 3114 | | if (error_type.errorSetCardinality() == .zero) { |
| 3120 | if (tv.ty.errorUnionSet().errorSetCardinality() == .zero) { |
| 3115 | 3121 | const payload_val = tv.val.castTag(.eu_payload).?.data; |
| 3116 | 3122 | return dg.lowerValue(.{ .ty = payload_type, .val = payload_val }); |
| 3117 | 3123 | } |
| ... | ... | @@ -3120,13 +3126,13 @@ pub const DeclGen = struct { |
| 3120 | 3126 | if (!payload_type.hasRuntimeBitsIgnoreComptime()) { |
| 3121 | 3127 | // We use the error type directly as the type. |
| 3122 | 3128 | const err_val = if (!is_pl) tv.val else Value.initTag(.zero); |
| 3123 | | return dg.lowerValue(.{ .ty = error_type, .val = err_val }); |
| 3129 | return dg.lowerValue(.{ .ty = Type.anyerror, .val = err_val }); |
| 3124 | 3130 | } |
| 3125 | 3131 | |
| 3126 | 3132 | const payload_align = payload_type.abiAlignment(target); |
| 3127 | 3133 | const error_align = Type.anyerror.abiAlignment(target); |
| 3128 | 3134 | const llvm_error_value = try dg.lowerValue(.{ |
| 3129 | | .ty = error_type, |
| 3135 | .ty = Type.anyerror, |
| 3130 | 3136 | .val = if (is_pl) Value.initTag(.zero) else tv.val, |
| 3131 | 3137 | }); |
| 3132 | 3138 | const llvm_payload_value = try dg.lowerValue(.{ |
| ... | ... | @@ -5656,13 +5662,12 @@ pub const FuncGen = struct { |
| 5656 | 5662 | const operand = try self.resolveInst(ty_op.operand); |
| 5657 | 5663 | const error_union_ty = self.air.typeOf(ty_op.operand).childType(); |
| 5658 | 5664 | |
| 5659 | | const error_ty = error_union_ty.errorUnionSet(); |
| 5660 | | if (error_ty.errorSetCardinality() == .zero) { |
| 5665 | if (error_union_ty.errorUnionSet().errorSetCardinality() == .zero) { |
| 5661 | 5666 | // TODO: write undefined bytes through the pointer here |
| 5662 | 5667 | return operand; |
| 5663 | 5668 | } |
| 5664 | 5669 | const payload_ty = error_union_ty.errorUnionPayload(); |
| 5665 | | const non_error_val = try self.dg.lowerValue(.{ .ty = error_ty, .val = Value.zero }); |
| 5670 | const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = Value.zero }); |
| 5666 | 5671 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 5667 | 5672 | _ = self.builder.buildStore(non_error_val, operand); |
| 5668 | 5673 | return operand; |
| ... | ... | @@ -6715,9 +6720,9 @@ pub const FuncGen = struct { |
| 6715 | 6720 | if (self.liveness.isUnused(inst)) return null; |
| 6716 | 6721 | |
| 6717 | 6722 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 6718 | | const operand = try self.resolveInst(ty_op.operand); |
| 6719 | 6723 | const operand_ty = self.air.typeOf(ty_op.operand); |
| 6720 | 6724 | const inst_ty = self.air.typeOfIndex(inst); |
| 6725 | const operand = try self.resolveInst(ty_op.operand); |
| 6721 | 6726 | const operand_is_ref = isByRef(operand_ty); |
| 6722 | 6727 | const result_is_ref = isByRef(inst_ty); |
| 6723 | 6728 | const llvm_dest_ty = try self.dg.lowerType(inst_ty); |