aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-07-19 18:39:48 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-07-19 18:39:48 -0700
commit0efc6a35bead74b5faffbc87b446b5087f1bb99b (patch)
tree6b8eaabe33a371d366c0be57b76c57e458d963e4 /src
parent1d5f865cfafdaa96cac35ada9bb9e8b1a4e2bc36 (diff)
downloadzig-0efc6a35bead74b5faffbc87b446b5087f1bb99b.tar.gz
zig-0efc6a35bead74b5faffbc87b446b5087f1bb99b.zip
Sema: fix enum value without tag name used as switch item
Previously stage2 would report a false positive compile error saying there was no tag for this value.
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig28
1 files changed, 9 insertions, 19 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 3c561821f4..702991bf5e 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -8378,9 +8378,12 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
.Enum => {
var seen_fields = try gpa.alloc(?Module.SwitchProngSrc, operand_ty.enumFieldCount());
defer gpa.free(seen_fields);
-
mem.set(?Module.SwitchProngSrc, seen_fields, null);
+ // This is used for non-exhaustive enum values that do not correspond to any tags.
+ var range_set = RangeSet.init(gpa, sema.mod);
+ defer range_set.deinit();
+
var extra_index: usize = special.end;
{
var scalar_i: u32 = 0;
@@ -8394,6 +8397,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
try sema.validateSwitchItemEnum(
block,
seen_fields,
+ &range_set,
item_ref,
src_node_offset,
.{ .scalar = scalar_i },
@@ -8416,6 +8420,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
try sema.validateSwitchItemEnum(
block,
seen_fields,
+ &range_set,
item_ref,
src_node_offset,
.{ .multi = .{ .prong = multi_i, .item = @intCast(u32, item_i) } },
@@ -9317,30 +9322,15 @@ fn validateSwitchItemEnum(
sema: *Sema,
block: *Block,
seen_fields: []?Module.SwitchProngSrc,
+ range_set: *RangeSet,
item_ref: Zir.Inst.Ref,
src_node_offset: i32,
switch_prong_src: Module.SwitchProngSrc,
) CompileError!void {
const item_tv = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none);
const field_index = item_tv.ty.enumTagFieldIndex(item_tv.val, sema.mod) orelse {
- const msg = msg: {
- const src = switch_prong_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), src_node_offset, .none);
- const msg = try sema.errMsg(
- block,
- src,
- "enum '{}' has no tag with value '{}'",
- .{ item_tv.ty.fmt(sema.mod), item_tv.val.fmtValue(item_tv.ty, sema.mod) },
- );
- errdefer msg.destroy(sema.gpa);
- try sema.mod.errNoteNonLazy(
- item_tv.ty.declSrcLoc(sema.mod),
- msg,
- "enum declared here",
- .{},
- );
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
+ const maybe_prev_src = try range_set.add(item_tv.val, item_tv.val, item_tv.ty, switch_prong_src);
+ return sema.validateSwitchDupe(block, maybe_prev_src, switch_prong_src, src_node_offset);
};
const maybe_prev_src = seen_fields[field_index];
seen_fields[field_index] = switch_prong_src;