| ... | @@ -8378,9 +8378,12 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -8378,9 +8378,12 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8378 | .Enum => { | 8378 | .Enum => { |
| 8379 | var seen_fields = try gpa.alloc(?Module.SwitchProngSrc, operand_ty.enumFieldCount()); | 8379 | var seen_fields = try gpa.alloc(?Module.SwitchProngSrc, operand_ty.enumFieldCount()); |
| 8380 | defer gpa.free(seen_fields); | 8380 | defer gpa.free(seen_fields); |
| 8381 | | | |
| 8382 | mem.set(?Module.SwitchProngSrc, seen_fields, null); | 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 | var extra_index: usize = special.end; | 8387 | var extra_index: usize = special.end; |
| 8385 | { | 8388 | { |
| 8386 | var scalar_i: u32 = 0; | 8389 | var scalar_i: u32 = 0; |
| ... | @@ -8394,6 +8397,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -8394,6 +8397,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8394 | try sema.validateSwitchItemEnum( | 8397 | try sema.validateSwitchItemEnum( |
| 8395 | block, | 8398 | block, |
| 8396 | seen_fields, | 8399 | seen_fields, |
| | 8400 | &range_set, |
| 8397 | item_ref, | 8401 | item_ref, |
| 8398 | src_node_offset, | 8402 | src_node_offset, |
| 8399 | .{ .scalar = scalar_i }, | 8403 | .{ .scalar = scalar_i }, |
| ... | @@ -8416,6 +8420,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -8416,6 +8420,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8416 | try sema.validateSwitchItemEnum( | 8420 | try sema.validateSwitchItemEnum( |
| 8417 | block, | 8421 | block, |
| 8418 | seen_fields, | 8422 | seen_fields, |
| | 8423 | &range_set, |
| 8419 | item_ref, | 8424 | item_ref, |
| 8420 | src_node_offset, | 8425 | src_node_offset, |
| 8421 | .{ .multi = .{ .prong = multi_i, .item = @intCast(u32, item_i) } }, | 8426 | .{ .multi = .{ .prong = multi_i, .item = @intCast(u32, item_i) } }, |
| ... | @@ -9317,30 +9322,15 @@ fn validateSwitchItemEnum( | ... | @@ -9317,30 +9322,15 @@ fn validateSwitchItemEnum( |
| 9317 | sema: *Sema, | 9322 | sema: *Sema, |
| 9318 | block: *Block, | 9323 | block: *Block, |
| 9319 | seen_fields: []?Module.SwitchProngSrc, | 9324 | seen_fields: []?Module.SwitchProngSrc, |
| | 9325 | range_set: *RangeSet, |
| 9320 | item_ref: Zir.Inst.Ref, | 9326 | item_ref: Zir.Inst.Ref, |
| 9321 | src_node_offset: i32, | 9327 | src_node_offset: i32, |
| 9322 | switch_prong_src: Module.SwitchProngSrc, | 9328 | switch_prong_src: Module.SwitchProngSrc, |
| 9323 | ) CompileError!void { | 9329 | ) CompileError!void { |
| 9324 | const item_tv = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none); | 9330 | const item_tv = try sema.resolveSwitchItemVal(block, item_ref, src_node_offset, switch_prong_src, .none); |
| 9325 | const field_index = item_tv.ty.enumTagFieldIndex(item_tv.val, sema.mod) orelse { | 9331 | const field_index = item_tv.ty.enumTagFieldIndex(item_tv.val, sema.mod) orelse { |
| 9326 | const msg = msg: { | 9332 | const maybe_prev_src = try range_set.add(item_tv.val, item_tv.val, item_tv.ty, switch_prong_src); |
| 9327 | const src = switch_prong_src.resolve(sema.gpa, sema.mod.declPtr(block.src_decl), src_node_offset, .none); | 9333 | return sema.validateSwitchDupe(block, maybe_prev_src, switch_prong_src, src_node_offset); |
| 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); | | |
| 9344 | }; | 9334 | }; |
| 9345 | const maybe_prev_src = seen_fields[field_index]; | 9335 | const maybe_prev_src = seen_fields[field_index]; |
| 9346 | seen_fields[field_index] = switch_prong_src; | 9336 | seen_fields[field_index] = switch_prong_src; |