mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
codegen: lower error_set and error_union
This commit is contained in:
parent
358b544157
commit
f4f23e307c
@ -3509,6 +3509,7 @@ fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
|
||||
return self.fail("TODO isErr for errors with size larger than register size", .{});
|
||||
}
|
||||
} else {
|
||||
log.warn("operand = {}, payload_type = {}", .{ operand, payload_type });
|
||||
return self.fail("TODO isErr for non-empty payloads", .{});
|
||||
}
|
||||
}
|
||||
@ -5108,22 +5109,18 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
|
||||
const error_type = typed_value.ty.errorUnionSet();
|
||||
const payload_type = typed_value.ty.errorUnionPayload();
|
||||
|
||||
if (typed_value.val.castTag(.eu_payload)) |pl| {
|
||||
if (typed_value.val.castTag(.eu_payload)) |_| {
|
||||
if (!payload_type.hasRuntimeBits()) {
|
||||
// We use the error type directly as the type.
|
||||
return MCValue{ .immediate = 0 };
|
||||
}
|
||||
|
||||
_ = pl;
|
||||
return self.fail("TODO implement error union const of type '{}' (non-error)", .{typed_value.ty});
|
||||
} else {
|
||||
if (!payload_type.hasRuntimeBits()) {
|
||||
// We use the error type directly as the type.
|
||||
return self.genTypedValue(.{ .ty = error_type, .val = typed_value.val });
|
||||
}
|
||||
}
|
||||
|
||||
return self.fail("TODO implement error union const of type '{}' (error)", .{typed_value.ty});
|
||||
return self.lowerUnnamedConst(typed_value);
|
||||
},
|
||||
.Struct => {
|
||||
return self.lowerUnnamedConst(typed_value);
|
||||
|
||||
@ -432,6 +432,54 @@ pub fn generateSymbol(
|
||||
|
||||
return Result{ .appended = {} };
|
||||
},
|
||||
.ErrorUnion => {
|
||||
const error_ty = typed_value.ty.errorUnionSet();
|
||||
const payload_ty = typed_value.ty.errorUnionPayload();
|
||||
const is_payload = typed_value.val.errorUnionIsPayload();
|
||||
|
||||
const error_val = if (!is_payload) typed_value.val else Value.initTag(.zero);
|
||||
switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
|
||||
.ty = error_ty,
|
||||
.val = error_val,
|
||||
}, code, debug_output)) {
|
||||
.appended => {},
|
||||
.externally_managed => |external_slice| {
|
||||
code.appendSliceAssumeCapacity(external_slice);
|
||||
},
|
||||
.fail => |em| return Result{ .fail = em },
|
||||
}
|
||||
|
||||
if (payload_ty.hasRuntimeBits()) {
|
||||
const payload_val = if (typed_value.val.castTag(.eu_payload)) |val| val.data else Value.initTag(.undef);
|
||||
switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
|
||||
.ty = payload_ty,
|
||||
.val = payload_val,
|
||||
}, code, debug_output)) {
|
||||
.appended => {},
|
||||
.externally_managed => |external_slice| {
|
||||
code.appendSliceAssumeCapacity(external_slice);
|
||||
},
|
||||
.fail => |em| return Result{ .fail = em },
|
||||
}
|
||||
}
|
||||
|
||||
return Result{ .appended = {} };
|
||||
},
|
||||
.ErrorSet => {
|
||||
const target = bin_file.options.target;
|
||||
switch (typed_value.val.tag()) {
|
||||
.@"error" => {
|
||||
const name = typed_value.val.getError().?;
|
||||
const kv = try bin_file.options.module.?.getErrorValue(name);
|
||||
const endian = target.cpu.arch.endian();
|
||||
try code.writer().writeInt(u32, kv.value, endian);
|
||||
},
|
||||
else => {
|
||||
try code.writer().writeByteNTimes(0, @intCast(usize, typed_value.ty.abiSize(target)));
|
||||
},
|
||||
}
|
||||
return Result{ .appended = {} };
|
||||
},
|
||||
else => |t| {
|
||||
return Result{
|
||||
.fail = try ErrorMsg.create(
|
||||
|
||||
@ -3127,6 +3127,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl: *Module.Decl
|
||||
.fail => |em| {
|
||||
decl.analysis = .codegen_failure;
|
||||
try module.failed_decls.put(module.gpa, decl, em);
|
||||
log.err("{s}", .{em.msg});
|
||||
return error.AnalysisFail;
|
||||
},
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user