| author | |
| committer | |
| log | 01a39fa1d4d0d2e3305af8e6d6af1079f020db7f |
| tree | f508a38bac37686def18c367c6b3d54c43845297 |
| parent | 19cf987198ff4de0b1460263a62ff6c41e1e3915 |
2 files changed, 94 insertions(+), 1 deletions(-)
src/Sema.zig+54| ... | @@ -4702,6 +4702,60 @@ fn coerce( | ... | @@ -4702,6 +4702,60 @@ fn coerce( |
| 4702 | } | 4702 | } |
| 4703 | } | 4703 | } |
| 4704 | }, | 4704 | }, |
| 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 | }, | ||
| 4705 | else => {}, | 4759 | else => {}, |
| 4706 | } | 4760 | } |
| 4707 | 4761 |
test/stage2/test.zig+40-1| ... | @@ -1022,7 +1022,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -1022,7 +1022,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 1022 | "Hello, World!\n", | 1022 | "Hello, World!\n", |
| 1023 | ); | 1023 | ); |
| 1024 | try case.files.append(.{ | 1024 | try case.files.append(.{ |
| 1025 | .src = | 1025 | .src = |
| 1026 | \\pub fn print() void { | 1026 | \\pub fn print() void { |
| 1027 | \\ asm volatile ("syscall" | 1027 | \\ asm volatile ("syscall" |
| 1028 | \\ : | 1028 | \\ : |
| ... | @@ -1598,4 +1598,43 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -1598,4 +1598,43 @@ pub fn addCases(ctx: *TestContext) !void { |
| 1598 | "", | 1598 | "", |
| 1599 | ); | 1599 | ); |
| 1600 | } | 1600 | } |
| 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 | } | ||
| 1601 | } | 1640 | } |