Merge pull request #24381 from Justus2308/switch-better-underscore
Enhance switch on non-exhaustive enums
This commit is contained in:
@@ -1073,3 +1073,50 @@ test "switch on 8-bit mod result" {
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
test "switch on non-exhaustive enum" {
|
||||
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
|
||||
|
||||
const E = enum(u4) {
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
_,
|
||||
|
||||
fn doTheTest(e: @This()) !void {
|
||||
switch (e) {
|
||||
.a, .b => {},
|
||||
else => return error.TestFailed,
|
||||
}
|
||||
switch (e) {
|
||||
.a, .b => {},
|
||||
.c => return error.TestFailed,
|
||||
_ => return error.TestFailed,
|
||||
}
|
||||
switch (e) {
|
||||
.a, .b => {},
|
||||
.c, _ => return error.TestFailed,
|
||||
}
|
||||
switch (e) {
|
||||
.a => {},
|
||||
.b, .c, _ => return error.TestFailed,
|
||||
}
|
||||
switch (e) {
|
||||
.b => return error.TestFailed,
|
||||
else => {},
|
||||
_ => return error.TestFailed,
|
||||
}
|
||||
switch (e) {
|
||||
else => {},
|
||||
_ => return error.TestFailed,
|
||||
}
|
||||
switch (e) {
|
||||
inline else => {},
|
||||
_ => return error.TestFailed,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
try E.doTheTest(.a);
|
||||
try comptime E.doTheTest(.a);
|
||||
}
|
||||
|
||||
@@ -249,3 +249,27 @@ test "switch loop on larger than pointer integer" {
|
||||
}
|
||||
try expect(entry == 3);
|
||||
}
|
||||
|
||||
test "switch loop on non-exhaustive enum" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
const E = enum(u8) { a, b, c, _ };
|
||||
|
||||
fn doTheTest() !void {
|
||||
var start: E = undefined;
|
||||
start = .a;
|
||||
const result: u32 = s: switch (start) {
|
||||
.a => continue :s .c,
|
||||
else => continue :s @enumFromInt(123),
|
||||
.b, _ => |x| break :s @intFromEnum(x),
|
||||
};
|
||||
try expect(result == 123);
|
||||
}
|
||||
};
|
||||
try S.doTheTest();
|
||||
try comptime S.doTheTest();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
const E = enum(u8) {
|
||||
a,
|
||||
b,
|
||||
_,
|
||||
};
|
||||
const U = union(E) {
|
||||
a: i32,
|
||||
b: u32,
|
||||
};
|
||||
pub export fn entry1() void {
|
||||
const e: E = .b;
|
||||
switch (e) { // error: switch not handling the tag `b`
|
||||
.a, _ => {},
|
||||
}
|
||||
}
|
||||
pub export fn entry2() void {
|
||||
const u = U{ .a = 2 };
|
||||
switch (u) { // error: `_` prong not allowed when switching on tagged union
|
||||
.a => {},
|
||||
.b, _ => {},
|
||||
}
|
||||
}
|
||||
|
||||
// error
|
||||
//
|
||||
// :12:5: error: switch must handle all possibilities
|
||||
// :3:5: note: unhandled enumeration value: 'b'
|
||||
// :1:11: note: enum 'tmp.E' declared here
|
||||
// :18:5: error: '_' prong only allowed when switching on non-exhaustive enums
|
||||
// :20:13: note: '_' prong here
|
||||
// :18:5: note: consider using 'else'
|
||||
@@ -0,0 +1,25 @@
|
||||
const E = enum(u8) {
|
||||
a,
|
||||
b,
|
||||
_,
|
||||
};
|
||||
|
||||
export fn f(e: E) void {
|
||||
switch (e) {
|
||||
.a => {},
|
||||
inline _ => {},
|
||||
}
|
||||
}
|
||||
|
||||
export fn g(e: E) void {
|
||||
switch (e) {
|
||||
.a => {},
|
||||
else => {},
|
||||
inline _ => {},
|
||||
}
|
||||
}
|
||||
|
||||
// error
|
||||
//
|
||||
// :10:16: error: cannot inline '_' prong
|
||||
// :18:16: error: cannot inline '_' prong
|
||||
@@ -0,0 +1,16 @@
|
||||
const E = enum(u8) {
|
||||
a,
|
||||
b,
|
||||
_,
|
||||
};
|
||||
|
||||
export fn f(e: E) void {
|
||||
switch (e) {
|
||||
.a, .b, _ => {},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
// error
|
||||
//
|
||||
// :10:14: error: unreachable else prong; all explicit cases already handled
|
||||
@@ -16,5 +16,5 @@ pub export fn entry() void {
|
||||
// target=native
|
||||
//
|
||||
// :7:5: error: '_' prong only allowed when switching on non-exhaustive enums
|
||||
// :10:11: note: '_' prong here
|
||||
// :10:9: note: '_' prong here
|
||||
// :7:5: note: consider using 'else'
|
||||
|
||||
@@ -37,7 +37,7 @@ pub export fn entry3() void {
|
||||
// :12:5: error: switch must handle all possibilities
|
||||
// :3:5: note: unhandled enumeration value: 'b'
|
||||
// :1:11: note: enum 'tmp.E' declared here
|
||||
// :19:5: error: switch on non-exhaustive enum must include 'else' or '_' prong
|
||||
// :19:5: error: switch on non-exhaustive enum must include 'else' or '_' prong or both
|
||||
// :26:5: error: '_' prong only allowed when switching on non-exhaustive enums
|
||||
// :29:11: note: '_' prong here
|
||||
// :29:9: note: '_' prong here
|
||||
// :26:5: note: consider using 'else'
|
||||
|
||||
Reference in New Issue
Block a user