mirror of
https://github.com/ziglang/zig.git
synced 2026-01-10 01:15:14 +00:00
stage2: coerce enum_literal -> enum
This commit is contained in:
parent
19cf987198
commit
01a39fa1d4
54
src/Sema.zig
54
src/Sema.zig
@ -4702,6 +4702,60 @@ fn coerce(
|
||||
}
|
||||
}
|
||||
},
|
||||
.Enum => {
|
||||
if (inst.ty.zigTypeTag() == .EnumLiteral) {
|
||||
const val = (try sema.resolveDefinedValue(block, inst_src, inst)).?;
|
||||
const bytes = val.castTag(.enum_literal).?.data;
|
||||
switch (dest_type.tag()) {
|
||||
.enum_full => {
|
||||
const enumeration = dest_type.castTag(.enum_full).?.data;
|
||||
const enum_fields = enumeration.fields;
|
||||
const i = enum_fields.getIndex(bytes) orelse return sema.mod.fail(
|
||||
&block.base,
|
||||
inst_src,
|
||||
"enum '{s}' has no field named '{s}'",
|
||||
.{ enumeration.owner_decl.name, bytes },
|
||||
);
|
||||
const val_pl = try Value.Tag.enum_field_index.create(sema.arena, @intCast(u32, i));
|
||||
return sema.mod.constInst(sema.arena, inst_src, .{
|
||||
.ty = dest_type,
|
||||
.val = val_pl,
|
||||
});
|
||||
},
|
||||
.enum_simple => {
|
||||
const enumeration = dest_type.castTag(.enum_simple).?.data;
|
||||
const enum_fields = enumeration.fields;
|
||||
const i = enum_fields.getIndex(bytes) orelse return sema.mod.fail(
|
||||
&block.base,
|
||||
inst_src,
|
||||
"enum '{s}' has no field named '{s}'",
|
||||
.{ enumeration.owner_decl.name, bytes },
|
||||
);
|
||||
const val_pl = try Value.Tag.enum_field_index.create(sema.arena, @intCast(u32, i));
|
||||
return sema.mod.constInst(sema.arena, inst_src, .{
|
||||
.ty = dest_type,
|
||||
.val = val_pl,
|
||||
});
|
||||
},
|
||||
.enum_nonexhaustive => {
|
||||
const enumeration = dest_type.castTag(.enum_nonexhaustive).?.data;
|
||||
const enum_fields = enumeration.fields;
|
||||
const i = enum_fields.getIndex(bytes) orelse return sema.mod.fail(
|
||||
&block.base,
|
||||
inst_src,
|
||||
"enum '{s}' has no field named '{s}'",
|
||||
.{ enumeration.owner_decl.name, bytes },
|
||||
);
|
||||
const val_pl = try Value.Tag.enum_field_index.create(sema.arena, @intCast(u32, i));
|
||||
return sema.mod.constInst(sema.arena, inst_src, .{
|
||||
.ty = dest_type,
|
||||
.val = val_pl,
|
||||
});
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
|
||||
@ -1022,7 +1022,7 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
"Hello, World!\n",
|
||||
);
|
||||
try case.files.append(.{
|
||||
.src =
|
||||
.src =
|
||||
\\pub fn print() void {
|
||||
\\ asm volatile ("syscall"
|
||||
\\ :
|
||||
@ -1598,4 +1598,43 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
"",
|
||||
);
|
||||
}
|
||||
{
|
||||
var case = ctx.exe("enum_literal -> enum", linux_x64);
|
||||
|
||||
case.addCompareOutput(
|
||||
\\const E = enum { a, b };
|
||||
\\export fn _start() noreturn {
|
||||
\\ const a: E = .a;
|
||||
\\ const b: E = .b;
|
||||
\\ exit();
|
||||
\\}
|
||||
\\fn exit() noreturn {
|
||||
\\ asm volatile ("syscall"
|
||||
\\ :
|
||||
\\ : [number] "{rax}" (231),
|
||||
\\ [arg1] "{rdi}" (0)
|
||||
\\ : "rcx", "r11", "memory"
|
||||
\\ );
|
||||
\\ unreachable;
|
||||
\\}
|
||||
,
|
||||
"",
|
||||
);
|
||||
case.addError(
|
||||
\\const E = enum { a, b };
|
||||
\\export fn _start() noreturn {
|
||||
\\ const a: E = .c;
|
||||
\\ exit();
|
||||
\\}
|
||||
\\fn exit() noreturn {
|
||||
\\ asm volatile ("syscall"
|
||||
\\ :
|
||||
\\ : [number] "{rax}" (231),
|
||||
\\ [arg1] "{rdi}" (0)
|
||||
\\ : "rcx", "r11", "memory"
|
||||
\\ );
|
||||
\\ unreachable;
|
||||
\\}
|
||||
, &.{":3:19: error: enum 'E' has no field named 'c'"});
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user