mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 05:20:34 +00:00
Sema: perform requested coercion when decl literal demoted to enum literal
Resolves: #21392
This commit is contained in:
parent
03c363300f
commit
55250a9370
39
src/Sema.zig
39
src/Sema.zig
@ -8980,36 +8980,41 @@ fn zirDeclLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index, do_coerce: b
|
||||
sema.code.nullTerminatedString(extra.field_name_start),
|
||||
.no_embedded_nulls,
|
||||
);
|
||||
|
||||
const orig_ty = sema.resolveType(block, src, extra.lhs) catch |err| switch (err) {
|
||||
error.GenericPoison => {
|
||||
// Treat this as a normal enum literal.
|
||||
return Air.internedToRef(try pt.intern(.{ .enum_literal = name }));
|
||||
},
|
||||
error.GenericPoison => Type.generic_poison,
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
var ty = orig_ty;
|
||||
while (true) switch (ty.zigTypeTag(zcu)) {
|
||||
.error_union => ty = ty.errorUnionPayload(zcu),
|
||||
.optional => ty = ty.optionalChild(zcu),
|
||||
.enum_literal, .error_set => {
|
||||
const uncoerced_result = res: {
|
||||
if (orig_ty.toIntern() == .generic_poison_type) {
|
||||
// Treat this as a normal enum literal.
|
||||
return Air.internedToRef(try pt.intern(.{ .enum_literal = name }));
|
||||
},
|
||||
else => break,
|
||||
break :res Air.internedToRef(try pt.intern(.{ .enum_literal = name }));
|
||||
}
|
||||
|
||||
var ty = orig_ty;
|
||||
while (true) switch (ty.zigTypeTag(zcu)) {
|
||||
.error_union => ty = ty.errorUnionPayload(zcu),
|
||||
.optional => ty = ty.optionalChild(zcu),
|
||||
.enum_literal, .error_set => {
|
||||
// Treat this as a normal enum literal.
|
||||
break :res Air.internedToRef(try pt.intern(.{ .enum_literal = name }));
|
||||
},
|
||||
else => break,
|
||||
};
|
||||
|
||||
break :res try sema.fieldVal(block, src, Air.internedToRef(ty.toIntern()), name, src);
|
||||
};
|
||||
|
||||
const result = try sema.fieldVal(block, src, Air.internedToRef(ty.toIntern()), name, src);
|
||||
|
||||
// Decl literals cannot lookup runtime `var`s.
|
||||
if (!try sema.isComptimeKnown(result)) {
|
||||
if (!try sema.isComptimeKnown(uncoerced_result)) {
|
||||
return sema.fail(block, src, "decl literal must be comptime-known", .{});
|
||||
}
|
||||
|
||||
if (do_coerce) {
|
||||
return sema.coerce(block, orig_ty, result, src);
|
||||
return sema.coerce(block, orig_ty, uncoerced_result, src);
|
||||
} else {
|
||||
return result;
|
||||
return uncoerced_result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
9
test/cases/compile_errors/error_set_decl_literal.zig
Normal file
9
test/cases/compile_errors/error_set_decl_literal.zig
Normal file
@ -0,0 +1,9 @@
|
||||
export fn entry() void {
|
||||
const E = error{Foo};
|
||||
const e: E = .Foo;
|
||||
_ = e;
|
||||
}
|
||||
|
||||
// error
|
||||
//
|
||||
// :3:19: error: expected type 'error{Foo}', found '@TypeOf(.enum_literal)'
|
||||
Loading…
x
Reference in New Issue
Block a user