Commit 01a39fa1d4

jacob gw <jacoblevgw@gmail.com>
2021-04-07 04:38:25
stage2: coerce enum_literal -> enum
1 parent 19cf987
Changed files (2)
src
test
stage2
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 => {},
     }
 
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'"});
+    }
 }