Sema: fix switch validation '_' prong on wrong type

This commit is contained in:
Andrew Kelley 2021-04-07 22:19:17 -07:00
parent e730172e47
commit 57aa289fde
3 changed files with 50 additions and 4 deletions

View File

@ -1972,7 +1972,7 @@ fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErr
return mod.fail(&block.base, dest_ty_src, "expected enum, found {}", .{dest_ty});
}
if (!dest_ty.isExhaustiveEnum()) {
if (dest_ty.isNonexhaustiveEnum()) {
if (operand.value()) |int_val| {
return mod.constInst(arena, src, .{
.ty = dest_ty,
@ -2762,7 +2762,7 @@ fn analyzeSwitch(
const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = src_node_offset };
// Validate usage of '_' prongs.
if (special_prong == .under and !operand.ty.isExhaustiveEnum()) {
if (special_prong == .under and !operand.ty.isNonexhaustiveEnum()) {
const msg = msg: {
const msg = try mod.errMsg(
&block.base,

View File

@ -2119,9 +2119,9 @@ pub const Type = extern union {
}
}
pub fn isExhaustiveEnum(ty: Type) bool {
pub fn isNonexhaustiveEnum(ty: Type) bool {
return switch (ty.tag()) {
.enum_full, .enum_simple => true,
.enum_nonexhaustive => true,
else => false,
};
}

View File

@ -717,6 +717,52 @@ pub fn addCases(ctx: *TestContext) !void {
":4:5: note: unhandled enumeration value: 'b'",
":1:11: note: enum 'E' declared here",
});
case.addError(
\\const E = enum { a, b, c };
\\export fn foo() void {
\\ var x: E = .a;
\\ switch (x) {
\\ .a => {},
\\ .b => {},
\\ .b => {},
\\ .c => {},
\\ }
\\}
, &.{
":7:10: error: duplicate switch value",
":6:10: note: previous value here",
});
case.addError(
\\const E = enum { a, b, c };
\\export fn foo() void {
\\ var x: E = .a;
\\ switch (x) {
\\ .a => {},
\\ .b => {},
\\ .c => {},
\\ else => {},
\\ }
\\}
, &.{
":8:14: error: unreachable else prong; all cases already handled",
});
case.addError(
\\const E = enum { a, b, c };
\\export fn foo() void {
\\ var x: E = .a;
\\ switch (x) {
\\ .a => {},
\\ .b => {},
\\ _ => {},
\\ }
\\}
, &.{
":4:5: error: '_' prong only allowed when switching on non-exhaustive enums",
":7:11: note: '_' prong here",
});
}
ctx.c("empty start function", linux_x64,