| author | |
| committer | |
| log | b971c7d0ff1c0ef86ac8d6816eb5e115f0d648fa |
| tree | fab4cfd6e9141b25b9e75f48a2b9e5d7473a3b54 |
| parent | 6fd0dddf186f6435f422f2992f44ec9a35e09f20 |
| signature |
5 files changed, 78 insertions(+), 42 deletions(-)
src-self-hosted/translate_c.zig+13-14| ... | ... | @@ -440,7 +440,6 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 440 | 440 | .PrivateExtern => return failDecl(c, fn_decl_loc, fn_name, "unsupported storage class: private extern", .{}), |
| 441 | 441 | .Auto => unreachable, // Not legal on functions |
| 442 | 442 | .Register => unreachable, // Not legal on functions |
| 443 | else => unreachable, | |
| 444 | 443 | }, |
| 445 | 444 | }; |
| 446 | 445 | |
| ... | ... | @@ -953,6 +952,19 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No |
| 953 | 952 | tld_node.semicolon_token = try appendToken(c, .Semicolon, ";"); |
| 954 | 953 | try addTopLevelDecl(c, field_name, &tld_node.base); |
| 955 | 954 | } |
| 955 | // make non exhaustive | |
| 956 | const field_node = try c.a().create(ast.Node.ContainerField); | |
| 957 | field_node.* = .{ | |
| 958 | .doc_comments = null, | |
| 959 | .comptime_token = null, | |
| 960 | .name_token = try appendIdentifier(c, "_"), | |
| 961 | .type_expr = null, | |
| 962 | .value_expr = null, | |
| 963 | .align_expr = null, | |
| 964 | }; | |
| 965 | ||
| 966 | try container_node.fields_and_decls.push(&field_node.base); | |
| 967 | _ = try appendToken(c, .Comma, ","); | |
| 956 | 968 | container_node.rbrace_token = try appendToken(c, .RBrace, "}"); |
| 957 | 969 | |
| 958 | 970 | break :blk &container_node.base; |
| ... | ... | @@ -1231,18 +1243,6 @@ fn transBinaryOperator( |
| 1231 | 1243 | op_id = .BitOr; |
| 1232 | 1244 | op_token = try appendToken(rp.c, .Pipe, "|"); |
| 1233 | 1245 | }, |
| 1234 | .Assign, | |
| 1235 | .MulAssign, | |
| 1236 | .DivAssign, | |
| 1237 | .RemAssign, | |
| 1238 | .AddAssign, | |
| 1239 | .SubAssign, | |
| 1240 | .ShlAssign, | |
| 1241 | .ShrAssign, | |
| 1242 | .AndAssign, | |
| 1243 | .XorAssign, | |
| 1244 | .OrAssign, | |
| 1245 | => unreachable, | |
| 1246 | 1246 | else => unreachable, |
| 1247 | 1247 | } |
| 1248 | 1248 | |
| ... | ... | @@ -1678,7 +1678,6 @@ fn transStringLiteral( |
| 1678 | 1678 | "TODO: support string literal kind {}", |
| 1679 | 1679 | .{kind}, |
| 1680 | 1680 | ), |
| 1681 | else => unreachable, | |
| 1682 | 1681 | } |
| 1683 | 1682 | } |
| 1684 | 1683 |
test/compile_errors.zig+22-19| ... | ... | @@ -2,6 +2,28 @@ const tests = @import("tests.zig"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | 3 | |
| 4 | 4 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5 | cases.addTest("non-exhaustive enums", | |
| 6 | \\const E = enum { | |
| 7 | \\ a, | |
| 8 | \\ b, | |
| 9 | \\ _, | |
| 10 | \\}; | |
| 11 | \\pub export fn entry() void { | |
| 12 | \\ var e: E = .b; | |
| 13 | \\ switch (e) { // error: switch not handling the tag `b` | |
| 14 | \\ .a => {}, | |
| 15 | \\ _ => {}, | |
| 16 | \\ } | |
| 17 | \\ switch (e) { // error: switch on non-exhaustive enum must include `else` or `_` prong | |
| 18 | \\ .a => {}, | |
| 19 | \\ .b => {}, | |
| 20 | \\ } | |
| 21 | \\} | |
| 22 | , &[_][]const u8{ | |
| 23 | "tmp.zig:8:5: error: enumeration value 'E.b' not handled in switch", | |
| 24 | "tmp.zig:12:5: error: switch on non-exhaustive enum must include `else` or `_` prong", | |
| 25 | }); | |
| 26 | ||
| 5 | 27 | cases.addTest("@export with empty name string", |
| 6 | 28 | \\pub export fn entry() void { } |
| 7 | 29 | \\comptime { |
| ... | ... | @@ -139,25 +161,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 139 | 161 | "tmp.zig:2:13: error: pointer type '[*]align(4) u8' requires aligned address", |
| 140 | 162 | }); |
| 141 | 163 | |
| 142 | cases.add("switch on extern enum missing else prong", | |
| 143 | \\const i = extern enum { | |
| 144 | \\ n = 0, | |
| 145 | \\ o = 2, | |
| 146 | \\ p = 4, | |
| 147 | \\ q = 4, | |
| 148 | \\}; | |
| 149 | \\pub fn main() void { | |
| 150 | \\ var x = @intToEnum(i, 52); | |
| 151 | \\ switch (x) { | |
| 152 | \\ .n, | |
| 153 | \\ .o, | |
| 154 | \\ .p => unreachable, | |
| 155 | \\ } | |
| 156 | \\} | |
| 157 | , &[_][]const u8{ | |
| 158 | "tmp.zig:9:5: error: switch on an extern enum must have an else prong", | |
| 159 | }); | |
| 160 | ||
| 161 | 164 | cases.add("invalid float literal", |
| 162 | 165 | \\const std = @import("std"); |
| 163 | 166 | \\ |
test/stage1/behavior/cast.zig-1| ... | ... | @@ -618,7 +618,6 @@ test "peer resolution of string literals" { |
| 618 | 618 | .b => "two", |
| 619 | 619 | .c => "three", |
| 620 | 620 | .d => "four", |
| 621 | else => unreachable, | |
| 622 | 621 | }; |
| 623 | 622 | expect(mem.eql(u8, cmd, "two")); |
| 624 | 623 | } |
test/stage1/behavior/enum.zig+32-8| ... | ... | @@ -11,17 +11,41 @@ test "extern enum" { |
| 11 | 11 | }; |
| 12 | 12 | fn doTheTest(y: c_int) void { |
| 13 | 13 | var x = i.o; |
| 14 | expect(@enumToInt(x) == 2); | |
| 15 | x = @intToEnum(i, 12); | |
| 16 | expect(@enumToInt(x) == 12); | |
| 17 | x = @intToEnum(i, y); | |
| 18 | expect(@enumToInt(x) == 52); | |
| 19 | 14 | switch (x) { |
| 20 | .n, | |
| 21 | .o, | |
| 22 | .p => unreachable, | |
| 15 | .n, .p => unreachable, | |
| 16 | .o => {}, | |
| 17 | } | |
| 18 | } | |
| 19 | }; | |
| 20 | S.doTheTest(52); | |
| 21 | comptime S.doTheTest(52); | |
| 22 | } | |
| 23 | ||
| 24 | test "non-exhaustive enum" { | |
| 25 | const S = struct { | |
| 26 | const E = enum(u8) { | |
| 27 | a, | |
| 28 | b, | |
| 29 | _, | |
| 30 | }; | |
| 31 | fn doTheTest(y: u8) void { | |
| 32 | var e: E = .b; | |
| 33 | switch (e) { | |
| 34 | .a => {}, | |
| 35 | .b => {}, | |
| 36 | _ => {}, | |
| 37 | } | |
| 38 | ||
| 39 | switch (e) { | |
| 40 | .a => {}, | |
| 41 | .b => {}, | |
| 23 | 42 | else => {}, |
| 24 | 43 | } |
| 44 | expect(@enumToInt(e) == 1); | |
| 45 | e = @intToEnum(E, 12); | |
| 46 | expect(@enumToInt(e) == 12); | |
| 47 | e = @intToEnum(E, y); | |
| 48 | expect(@enumToInt(e) == 52); | |
| 25 | 49 | } |
| 26 | 50 | }; |
| 27 | 51 | S.doTheTest(52); |
test/translate_c.zig+11| ... | ... | @@ -629,6 +629,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 629 | 629 | \\ VAL21 = 6917529027641081853, |
| 630 | 630 | \\ VAL22 = 0, |
| 631 | 631 | \\ VAL23 = -1, |
| 632 | \\ _, | |
| 632 | 633 | \\}; |
| 633 | 634 | }); |
| 634 | 635 | } |
| ... | ... | @@ -990,6 +991,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 990 | 991 | \\pub const FOO = @enumToInt(enum_enum_ty.FOO); |
| 991 | 992 | \\pub const enum_enum_ty = extern enum { |
| 992 | 993 | \\ FOO, |
| 994 | \\ _, | |
| 993 | 995 | \\}; |
| 994 | 996 | \\pub extern var my_enum: enum_enum_ty; |
| 995 | 997 | }); |
| ... | ... | @@ -1106,6 +1108,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1106 | 1108 | \\ a, |
| 1107 | 1109 | \\ b, |
| 1108 | 1110 | \\ c, |
| 1111 | \\ _, | |
| 1109 | 1112 | \\}; |
| 1110 | 1113 | \\pub const d = enum_unnamed_1; |
| 1111 | 1114 | \\pub const e = @enumToInt(enum_unnamed_2.e); |
| ... | ... | @@ -1115,6 +1118,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1115 | 1118 | \\ e = 0, |
| 1116 | 1119 | \\ f = 4, |
| 1117 | 1120 | \\ g = 5, |
| 1121 | \\ _, | |
| 1118 | 1122 | \\}; |
| 1119 | 1123 | \\pub export var h: enum_unnamed_2 = @intToEnum(enum_unnamed_2, e); |
| 1120 | 1124 | \\pub const i = @enumToInt(enum_unnamed_3.i); |
| ... | ... | @@ -1124,6 +1128,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1124 | 1128 | \\ i, |
| 1125 | 1129 | \\ j, |
| 1126 | 1130 | \\ k, |
| 1131 | \\ _, | |
| 1127 | 1132 | \\}; |
| 1128 | 1133 | \\pub const struct_Baz = extern struct { |
| 1129 | 1134 | \\ l: enum_unnamed_3, |
| ... | ... | @@ -1136,6 +1141,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1136 | 1141 | \\ n, |
| 1137 | 1142 | \\ o, |
| 1138 | 1143 | \\ p, |
| 1144 | \\ _, | |
| 1139 | 1145 | \\}; |
| 1140 | 1146 | , |
| 1141 | 1147 | \\pub const Baz = struct_Baz; |
| ... | ... | @@ -1566,6 +1572,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1566 | 1572 | \\const enum_unnamed_1 = extern enum { |
| 1567 | 1573 | \\ One, |
| 1568 | 1574 | \\ Two, |
| 1575 | \\ _, | |
| 1569 | 1576 | \\}; |
| 1570 | 1577 | }); |
| 1571 | 1578 | |
| ... | ... | @@ -1669,6 +1676,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1669 | 1676 | \\ A, |
| 1670 | 1677 | \\ B, |
| 1671 | 1678 | \\ C, |
| 1679 | \\ _, | |
| 1672 | 1680 | \\}; |
| 1673 | 1681 | \\pub const SomeTypedef = c_int; |
| 1674 | 1682 | \\pub export fn and_or_non_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void) c_int { |
| ... | ... | @@ -1713,6 +1721,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1713 | 1721 | \\pub const enum_Bar = extern enum { |
| 1714 | 1722 | \\ A, |
| 1715 | 1723 | \\ B, |
| 1724 | \\ _, | |
| 1716 | 1725 | \\}; |
| 1717 | 1726 | \\pub extern fn func(a: [*c]struct_Foo, b: [*c][*c]enum_Bar) void; |
| 1718 | 1727 | , |
| ... | ... | @@ -1977,6 +1986,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1977 | 1986 | \\ A, |
| 1978 | 1987 | \\ B, |
| 1979 | 1988 | \\ C, |
| 1989 | \\ _, | |
| 1980 | 1990 | \\}; |
| 1981 | 1991 | \\pub export fn if_none_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void, arg_d: enum_SomeEnum) c_int { |
| 1982 | 1992 | \\ var a = arg_a; |
| ... | ... | @@ -2418,6 +2428,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 2418 | 2428 | \\ A = 2, |
| 2419 | 2429 | \\ B = 5, |
| 2420 | 2430 | \\ @"1" = 6, |
| 2431 | \\ _, | |
| 2421 | 2432 | \\}; |
| 2422 | 2433 | , |
| 2423 | 2434 | \\pub const Foo = enum_Foo; |