authorgravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2021-04-06 22:38:25-04:00
committergravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2021-04-07 07:19:11-04:00
log01a39fa1d4d0d2e3305af8e6d6af1079f020db7f
treef508a38bac37686def18c367c6b3d54c43845297
parent19cf987198ff4de0b1460263a62ff6c41e1e3915

stage2: coerce enum_literal -> enum


2 files changed, 94 insertions(+), 1 deletions(-)

src/Sema.zig+54
......@@ -4702,6 +4702,60 @@ fn coerce(
47024702 }
47034703 }
47044704 },
4705 .Enum => {
4706 if (inst.ty.zigTypeTag() == .EnumLiteral) {
4707 const val = (try sema.resolveDefinedValue(block, inst_src, inst)).?;
4708 const bytes = val.castTag(.enum_literal).?.data;
4709 switch (dest_type.tag()) {
4710 .enum_full => {
4711 const enumeration = dest_type.castTag(.enum_full).?.data;
4712 const enum_fields = enumeration.fields;
4713 const i = enum_fields.getIndex(bytes) orelse return sema.mod.fail(
4714 &block.base,
4715 inst_src,
4716 "enum '{s}' has no field named '{s}'",
4717 .{ enumeration.owner_decl.name, bytes },
4718 );
4719 const val_pl = try Value.Tag.enum_field_index.create(sema.arena, @intCast(u32, i));
4720 return sema.mod.constInst(sema.arena, inst_src, .{
4721 .ty = dest_type,
4722 .val = val_pl,
4723 });
4724 },
4725 .enum_simple => {
4726 const enumeration = dest_type.castTag(.enum_simple).?.data;
4727 const enum_fields = enumeration.fields;
4728 const i = enum_fields.getIndex(bytes) orelse return sema.mod.fail(
4729 &block.base,
4730 inst_src,
4731 "enum '{s}' has no field named '{s}'",
4732 .{ enumeration.owner_decl.name, bytes },
4733 );
4734 const val_pl = try Value.Tag.enum_field_index.create(sema.arena, @intCast(u32, i));
4735 return sema.mod.constInst(sema.arena, inst_src, .{
4736 .ty = dest_type,
4737 .val = val_pl,
4738 });
4739 },
4740 .enum_nonexhaustive => {
4741 const enumeration = dest_type.castTag(.enum_nonexhaustive).?.data;
4742 const enum_fields = enumeration.fields;
4743 const i = enum_fields.getIndex(bytes) orelse return sema.mod.fail(
4744 &block.base,
4745 inst_src,
4746 "enum '{s}' has no field named '{s}'",
4747 .{ enumeration.owner_decl.name, bytes },
4748 );
4749 const val_pl = try Value.Tag.enum_field_index.create(sema.arena, @intCast(u32, i));
4750 return sema.mod.constInst(sema.arena, inst_src, .{
4751 .ty = dest_type,
4752 .val = val_pl,
4753 });
4754 },
4755 else => unreachable,
4756 }
4757 }
4758 },
47054759 else => {},
47064760 }
47074761
test/stage2/test.zig+40-1
......@@ -1022,7 +1022,7 @@ pub fn addCases(ctx: *TestContext) !void {
10221022 "Hello, World!\n",
10231023 );
10241024 try case.files.append(.{
1025 .src =
1025 .src =
10261026 \\pub fn print() void {
10271027 \\ asm volatile ("syscall"
10281028 \\ :
......@@ -1598,4 +1598,43 @@ pub fn addCases(ctx: *TestContext) !void {
15981598 "",
15991599 );
16001600 }
1601 {
1602 var case = ctx.exe("enum_literal -> enum", linux_x64);
1603
1604 case.addCompareOutput(
1605 \\const E = enum { a, b };
1606 \\export fn _start() noreturn {
1607 \\ const a: E = .a;
1608 \\ const b: E = .b;
1609 \\ exit();
1610 \\}
1611 \\fn exit() noreturn {
1612 \\ asm volatile ("syscall"
1613 \\ :
1614 \\ : [number] "{rax}" (231),
1615 \\ [arg1] "{rdi}" (0)
1616 \\ : "rcx", "r11", "memory"
1617 \\ );
1618 \\ unreachable;
1619 \\}
1620 ,
1621 "",
1622 );
1623 case.addError(
1624 \\const E = enum { a, b };
1625 \\export fn _start() noreturn {
1626 \\ const a: E = .c;
1627 \\ exit();
1628 \\}
1629 \\fn exit() noreturn {
1630 \\ asm volatile ("syscall"
1631 \\ :
1632 \\ : [number] "{rax}" (231),
1633 \\ [arg1] "{rdi}" (0)
1634 \\ : "rcx", "r11", "memory"
1635 \\ );
1636 \\ unreachable;
1637 \\}
1638 , &.{":3:19: error: enum 'E' has no field named 'c'"});
1639 }
16011640}