authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-11-25 18:20:39-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-11-25 18:20:39-07:00
log67b201982bb1a0b4650b7ff222ef22875c32c810
tree76fb74ec68c16955073552e437fc413fdb68b7f1
parent7b78b4fff02e5f59da3034ee739c0eae99a01de5

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

3 files changed, 36 insertions(+), 4 deletions(-)

src/stage1/ir.cpp+8-4
......@@ -11380,9 +11380,11 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns
1138011380 }
1138111381 break;
1138211382 case ZigTypeIdEnum:
11383 if (target->value->type->data.enumeration.layout != ContainerLayoutExtern) {
11383 if ((err = type_resolve(ira->codegen, target->value->type, ResolveStatusZeroBitsKnown)))
11384 return ira->codegen->invalid_inst_gen;
11385 if (!target->value->type->data.enumeration.has_explicit_tag_type) {
1138411386 ErrorMsg *msg = ir_add_error(ira, target,
11385 buf_sprintf("exported enum value must be declared extern"));
11387 buf_sprintf("exported enum value without explicit integer tag type"));
1138611388 add_error_note(ira->codegen, msg, target->value->type->data.enumeration.decl_node, buf_sprintf("declared here"));
1138711389 } else {
1138811390 want_var_export = true;
......@@ -11425,9 +11427,11 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns
1142511427 }
1142611428 break;
1142711429 case ZigTypeIdEnum:
11428 if (type_value->data.enumeration.layout != ContainerLayoutExtern) {
11430 if ((err = type_resolve(ira->codegen, type_value, ResolveStatusZeroBitsKnown)))
11431 return ira->codegen->invalid_inst_gen;
11432 if (!type_value->data.enumeration.has_explicit_tag_type) {
1142911433 ErrorMsg *msg = ir_add_error(ira, target,
11430 buf_sprintf("exported enum must be declared extern"));
11434 buf_sprintf("exported enum without explicit integer tag type"));
1143111435 add_error_note(ira->codegen, msg, type_value->data.enumeration.decl_node, buf_sprintf("declared here"));
1143211436 }
1143311437 break;
test/behavior/enum_stage1.zig+14
......@@ -423,3 +423,17 @@ test "method call on an enum" {
423423 try S.doTheTest();
424424 comptime try S.doTheTest();
425425}
426
427test "exporting enum type and value" {
428 const S = struct {
429 const E = enum(c_int) { one, two };
430 comptime {
431 @export(E, .{ .name = "E" });
432 }
433 const e: E = .two;
434 comptime {
435 @export(e, .{ .name = "e" });
436 }
437 };
438 try expect(S.e == .two);
439}
test/compile_errors.zig+14
......@@ -23,6 +23,20 @@ pub fn addCases(ctx: *TestContext) !void {
2323 });
2424 }
2525
26 ctx.objErrStage1("exported enum without explicit integer tag type",
27 \\const E = enum { one, two };
28 \\comptime {
29 \\ @export(E, .{ .name = "E" });
30 \\}
31 \\const e: E = .two;
32 \\comptime {
33 \\ @export(e, .{ .name = "e" });
34 \\}
35 , &.{
36 "tmp.zig:3:13: error: exported enum without explicit integer tag type",
37 "tmp.zig:7:13: error: exported enum value without explicit integer tag type",
38 });
39
2640 ctx.objErrStage1("issue #9346: return outside of function scope",
2741 \\pub const empty = return 1;
2842 , &.{"tmp.zig:1:19: error: 'return' outside function scope"});