From 67b201982bb1a0b4650b7ff222ef22875c32c810 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 25 Nov 2021 18:20:39 -0700 Subject: [PATCH] stage1: fix exporting enums After extern enums were removed, stage1 was left in an incorrect state of checking for `extern enum` for exported enums. This commit fixes it to look for an explicit integer tag type instead, and adds test coverage for the compile error case as well as the success case. closes #9498 --- src/stage1/ir.cpp | 12 ++++++++---- test/behavior/enum_stage1.zig | 14 ++++++++++++++ test/compile_errors.zig | 14 ++++++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index 9a3b938dbd5477ef853f102593fc7ffc201f08d6..0684b7bce17447b2ecfc05343ff4418fc5af3b0a 100644 --- a/src/stage1/ir.cpp +++ b/src/stage1/ir.cpp @@ -11380,9 +11380,11 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns } break; case ZigTypeIdEnum: - if (target->value->type->data.enumeration.layout != ContainerLayoutExtern) { + if ((err = type_resolve(ira->codegen, target->value->type, ResolveStatusZeroBitsKnown))) + return ira->codegen->invalid_inst_gen; + if (!target->value->type->data.enumeration.has_explicit_tag_type) { ErrorMsg *msg = ir_add_error(ira, target, - buf_sprintf("exported enum value must be declared extern")); + buf_sprintf("exported enum value without explicit integer tag type")); add_error_note(ira->codegen, msg, target->value->type->data.enumeration.decl_node, buf_sprintf("declared here")); } else { want_var_export = true; @@ -11425,9 +11427,11 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns } break; case ZigTypeIdEnum: - if (type_value->data.enumeration.layout != ContainerLayoutExtern) { + if ((err = type_resolve(ira->codegen, type_value, ResolveStatusZeroBitsKnown))) + return ira->codegen->invalid_inst_gen; + if (!type_value->data.enumeration.has_explicit_tag_type) { ErrorMsg *msg = ir_add_error(ira, target, - buf_sprintf("exported enum must be declared extern")); + buf_sprintf("exported enum without explicit integer tag type")); add_error_note(ira->codegen, msg, type_value->data.enumeration.decl_node, buf_sprintf("declared here")); } break; diff --git a/test/behavior/enum_stage1.zig b/test/behavior/enum_stage1.zig index fbc73215ba549eefa09db3eaca604d2e87e63a54..57f5eed6a2528d5cc69c0cf2c4cc21ccc52a977e 100644 --- a/test/behavior/enum_stage1.zig +++ b/test/behavior/enum_stage1.zig @@ -423,3 +423,17 @@ test "method call on an enum" { try S.doTheTest(); comptime try S.doTheTest(); } + +test "exporting enum type and value" { + const S = struct { + const E = enum(c_int) { one, two }; + comptime { + @export(E, .{ .name = "E" }); + } + const e: E = .two; + comptime { + @export(e, .{ .name = "e" }); + } + }; + try expect(S.e == .two); +} diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 21bdbfbcfb9ab8f80402aa4eb5953274e445866d..d717125fb266c9ca2ccb29ecbf158b923f826614 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -23,6 +23,20 @@ pub fn addCases(ctx: *TestContext) !void { }); } + ctx.objErrStage1("exported enum without explicit integer tag type", + \\const E = enum { one, two }; + \\comptime { + \\ @export(E, .{ .name = "E" }); + \\} + \\const e: E = .two; + \\comptime { + \\ @export(e, .{ .name = "e" }); + \\} + , &.{ + "tmp.zig:3:13: error: exported enum without explicit integer tag type", + "tmp.zig:7:13: error: exported enum value without explicit integer tag type", + }); + ctx.objErrStage1("issue #9346: return outside of function scope", \\pub const empty = return 1; , &.{"tmp.zig:1:19: error: 'return' outside function scope"}); -- 2.54.0