| author | |
| committer | |
| log | 57aa289fdef543a507d8da039f5b7e7f2762c878 |
| tree | 1e8f3c072f2c004554880cd23e53337bbc24a39b |
| parent | e730172e47749db8a9d3be5949231bde95343b39 |
3 files changed, 50 insertions(+), 4 deletions(-)
src/Sema.zig+2-2| ... | @@ -1972,7 +1972,7 @@ fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErr | ... | @@ -1972,7 +1972,7 @@ fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErr |
| 1972 | return mod.fail(&block.base, dest_ty_src, "expected enum, found {}", .{dest_ty}); | 1972 | return mod.fail(&block.base, dest_ty_src, "expected enum, found {}", .{dest_ty}); |
| 1973 | } | 1973 | } |
| 1974 | 1974 | ||
| 1975 | if (!dest_ty.isExhaustiveEnum()) { | 1975 | if (dest_ty.isNonexhaustiveEnum()) { |
| 1976 | if (operand.value()) |int_val| { | 1976 | if (operand.value()) |int_val| { |
| 1977 | return mod.constInst(arena, src, .{ | 1977 | return mod.constInst(arena, src, .{ |
| 1978 | .ty = dest_ty, | 1978 | .ty = dest_ty, |
| ... | @@ -2762,7 +2762,7 @@ fn analyzeSwitch( | ... | @@ -2762,7 +2762,7 @@ fn analyzeSwitch( |
| 2762 | const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = src_node_offset }; | 2762 | const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = src_node_offset }; |
| 2763 | 2763 | ||
| 2764 | // Validate usage of '_' prongs. | 2764 | // Validate usage of '_' prongs. |
| 2765 | if (special_prong == .under and !operand.ty.isExhaustiveEnum()) { | 2765 | if (special_prong == .under and !operand.ty.isNonexhaustiveEnum()) { |
| 2766 | const msg = msg: { | 2766 | const msg = msg: { |
| 2767 | const msg = try mod.errMsg( | 2767 | const msg = try mod.errMsg( |
| 2768 | &block.base, | 2768 | &block.base, |
src/type.zig+2-2| ... | @@ -2119,9 +2119,9 @@ pub const Type = extern union { | ... | @@ -2119,9 +2119,9 @@ pub const Type = extern union { |
| 2119 | } | 2119 | } |
| 2120 | } | 2120 | } |
| 2121 | 2121 | ||
| 2122 | pub fn isExhaustiveEnum(ty: Type) bool { | 2122 | pub fn isNonexhaustiveEnum(ty: Type) bool { |
| 2123 | return switch (ty.tag()) { | 2123 | return switch (ty.tag()) { |
| 2124 | .enum_full, .enum_simple => true, | 2124 | .enum_nonexhaustive => true, |
| 2125 | else => false, | 2125 | else => false, |
| 2126 | }; | 2126 | }; |
| 2127 | } | 2127 | } |
test/stage2/cbe.zig+46| ... | @@ -717,6 +717,52 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -717,6 +717,52 @@ pub fn addCases(ctx: *TestContext) !void { |
| 717 | ":4:5: note: unhandled enumeration value: 'b'", | 717 | ":4:5: note: unhandled enumeration value: 'b'", |
| 718 | ":1:11: note: enum 'E' declared here", | 718 | ":1:11: note: enum 'E' declared here", |
| 719 | }); | 719 | }); |
| 720 | |||
| 721 | case.addError( | ||
| 722 | \\const E = enum { a, b, c }; | ||
| 723 | \\export fn foo() void { | ||
| 724 | \\ var x: E = .a; | ||
| 725 | \\ switch (x) { | ||
| 726 | \\ .a => {}, | ||
| 727 | \\ .b => {}, | ||
| 728 | \\ .b => {}, | ||
| 729 | \\ .c => {}, | ||
| 730 | \\ } | ||
| 731 | \\} | ||
| 732 | , &.{ | ||
| 733 | ":7:10: error: duplicate switch value", | ||
| 734 | ":6:10: note: previous value here", | ||
| 735 | }); | ||
| 736 | |||
| 737 | case.addError( | ||
| 738 | \\const E = enum { a, b, c }; | ||
| 739 | \\export fn foo() void { | ||
| 740 | \\ var x: E = .a; | ||
| 741 | \\ switch (x) { | ||
| 742 | \\ .a => {}, | ||
| 743 | \\ .b => {}, | ||
| 744 | \\ .c => {}, | ||
| 745 | \\ else => {}, | ||
| 746 | \\ } | ||
| 747 | \\} | ||
| 748 | , &.{ | ||
| 749 | ":8:14: error: unreachable else prong; all cases already handled", | ||
| 750 | }); | ||
| 751 | |||
| 752 | case.addError( | ||
| 753 | \\const E = enum { a, b, c }; | ||
| 754 | \\export fn foo() void { | ||
| 755 | \\ var x: E = .a; | ||
| 756 | \\ switch (x) { | ||
| 757 | \\ .a => {}, | ||
| 758 | \\ .b => {}, | ||
| 759 | \\ _ => {}, | ||
| 760 | \\ } | ||
| 761 | \\} | ||
| 762 | , &.{ | ||
| 763 | ":4:5: error: '_' prong only allowed when switching on non-exhaustive enums", | ||
| 764 | ":7:11: note: '_' prong here", | ||
| 765 | }); | ||
| 720 | } | 766 | } |
| 721 | 767 | ||
| 722 | ctx.c("empty start function", linux_x64, | 768 | ctx.c("empty start function", linux_x64, |