| author | |
| committer | |
| log | f42725c39bbbe5db13c1a1706db3f31aa0549307 |
| tree | 08284761e667668a852e512a4a5ab193ded5288c |
| parent | d1fd864da7859989828feb8be806634606cc761c |
| parent | ea45062d8227f9f9f1356c78eac5a0daa578f97e |
| signature |
stage2: astgen unionDecl fixes4 files changed, 60 insertions(+), 4 deletions(-)
src/AstGen.zig+22-3| ... | @@ -4134,7 +4134,7 @@ fn unionDeclInner( | ... | @@ -4134,7 +4134,7 @@ fn unionDeclInner( |
| 4134 | if (member.comptime_token) |comptime_token| { | 4134 | if (member.comptime_token) |comptime_token| { |
| 4135 | return astgen.failTok(comptime_token, "union fields cannot be marked comptime", .{}); | 4135 | return astgen.failTok(comptime_token, "union fields cannot be marked comptime", .{}); |
| 4136 | } | 4136 | } |
| 4137 | try fields_data.ensureUnusedCapacity(gpa, if (node_tags[member.ast.type_expr] != .@"anytype") 4 else 3); | 4137 | try fields_data.ensureUnusedCapacity(gpa, 4); |
| 4138 | 4138 | ||
| 4139 | const field_name = try astgen.identAsString(member.ast.name_token); | 4139 | const field_name = try astgen.identAsString(member.ast.name_token); |
| 4140 | fields_data.appendAssumeCapacity(field_name); | 4140 | fields_data.appendAssumeCapacity(field_name); |
| ... | @@ -4149,9 +4149,14 @@ fn unionDeclInner( | ... | @@ -4149,9 +4149,14 @@ fn unionDeclInner( |
| 4149 | (@as(u32, @boolToInt(have_value)) << 30) | | 4149 | (@as(u32, @boolToInt(have_value)) << 30) | |
| 4150 | (@as(u32, @boolToInt(unused)) << 31); | 4150 | (@as(u32, @boolToInt(unused)) << 31); |
| 4151 | 4151 | ||
| 4152 | if (have_type and node_tags[member.ast.type_expr] != .@"anytype") { | 4152 | if (have_type) { |
| 4153 | const field_type = try typeExpr(&block_scope, &namespace.base, member.ast.type_expr); | 4153 | const field_type: Zir.Inst.Ref = if (node_tags[member.ast.type_expr] == .@"anytype") |
| 4154 | .none | ||
| 4155 | else | ||
| 4156 | try typeExpr(&block_scope, &namespace.base, member.ast.type_expr); | ||
| 4154 | fields_data.appendAssumeCapacity(@enumToInt(field_type)); | 4157 | fields_data.appendAssumeCapacity(@enumToInt(field_type)); |
| 4158 | } else if (arg_inst == .none and !have_auto_enum) { | ||
| 4159 | return astgen.failNode(member_node, "union field missing type", .{}); | ||
| 4155 | } | 4160 | } |
| 4156 | if (have_align) { | 4161 | if (have_align) { |
| 4157 | const align_inst = try expr(&block_scope, &block_scope.base, .{ .ty = .u32_type }, member.ast.align_expr); | 4162 | const align_inst = try expr(&block_scope, &block_scope.base, .{ .ty = .u32_type }, member.ast.align_expr); |
| ... | @@ -4172,6 +4177,20 @@ fn unionDeclInner( | ... | @@ -4172,6 +4177,20 @@ fn unionDeclInner( |
| 4172 | }, | 4177 | }, |
| 4173 | ); | 4178 | ); |
| 4174 | } | 4179 | } |
| 4180 | if (!have_auto_enum) { | ||
| 4181 | return astgen.failNodeNotes( | ||
| 4182 | node, | ||
| 4183 | "explicitly valued tagged union requires inferred enum tag type", | ||
| 4184 | .{}, | ||
| 4185 | &[_]u32{ | ||
| 4186 | try astgen.errNoteNode( | ||
| 4187 | member.ast.value_expr, | ||
| 4188 | "tag value specified here", | ||
| 4189 | .{}, | ||
| 4190 | ), | ||
| 4191 | }, | ||
| 4192 | ); | ||
| 4193 | } | ||
| 4175 | const tag_value = try expr(&block_scope, &block_scope.base, .{ .ty = arg_inst }, member.ast.value_expr); | 4194 | const tag_value = try expr(&block_scope, &block_scope.base, .{ .ty = arg_inst }, member.ast.value_expr); |
| 4176 | fields_data.appendAssumeCapacity(@enumToInt(tag_value)); | 4195 | fields_data.appendAssumeCapacity(@enumToInt(tag_value)); |
| 4177 | } | 4196 | } |
src/Sema.zig+3-1| ... | @@ -12629,8 +12629,10 @@ fn semaUnionFields( | ... | @@ -12629,8 +12629,10 @@ fn semaUnionFields( |
| 12629 | set.putAssumeCapacity(field_name, {}); | 12629 | set.putAssumeCapacity(field_name, {}); |
| 12630 | } | 12630 | } |
| 12631 | 12631 | ||
| 12632 | const field_ty: Type = if (field_type_ref == .none) | 12632 | const field_ty: Type = if (!has_type) |
| 12633 | Type.initTag(.void) | 12633 | Type.initTag(.void) |
| 12634 | else if (field_type_ref == .none) | ||
| 12635 | Type.initTag(.noreturn) | ||
| 12634 | else | 12636 | else |
| 12635 | // TODO: if we need to report an error here, use a source location | 12637 | // TODO: if we need to report an error here, use a source location |
| 12636 | // that points to this type expression rather than the union. | 12638 | // that points to this type expression rather than the union. |
src/Zir.zig+1| ... | @@ -2686,6 +2686,7 @@ pub const Inst = struct { | ... | @@ -2686,6 +2686,7 @@ pub const Inst = struct { |
| 2686 | /// 9. fields: { // for every fields_len | 2686 | /// 9. fields: { // for every fields_len |
| 2687 | /// field_name: u32, // null terminated string index | 2687 | /// field_name: u32, // null terminated string index |
| 2688 | /// field_type: Ref, // if corresponding bit is set | 2688 | /// field_type: Ref, // if corresponding bit is set |
| 2689 | /// - if none, means `anytype`. | ||
| 2689 | /// align: Ref, // if corresponding bit is set | 2690 | /// align: Ref, // if corresponding bit is set |
| 2690 | /// tag_value: Ref, // if corresponding bit is set | 2691 | /// tag_value: Ref, // if corresponding bit is set |
| 2691 | /// } | 2692 | /// } |
test/stage2/cbe.zig+34| ... | @@ -570,6 +570,40 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -570,6 +570,40 @@ pub fn addCases(ctx: *TestContext) !void { |
| 570 | , ""); | 570 | , ""); |
| 571 | } | 571 | } |
| 572 | 572 | ||
| 573 | { | ||
| 574 | var case = ctx.exeFromCompiledC("unions", .{}); | ||
| 575 | |||
| 576 | case.addError( | ||
| 577 | \\const U = union { | ||
| 578 | \\ a: u32, | ||
| 579 | \\ b | ||
| 580 | \\}; | ||
| 581 | , &.{ | ||
| 582 | ":3:5: error: union field missing type", | ||
| 583 | }); | ||
| 584 | |||
| 585 | case.addError( | ||
| 586 | \\const E = enum { a, b }; | ||
| 587 | \\const U = union(E) { | ||
| 588 | \\ a: u32 = 1, | ||
| 589 | \\ b: f32 = 2, | ||
| 590 | \\}; | ||
| 591 | , &.{ | ||
| 592 | ":2:11: error: explicitly valued tagged union requires inferred enum tag type", | ||
| 593 | ":3:14: note: tag value specified here", | ||
| 594 | }); | ||
| 595 | |||
| 596 | case.addError( | ||
| 597 | \\const U = union(enum) { | ||
| 598 | \\ a: u32 = 1, | ||
| 599 | \\ b: f32 = 2, | ||
| 600 | \\}; | ||
| 601 | , &.{ | ||
| 602 | ":1:11: error: explicitly valued tagged union missing integer tag type", | ||
| 603 | ":2:14: note: tag value specified here", | ||
| 604 | }); | ||
| 605 | } | ||
| 606 | |||
| 573 | { | 607 | { |
| 574 | var case = ctx.exeFromCompiledC("enums", .{}); | 608 | var case = ctx.exeFromCompiledC("enums", .{}); |
| 575 | 609 |