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...@@ -11380,9 +11380,11 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns
11380 }11380 }
11381 break;11381 break;
11382 case ZigTypeIdEnum:11382 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) {
11384 ErrorMsg *msg = ir_add_error(ira, target,11386 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"));
11386 add_error_note(ira->codegen, msg, target->value->type->data.enumeration.decl_node, buf_sprintf("declared here"));11388 add_error_note(ira->codegen, msg, target->value->type->data.enumeration.decl_node, buf_sprintf("declared here"));
11387 } else {11389 } else {
11388 want_var_export = true;11390 want_var_export = true;
...@@ -11425,9 +11427,11 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns...@@ -11425,9 +11427,11 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns
11425 }11427 }
11426 break;11428 break;
11427 case ZigTypeIdEnum:11429 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) {
11429 ErrorMsg *msg = ir_add_error(ira, target,11433 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"));
11431 add_error_note(ira->codegen, msg, type_value->data.enumeration.decl_node, buf_sprintf("declared here"));11435 add_error_note(ira->codegen, msg, type_value->data.enumeration.decl_node, buf_sprintf("declared here"));
11432 }11436 }
11433 break;11437 break;
test/behavior/enum_stage1.zig+14
...@@ -423,3 +423,17 @@ test "method call on an enum" {...@@ -423,3 +423,17 @@ test "method call on an enum" {
423 try S.doTheTest();423 try S.doTheTest();
424 comptime try S.doTheTest();424 comptime try S.doTheTest();
425}425}
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 {...@@ -23,6 +23,20 @@ pub fn addCases(ctx: *TestContext) !void {
23 });23 });
24 }24 }
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
26 ctx.objErrStage1("issue #9346: return outside of function scope",40 ctx.objErrStage1("issue #9346: return outside of function scope",
27 \\pub const empty = return 1;41 \\pub const empty = return 1;
28 , &.{"tmp.zig:1:19: error: 'return' outside function scope"});42 , &.{"tmp.zig:1:19: error: 'return' outside function scope"});