From b971c7d0ff1c0ef86ac8d6816eb5e115f0d648fa Mon Sep 17 00:00:00 2001 From: Vexu Date: Wed, 15 Jan 2020 20:40:56 +0200 Subject: [PATCH] update tests and translate-c --- src-self-hosted/translate_c.zig | 27 +++++++++++----------- test/compile_errors.zig | 41 ++++++++++++++++++--------------- test/stage1/behavior/cast.zig | 1 - test/stage1/behavior/enum.zig | 40 +++++++++++++++++++++++++------- test/translate_c.zig | 11 +++++++++ 5 files changed, 78 insertions(+), 42 deletions(-) diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index a876b20b68..ad58b6a916 100644 --- a/src-self-hosted/translate_c.zig +++ b/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, } } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 3ce5bd8801..e7ef53452a 100644 --- a/test/compile_errors.zig +++ b/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"); \\ diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig index ae2530af61..fe55b445a8 100644 --- a/test/stage1/behavior/cast.zig +++ b/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")); } diff --git a/test/stage1/behavior/enum.zig b/test/stage1/behavior/enum.zig index d5bb2ddbb2..c888722f27 100644 --- a/test/stage1/behavior/enum.zig +++ b/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); diff --git a/test/translate_c.zig b/test/translate_c.zig index 16caa6e323..13779cb2fa 100644 --- a/test/translate_c.zig +++ b/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;