mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 05:20:34 +00:00
Sema: fix switch validation '_' prong on wrong type
This commit is contained in:
parent
e730172e47
commit
57aa289fde
@ -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,
|
||||
|
||||
@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user