mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-07 23:04:34 +01:00
Sema: fix nested error union coercions
Previously, `E1!void` failed to coerce to `E2!E1!void` because it tried to coerce the `E1` error to an `E2` if comptime-known and refused to attempt any other coercion. This is a strange language rule with no clear justification, and breaks real use cases (such as calling `getOne` on an `Io.Queue(E!T)`). Instead, only error *sets* should try to coerce to an "error" value of an error union type.
This commit is contained in:
parent
3f08073f7d
commit
5611779f39
1 changed files with 0 additions and 27 deletions
27
src/Sema.zig
27
src/Sema.zig
|
|
@ -29023,33 +29023,6 @@ fn coerceExtra(
|
|||
else => {},
|
||||
},
|
||||
.error_union => switch (inst_ty.zigTypeTag(zcu)) {
|
||||
.error_union => eu: {
|
||||
if (maybe_inst_val) |inst_val| {
|
||||
switch (inst_val.toIntern()) {
|
||||
.undef => return pt.undefRef(dest_ty),
|
||||
else => switch (zcu.intern_pool.indexToKey(inst_val.toIntern())) {
|
||||
.error_union => |error_union| switch (error_union.val) {
|
||||
.err_name => |err_name| {
|
||||
const error_set_ty = inst_ty.errorUnionSet(zcu);
|
||||
const error_set_val = Air.internedToRef((try pt.intern(.{ .err = .{
|
||||
.ty = error_set_ty.toIntern(),
|
||||
.name = err_name,
|
||||
} })));
|
||||
return sema.wrapErrorUnionSet(block, dest_ty, error_set_val, inst_src);
|
||||
},
|
||||
.payload => |payload| {
|
||||
const payload_val = Air.internedToRef(payload);
|
||||
return sema.wrapErrorUnionPayload(block, dest_ty, payload_val, inst_src) catch |err| switch (err) {
|
||||
error.NotCoercible => break :eu,
|
||||
else => |e| return e,
|
||||
};
|
||||
},
|
||||
},
|
||||
else => unreachable,
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
.error_set => {
|
||||
// E to E!T
|
||||
return sema.wrapErrorUnionSet(block, dest_ty, inst, inst_src);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue