| author | |
| committer | |
| log | 67b201982bb1a0b4650b7ff222ef22875c32c810 |
| tree | 76fb74ec68c16955073552e437fc413fdb68b7f1 |
| parent | 7b78b4fff02e5f59da3034ee739c0eae99a01de5 |
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 #94983 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 | 11380 | } |
| 11381 | 11381 | break; |
| 11382 | 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 | 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 | 11388 | add_error_note(ira->codegen, msg, target->value->type->data.enumeration.decl_node, buf_sprintf("declared here")); |
| 11387 | 11389 | } else { |
| 11388 | 11390 | want_var_export = true; |
| ... | ... | @@ -11425,9 +11427,11 @@ static Stage1AirInst *ir_analyze_instruction_export(IrAnalyze *ira, Stage1ZirIns |
| 11425 | 11427 | } |
| 11426 | 11428 | break; |
| 11427 | 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 | 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 | 11435 | add_error_note(ira->codegen, msg, type_value->data.enumeration.decl_node, buf_sprintf("declared here")); |
| 11432 | 11436 | } |
| 11433 | 11437 | break; |
test/behavior/enum_stage1.zig+14| ... | ... | @@ -423,3 +423,17 @@ test "method call on an enum" { |
| 423 | 423 | try S.doTheTest(); |
| 424 | 424 | comptime try S.doTheTest(); |
| 425 | 425 | } |
| 426 | ||
| 427 | test "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 | 23 | }); |
| 24 | 24 | } |
| 25 | 25 | |
| 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 | 40 | ctx.objErrStage1("issue #9346: return outside of function scope", |
| 27 | 41 | \\pub const empty = return 1; |
| 28 | 42 | , &.{"tmp.zig:1:19: error: 'return' outside function scope"}); |