@@ -8378,9 +8378,12 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8378
8378
.Enum => {
8379
8379
var seen_fields = try gpa.alloc(?Module.SwitchProngSrc, operand_ty.enumFieldCount());
8380
8380
defer gpa.free(seen_fields);
8381
-
8382
8381
mem.set(?Module.SwitchProngSrc, seen_fields, null);
8383
8382
8383
+ // This is used for non-exhaustive enum values that do not correspond to any tags.
8384
+ var range_set = RangeSet.init(gpa, sema.mod);
8385
+ defer range_set.deinit();
8386
+
8384
8387
var extra_index: usize = special.end;
8385
8388
{
8386
8389
var scalar_i: u32 = 0;
@@ -8394,6 +8397,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8394
8397
try sema.validateSwitchItemEnum(
8395
8398
block,
8396
8399
seen_fields,
8400
+ &range_set,
8397
8401
item_ref,
8398
8402
src_node_offset,
8399
8403
.{ .scalar = scalar_i },
@@ -8416,6 +8420,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8416
8420
try sema.validateSwitchItemEnum(
8417
8421
block,
8418
8422
seen_fields,
8423
+ &range_set,
8419
8424
item_ref,
8420
8425
src_node_offset,
8421
8426
.{ .multi = .{ .prong = multi_i, .item = @intCast(u32, item_i) } },
@@ -9317,30 +9322,15 @@ fn validateSwitchItemEnum(
9317
9322
sema: *Sema,
9318
9323
block: *Block,
9319
9324
seen_fields: []?Module.SwitchProngSrc,
9325
+ range_set: *RangeSet,
9320
9326
item_ref: Zir.Inst.Ref,
9321
9327
src_node_offset: i32,
9322
9328
switch_prong_src: Module.SwitchProngSrc,
9323
9329
) CompileError!void {
9324
9330
const item_tv = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none);
9325
9331
const field_index = item_tv.ty.enumTagFieldIndex(item_tv.val, sema.mod) orelse {
9326
- const msg = msg: {
9327
- const src = switch_prong_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), src_node_offset, .none);
9328
- const msg = try sema.errMsg(
9329
- block,
9330
- src,
9331
- "enum '{}' has no tag with value '{}'",
9332
- .{ item_tv.ty.fmt(sema.mod), item_tv.val.fmtValue(item_tv.ty, sema.mod) },
9333
- );
9334
- errdefer msg.destroy(sema.gpa);
9335
- try sema.mod.errNoteNonLazy(
9336
- item_tv.ty.declSrcLoc(sema.mod),
9337
- msg,
9338
- "enum declared here",
9339
- .{},
9340
- );
9341
- break :msg msg;
9342
- };
9343
- return sema.failWithOwnedErrorMsg(block, msg);
9332
+ const maybe_prev_src = try range_set.add(item_tv.val, item_tv.val, item_tv.ty, switch_prong_src);
9333
+ return sema.validateSwitchDupe(block, maybe_prev_src, switch_prong_src, src_node_offset);
9344
9334
};
9345
9335
const maybe_prev_src = seen_fields[field_index];
9346
9336
seen_fields[field_index] = switch_prong_src;
0 commit comments