From 01a39fa1d4d0d2e3305af8e6d6af1079f020db7f Mon Sep 17 00:00:00 2001 From: jacob gw Date: Tue, 6 Apr 2021 22:38:25 -0400 Subject: [PATCH] stage2: coerce enum_literal -> enum --- src/Sema.zig | 54 ++++++++++++++++++++++++++++++++++++++++++++ test/stage2/test.zig | 41 ++++++++++++++++++++++++++++++++- 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/src/Sema.zig b/src/Sema.zig index 115ca11858..0cd9837c3a 100644 --- a/src/Sema.zig +++ b/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 => {}, } diff --git a/test/stage2/test.zig b/test/stage2/test.zig index 4ef172e65d..2d3a445ca1 100644 --- a/test/stage2/test.zig +++ b/test/stage2/test.zig @@ -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'"}); + } }