Commit b971c7d0ff
Changed files (5)
src-self-hosted
test
src-self-hosted/translate_c.zig
@@ -440,7 +440,6 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
.PrivateExtern => return failDecl(c, fn_decl_loc, fn_name, "unsupported storage class: private extern", .{}),
.Auto => unreachable, // Not legal on functions
.Register => unreachable, // Not legal on functions
- else => unreachable,
},
};
@@ -953,6 +952,19 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
tld_node.semicolon_token = try appendToken(c, .Semicolon, ";");
try addTopLevelDecl(c, field_name, &tld_node.base);
}
+ // make non exhaustive
+ const field_node = try c.a().create(ast.Node.ContainerField);
+ field_node.* = .{
+ .doc_comments = null,
+ .comptime_token = null,
+ .name_token = try appendIdentifier(c, "_"),
+ .type_expr = null,
+ .value_expr = null,
+ .align_expr = null,
+ };
+
+ try container_node.fields_and_decls.push(&field_node.base);
+ _ = try appendToken(c, .Comma, ",");
container_node.rbrace_token = try appendToken(c, .RBrace, "}");
break :blk &container_node.base;
@@ -1231,18 +1243,6 @@ fn transBinaryOperator(
op_id = .BitOr;
op_token = try appendToken(rp.c, .Pipe, "|");
},
- .Assign,
- .MulAssign,
- .DivAssign,
- .RemAssign,
- .AddAssign,
- .SubAssign,
- .ShlAssign,
- .ShrAssign,
- .AndAssign,
- .XorAssign,
- .OrAssign,
- => unreachable,
else => unreachable,
}
@@ -1678,7 +1678,6 @@ fn transStringLiteral(
"TODO: support string literal kind {}",
.{kind},
),
- else => unreachable,
}
}
test/stage1/behavior/cast.zig
@@ -618,7 +618,6 @@ test "peer resolution of string literals" {
.b => "two",
.c => "three",
.d => "four",
- else => unreachable,
};
expect(mem.eql(u8, cmd, "two"));
}
test/stage1/behavior/enum.zig
@@ -11,17 +11,41 @@ test "extern enum" {
};
fn doTheTest(y: c_int) void {
var x = i.o;
- expect(@enumToInt(x) == 2);
- x = @intToEnum(i, 12);
- expect(@enumToInt(x) == 12);
- x = @intToEnum(i, y);
- expect(@enumToInt(x) == 52);
switch (x) {
- .n,
- .o,
- .p => unreachable,
+ .n, .p => unreachable,
+ .o => {},
+ }
+ }
+ };
+ S.doTheTest(52);
+ comptime S.doTheTest(52);
+}
+
+test "non-exhaustive enum" {
+ const S = struct {
+ const E = enum(u8) {
+ a,
+ b,
+ _,
+ };
+ fn doTheTest(y: u8) void {
+ var e: E = .b;
+ switch (e) {
+ .a => {},
+ .b => {},
+ _ => {},
+ }
+
+ switch (e) {
+ .a => {},
+ .b => {},
else => {},
}
+ expect(@enumToInt(e) == 1);
+ e = @intToEnum(E, 12);
+ expect(@enumToInt(e) == 12);
+ e = @intToEnum(E, y);
+ expect(@enumToInt(e) == 52);
}
};
S.doTheTest(52);
test/compile_errors.zig
@@ -2,6 +2,28 @@ const tests = @import("tests.zig");
const builtin = @import("builtin");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.addTest("non-exhaustive enums",
+ \\const E = enum {
+ \\ a,
+ \\ b,
+ \\ _,
+ \\};
+ \\pub export fn entry() void {
+ \\ var e: E = .b;
+ \\ switch (e) { // error: switch not handling the tag `b`
+ \\ .a => {},
+ \\ _ => {},
+ \\ }
+ \\ switch (e) { // error: switch on non-exhaustive enum must include `else` or `_` prong
+ \\ .a => {},
+ \\ .b => {},
+ \\ }
+ \\}
+ , &[_][]const u8{
+ "tmp.zig:8:5: error: enumeration value 'E.b' not handled in switch",
+ "tmp.zig:12:5: error: switch on non-exhaustive enum must include `else` or `_` prong",
+ });
+
cases.addTest("@export with empty name string",
\\pub export fn entry() void { }
\\comptime {
@@ -139,25 +161,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
"tmp.zig:2:13: error: pointer type '[*]align(4) u8' requires aligned address",
});
- cases.add("switch on extern enum missing else prong",
- \\const i = extern enum {
- \\ n = 0,
- \\ o = 2,
- \\ p = 4,
- \\ q = 4,
- \\};
- \\pub fn main() void {
- \\ var x = @intToEnum(i, 52);
- \\ switch (x) {
- \\ .n,
- \\ .o,
- \\ .p => unreachable,
- \\ }
- \\}
- , &[_][]const u8{
- "tmp.zig:9:5: error: switch on an extern enum must have an else prong",
- });
-
cases.add("invalid float literal",
\\const std = @import("std");
\\
test/translate_c.zig
@@ -629,6 +629,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ VAL21 = 6917529027641081853,
\\ VAL22 = 0,
\\ VAL23 = -1,
+ \\ _,
\\};
});
}
@@ -990,6 +991,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const FOO = @enumToInt(enum_enum_ty.FOO);
\\pub const enum_enum_ty = extern enum {
\\ FOO,
+ \\ _,
\\};
\\pub extern var my_enum: enum_enum_ty;
});
@@ -1106,6 +1108,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ a,
\\ b,
\\ c,
+ \\ _,
\\};
\\pub const d = enum_unnamed_1;
\\pub const e = @enumToInt(enum_unnamed_2.e);
@@ -1115,6 +1118,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ e = 0,
\\ f = 4,
\\ g = 5,
+ \\ _,
\\};
\\pub export var h: enum_unnamed_2 = @intToEnum(enum_unnamed_2, e);
\\pub const i = @enumToInt(enum_unnamed_3.i);
@@ -1124,6 +1128,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ i,
\\ j,
\\ k,
+ \\ _,
\\};
\\pub const struct_Baz = extern struct {
\\ l: enum_unnamed_3,
@@ -1136,6 +1141,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ n,
\\ o,
\\ p,
+ \\ _,
\\};
,
\\pub const Baz = struct_Baz;
@@ -1566,6 +1572,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\const enum_unnamed_1 = extern enum {
\\ One,
\\ Two,
+ \\ _,
\\};
});
@@ -1669,6 +1676,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ A,
\\ B,
\\ C,
+ \\ _,
\\};
\\pub const SomeTypedef = c_int;
\\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 {
\\pub const enum_Bar = extern enum {
\\ A,
\\ B,
+ \\ _,
\\};
\\pub extern fn func(a: [*c]struct_Foo, b: [*c][*c]enum_Bar) void;
,
@@ -1977,6 +1986,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ A,
\\ B,
\\ C,
+ \\ _,
\\};
\\pub export fn if_none_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void, arg_d: enum_SomeEnum) c_int {
\\ var a = arg_a;
@@ -2418,6 +2428,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ A = 2,
\\ B = 5,
\\ @"1" = 6,
+ \\ _,
\\};
,
\\pub const Foo = enum_Foo;