| ... | ... | @@ -277,9 +277,6 @@ pub const Block = struct { |
| 277 | 277 | |
| 278 | 278 | c_import_buf: ?*std.ArrayList(u8) = null, |
| 279 | 279 | |
| 280 | | /// Value for switch_capture in an inline case |
| 281 | | inline_case_capture: Air.Inst.Ref = .none, |
| 282 | | |
| 283 | 280 | const ComptimeReason = union(enum) { |
| 284 | 281 | c_import: struct { |
| 285 | 282 | block: *Block, |
| ... | ... | @@ -1013,7 +1010,6 @@ fn analyzeBodyInner( |
| 1013 | 1010 | .switch_block => try sema.zirSwitchBlock(block, inst), |
| 1014 | 1011 | .switch_cond => try sema.zirSwitchCond(block, inst, false), |
| 1015 | 1012 | .switch_cond_ref => try sema.zirSwitchCond(block, inst, true), |
| 1016 | | .switch_capture_tag => try sema.zirSwitchCaptureTag(block, inst), |
| 1017 | 1013 | .type_info => try sema.zirTypeInfo(block, inst), |
| 1018 | 1014 | .size_of => try sema.zirSizeOf(block, inst), |
| 1019 | 1015 | .bit_size_of => try sema.zirBitSizeOf(block, inst), |
| ... | ... | @@ -1217,7 +1213,7 @@ fn analyzeBodyInner( |
| 1217 | 1213 | i += 1; |
| 1218 | 1214 | continue; |
| 1219 | 1215 | }, |
| 1220 | | .errdefer_err_code => unreachable, // never appears in a body |
| 1216 | .value_placeholder => unreachable, // never appears in a body |
| 1221 | 1217 | }; |
| 1222 | 1218 | }, |
| 1223 | 1219 | |
| ... | ... | @@ -10092,6 +10088,9 @@ const SwitchProngAnalysis = struct { |
| 10092 | 10088 | else_error_ty: ?Type, |
| 10093 | 10089 | /// The index of the `switch_block` instruction itself. |
| 10094 | 10090 | switch_block_inst: Zir.Inst.Index, |
| 10091 | /// The dummy index into which inline tag captures should be placed. May be |
| 10092 | /// undefined if no prong has a tag capture. |
| 10093 | tag_capture_inst: Zir.Inst.Index, |
| 10095 | 10094 | |
| 10096 | 10095 | /// Resolve a switch prong which is determined at comptime to have no peers. |
| 10097 | 10096 | /// Uses `resolveBlockBody`. Sets up captures as needed. |
| ... | ... | @@ -10106,10 +10105,23 @@ const SwitchProngAnalysis = struct { |
| 10106 | 10105 | /// The set of all values which can reach this prong. May be undefined |
| 10107 | 10106 | /// if the prong is special or contains ranges. |
| 10108 | 10107 | case_vals: []const Air.Inst.Ref, |
| 10108 | /// The inline capture of this prong. If this is not an inline prong, |
| 10109 | /// this is `.none`. |
| 10110 | inline_case_capture: Air.Inst.Ref, |
| 10111 | /// Whether this prong has an inline tag capture. If `true`, then |
| 10112 | /// `inline_case_capture` cannot be `.none`. |
| 10113 | has_tag_capture: bool, |
| 10109 | 10114 | merges: *Block.Merges, |
| 10110 | 10115 | ) CompileError!Air.Inst.Ref { |
| 10111 | 10116 | const sema = spa.sema; |
| 10112 | 10117 | const src = sema.code.instructions.items(.data)[spa.switch_block_inst].pl_node.src(); |
| 10118 | |
| 10119 | if (has_tag_capture) { |
| 10120 | const tag_ref = try spa.analyzeTagCapture(child_block, raw_capture_src, inline_case_capture); |
| 10121 | sema.inst_map.putAssumeCapacity(spa.tag_capture_inst, tag_ref); |
| 10122 | } |
| 10123 | defer if (has_tag_capture) assert(sema.inst_map.remove(spa.tag_capture_inst)); |
| 10124 | |
| 10113 | 10125 | switch (capture) { |
| 10114 | 10126 | .none => { |
| 10115 | 10127 | return sema.resolveBlockBody(spa.parent_block, src, child_block, prong_body, spa.switch_block_inst, merges); |
| ... | ... | @@ -10122,6 +10134,7 @@ const SwitchProngAnalysis = struct { |
| 10122 | 10134 | prong_type == .special, |
| 10123 | 10135 | raw_capture_src, |
| 10124 | 10136 | case_vals, |
| 10137 | inline_case_capture, |
| 10125 | 10138 | ); |
| 10126 | 10139 | |
| 10127 | 10140 | if (sema.typeOf(capture_ref).isNoReturn(sema.mod)) { |
| ... | ... | @@ -10150,8 +10163,21 @@ const SwitchProngAnalysis = struct { |
| 10150 | 10163 | /// The set of all values which can reach this prong. May be undefined |
| 10151 | 10164 | /// if the prong is special or contains ranges. |
| 10152 | 10165 | case_vals: []const Air.Inst.Ref, |
| 10166 | /// The inline capture of this prong. If this is not an inline prong, |
| 10167 | /// this is `.none`. |
| 10168 | inline_case_capture: Air.Inst.Ref, |
| 10169 | /// Whether this prong has an inline tag capture. If `true`, then |
| 10170 | /// `inline_case_capture` cannot be `.none`. |
| 10171 | has_tag_capture: bool, |
| 10153 | 10172 | ) CompileError!void { |
| 10154 | 10173 | const sema = spa.sema; |
| 10174 | |
| 10175 | if (has_tag_capture) { |
| 10176 | const tag_ref = try spa.analyzeTagCapture(case_block, raw_capture_src, inline_case_capture); |
| 10177 | sema.inst_map.putAssumeCapacity(spa.tag_capture_inst, tag_ref); |
| 10178 | } |
| 10179 | defer if (has_tag_capture) assert(sema.inst_map.remove(spa.tag_capture_inst)); |
| 10180 | |
| 10155 | 10181 | switch (capture) { |
| 10156 | 10182 | .none => { |
| 10157 | 10183 | return sema.analyzeBodyRuntimeBreak(case_block, prong_body); |
| ... | ... | @@ -10164,6 +10190,7 @@ const SwitchProngAnalysis = struct { |
| 10164 | 10190 | prong_type == .special, |
| 10165 | 10191 | raw_capture_src, |
| 10166 | 10192 | case_vals, |
| 10193 | inline_case_capture, |
| 10167 | 10194 | ); |
| 10168 | 10195 | |
| 10169 | 10196 | if (sema.typeOf(capture_ref).isNoReturn(sema.mod)) { |
| ... | ... | @@ -10179,6 +10206,33 @@ const SwitchProngAnalysis = struct { |
| 10179 | 10206 | } |
| 10180 | 10207 | } |
| 10181 | 10208 | |
| 10209 | fn analyzeTagCapture( |
| 10210 | spa: SwitchProngAnalysis, |
| 10211 | block: *Block, |
| 10212 | raw_capture_src: Module.SwitchProngSrc, |
| 10213 | inline_case_capture: Air.Inst.Ref, |
| 10214 | ) CompileError!Air.Inst.Ref { |
| 10215 | const sema = spa.sema; |
| 10216 | const mod = sema.mod; |
| 10217 | const operand_ty = sema.typeOf(spa.operand); |
| 10218 | if (operand_ty.zigTypeTag(mod) != .Union) { |
| 10219 | const zir_datas = sema.code.instructions.items(.data); |
| 10220 | const switch_node_offset = zir_datas[spa.switch_block_inst].pl_node.src_node; |
| 10221 | const capture_src = raw_capture_src.resolve(mod, mod.declPtr(block.src_decl), switch_node_offset, .none); |
| 10222 | const msg = msg: { |
| 10223 | const msg = try sema.errMsg(block, capture_src, "cannot capture tag of non-union type '{}'", .{ |
| 10224 | operand_ty.fmt(mod), |
| 10225 | }); |
| 10226 | errdefer msg.destroy(sema.gpa); |
| 10227 | try sema.addDeclaredHereNote(msg, operand_ty); |
| 10228 | break :msg msg; |
| 10229 | }; |
| 10230 | return sema.failWithOwnedErrorMsg(msg); |
| 10231 | } |
| 10232 | assert(inline_case_capture != .none); |
| 10233 | return inline_case_capture; |
| 10234 | } |
| 10235 | |
| 10182 | 10236 | fn analyzeCapture( |
| 10183 | 10237 | spa: SwitchProngAnalysis, |
| 10184 | 10238 | block: *Block, |
| ... | ... | @@ -10186,6 +10240,7 @@ const SwitchProngAnalysis = struct { |
| 10186 | 10240 | is_special_prong: bool, |
| 10187 | 10241 | raw_capture_src: Module.SwitchProngSrc, |
| 10188 | 10242 | case_vals: []const Air.Inst.Ref, |
| 10243 | inline_case_capture: Air.Inst.Ref, |
| 10189 | 10244 | ) CompileError!Air.Inst.Ref { |
| 10190 | 10245 | const sema = spa.sema; |
| 10191 | 10246 | const mod = sema.mod; |
| ... | ... | @@ -10197,8 +10252,8 @@ const SwitchProngAnalysis = struct { |
| 10197 | 10252 | const operand_ptr_ty = if (capture_byref) sema.typeOf(spa.operand_ptr) else undefined; |
| 10198 | 10253 | const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = switch_node_offset }; |
| 10199 | 10254 | |
| 10200 | | if (block.inline_case_capture != .none) { |
| 10201 | | const item_val = sema.resolveConstValue(block, .unneeded, block.inline_case_capture, "") catch unreachable; |
| 10255 | if (inline_case_capture != .none) { |
| 10256 | const item_val = sema.resolveConstValue(block, .unneeded, inline_case_capture, "") catch unreachable; |
| 10202 | 10257 | if (operand_ty.zigTypeTag(mod) == .Union) { |
| 10203 | 10258 | const field_index = @intCast(u32, operand_ty.unionTagFieldIndex(item_val, mod).?); |
| 10204 | 10259 | const union_obj = mod.typeToUnion(operand_ty).?; |
| ... | ... | @@ -10233,7 +10288,7 @@ const SwitchProngAnalysis = struct { |
| 10233 | 10288 | } else if (capture_byref) { |
| 10234 | 10289 | return sema.addConstantMaybeRef(block, operand_ty, item_val, true); |
| 10235 | 10290 | } else { |
| 10236 | | return block.inline_case_capture; |
| 10291 | return inline_case_capture; |
| 10237 | 10292 | } |
| 10238 | 10293 | } |
| 10239 | 10294 | |
| ... | ... | @@ -10356,34 +10411,6 @@ const SwitchProngAnalysis = struct { |
| 10356 | 10411 | } |
| 10357 | 10412 | }; |
| 10358 | 10413 | |
| 10359 | | fn zirSwitchCaptureTag(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 10360 | | const mod = sema.mod; |
| 10361 | | const zir_datas = sema.code.instructions.items(.data); |
| 10362 | | const inst_data = zir_datas[inst].un_tok; |
| 10363 | | const src = inst_data.src(); |
| 10364 | | |
| 10365 | | const switch_tag = sema.code.instructions.items(.tag)[Zir.refToIndex(inst_data.operand).?]; |
| 10366 | | const is_ref = switch_tag == .switch_cond_ref; |
| 10367 | | const cond_data = zir_datas[Zir.refToIndex(inst_data.operand).?].un_node; |
| 10368 | | const operand_ptr = try sema.resolveInst(cond_data.operand); |
| 10369 | | const operand_ptr_ty = sema.typeOf(operand_ptr); |
| 10370 | | const operand_ty = if (is_ref) operand_ptr_ty.childType(mod) else operand_ptr_ty; |
| 10371 | | |
| 10372 | | if (operand_ty.zigTypeTag(mod) != .Union) { |
| 10373 | | const msg = msg: { |
| 10374 | | const msg = try sema.errMsg(block, src, "cannot capture tag of non-union type '{}'", .{ |
| 10375 | | operand_ty.fmt(mod), |
| 10376 | | }); |
| 10377 | | errdefer msg.destroy(sema.gpa); |
| 10378 | | try sema.addDeclaredHereNote(msg, operand_ty); |
| 10379 | | break :msg msg; |
| 10380 | | }; |
| 10381 | | return sema.failWithOwnedErrorMsg(msg); |
| 10382 | | } |
| 10383 | | |
| 10384 | | return block.inline_case_capture; |
| 10385 | | } |
| 10386 | | |
| 10387 | 10414 | fn zirSwitchCond( |
| 10388 | 10415 | sema: *Sema, |
| 10389 | 10416 | block: *Block, |
| ... | ... | @@ -10485,6 +10512,16 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10485 | 10512 | break :blk multi_cases_len; |
| 10486 | 10513 | } else 0; |
| 10487 | 10514 | |
| 10515 | const tag_capture_inst: Zir.Inst.Index = if (extra.data.bits.any_has_tag_capture) blk: { |
| 10516 | const tag_capture_inst = sema.code.extra[header_extra_index]; |
| 10517 | header_extra_index += 1; |
| 10518 | // SwitchProngAnalysis wants inst_map to have space for the tag capture. |
| 10519 | // Note that the normal capture is referred to via the switch block |
| 10520 | // index, which there is already necessarily space for. |
| 10521 | try sema.inst_map.ensureSpaceForInstructions(gpa, &.{tag_capture_inst}); |
| 10522 | break :blk tag_capture_inst; |
| 10523 | } else undefined; |
| 10524 | |
| 10488 | 10525 | var case_vals = try std.ArrayListUnmanaged(Air.Inst.Ref).initCapacity(gpa, scalar_cases_len + 2 * multi_cases_len); |
| 10489 | 10526 | defer case_vals.deinit(gpa); |
| 10490 | 10527 | |
| ... | ... | @@ -10493,11 +10530,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10493 | 10530 | end: usize, |
| 10494 | 10531 | capture: Zir.Inst.SwitchBlock.ProngInfo.Capture, |
| 10495 | 10532 | is_inline: bool, |
| 10533 | has_tag_capture: bool, |
| 10496 | 10534 | }; |
| 10497 | 10535 | |
| 10498 | 10536 | const special_prong = extra.data.bits.specialProng(); |
| 10499 | 10537 | const special: Special = switch (special_prong) { |
| 10500 | | .none => .{ .body = &.{}, .end = header_extra_index, .capture = .none, .is_inline = false }, |
| 10538 | .none => .{ |
| 10539 | .body = &.{}, |
| 10540 | .end = header_extra_index, |
| 10541 | .capture = .none, |
| 10542 | .is_inline = false, |
| 10543 | .has_tag_capture = false, |
| 10544 | }, |
| 10501 | 10545 | .under, .@"else" => blk: { |
| 10502 | 10546 | const info = @bitCast(Zir.Inst.SwitchBlock.ProngInfo, sema.code.extra[header_extra_index]); |
| 10503 | 10547 | const extra_body_start = header_extra_index + 1; |
| ... | ... | @@ -10506,6 +10550,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10506 | 10550 | .end = extra_body_start + info.body_len, |
| 10507 | 10551 | .capture = info.capture, |
| 10508 | 10552 | .is_inline = info.is_inline, |
| 10553 | .has_tag_capture = info.has_tag_capture, |
| 10509 | 10554 | }; |
| 10510 | 10555 | }, |
| 10511 | 10556 | }; |
| ... | ... | @@ -11068,6 +11113,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11068 | 11113 | .operand_ptr = raw_operand.ptr, |
| 11069 | 11114 | .else_error_ty = else_error_ty, |
| 11070 | 11115 | .switch_block_inst = inst, |
| 11116 | .tag_capture_inst = tag_capture_inst, |
| 11071 | 11117 | }; |
| 11072 | 11118 | |
| 11073 | 11119 | const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len); |
| ... | ... | @@ -11122,7 +11168,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11122 | 11168 | const item = case_vals.items[scalar_i]; |
| 11123 | 11169 | const item_val = sema.resolveConstValue(&child_block, .unneeded, item, "") catch unreachable; |
| 11124 | 11170 | if (operand_val.eql(item_val, operand_ty, sema.mod)) { |
| 11125 | | if (info.is_inline) child_block.inline_case_capture = operand; |
| 11126 | 11171 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); |
| 11127 | 11172 | return spa.resolveProngComptime( |
| 11128 | 11173 | &child_block, |
| ... | ... | @@ -11131,6 +11176,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11131 | 11176 | info.capture, |
| 11132 | 11177 | .{ .scalar = @intCast(u32, scalar_i) }, |
| 11133 | 11178 | &.{item}, |
| 11179 | if (info.is_inline) operand else .none, |
| 11180 | info.has_tag_capture, |
| 11134 | 11181 | merges, |
| 11135 | 11182 | ); |
| 11136 | 11183 | } |
| ... | ... | @@ -11155,7 +11202,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11155 | 11202 | // Validation above ensured these will succeed. |
| 11156 | 11203 | const item_val = sema.resolveConstValue(&child_block, .unneeded, item, "") catch unreachable; |
| 11157 | 11204 | if (operand_val.eql(item_val, operand_ty, sema.mod)) { |
| 11158 | | if (info.is_inline) child_block.inline_case_capture = operand; |
| 11159 | 11205 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); |
| 11160 | 11206 | return spa.resolveProngComptime( |
| 11161 | 11207 | &child_block, |
| ... | ... | @@ -11164,6 +11210,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11164 | 11210 | info.capture, |
| 11165 | 11211 | .{ .multi_capture = @intCast(u32, multi_i) }, |
| 11166 | 11212 | items, |
| 11213 | if (info.is_inline) operand else .none, |
| 11214 | info.has_tag_capture, |
| 11167 | 11215 | merges, |
| 11168 | 11216 | ); |
| 11169 | 11217 | } |
| ... | ... | @@ -11181,7 +11229,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11181 | 11229 | if ((try sema.compareAll(resolved_operand_val, .gte, first_val, operand_ty)) and |
| 11182 | 11230 | (try sema.compareAll(resolved_operand_val, .lte, last_val, operand_ty))) |
| 11183 | 11231 | { |
| 11184 | | if (info.is_inline) child_block.inline_case_capture = operand; |
| 11185 | 11232 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); |
| 11186 | 11233 | return spa.resolveProngComptime( |
| 11187 | 11234 | &child_block, |
| ... | ... | @@ -11190,6 +11237,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11190 | 11237 | info.capture, |
| 11191 | 11238 | .{ .multi_capture = @intCast(u32, multi_i) }, |
| 11192 | 11239 | undefined, // case_vals may be undefined for ranges |
| 11240 | if (info.is_inline) operand else .none, |
| 11241 | info.has_tag_capture, |
| 11193 | 11242 | merges, |
| 11194 | 11243 | ); |
| 11195 | 11244 | } |
| ... | ... | @@ -11199,7 +11248,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11199 | 11248 | } |
| 11200 | 11249 | } |
| 11201 | 11250 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, special.body, operand); |
| 11202 | | if (special.is_inline) child_block.inline_case_capture = operand; |
| 11203 | 11251 | if (empty_enum) { |
| 11204 | 11252 | return Air.Inst.Ref.void_value; |
| 11205 | 11253 | } |
| ... | ... | @@ -11211,6 +11259,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11211 | 11259 | special.capture, |
| 11212 | 11260 | .special, |
| 11213 | 11261 | undefined, // case_vals may be undefined for special prongs |
| 11262 | if (special.is_inline) operand else .none, |
| 11263 | special.has_tag_capture, |
| 11214 | 11264 | merges, |
| 11215 | 11265 | ); |
| 11216 | 11266 | } |
| ... | ... | @@ -11240,6 +11290,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11240 | 11290 | special.capture, |
| 11241 | 11291 | .special, |
| 11242 | 11292 | undefined, // case_vals may be undefined for special prongs |
| 11293 | .none, |
| 11294 | false, |
| 11243 | 11295 | merges, |
| 11244 | 11296 | ); |
| 11245 | 11297 | } |
| ... | ... | @@ -11278,10 +11330,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11278 | 11330 | |
| 11279 | 11331 | case_block.instructions.shrinkRetainingCapacity(0); |
| 11280 | 11332 | case_block.wip_capture_scope = wip_captures.scope; |
| 11281 | | case_block.inline_case_capture = .none; |
| 11282 | 11333 | |
| 11283 | 11334 | const item = case_vals.items[scalar_i]; |
| 11284 | | if (info.is_inline) case_block.inline_case_capture = item; |
| 11285 | 11335 | // `item` is already guaranteed to be constant known. |
| 11286 | 11336 | |
| 11287 | 11337 | const analyze_body = if (union_originally) blk: { |
| ... | ... | @@ -11300,6 +11350,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11300 | 11350 | info.capture, |
| 11301 | 11351 | .{ .scalar = @intCast(u32, scalar_i) }, |
| 11302 | 11352 | &.{item}, |
| 11353 | if (info.is_inline) item else .none, |
| 11354 | info.has_tag_capture, |
| 11303 | 11355 | ); |
| 11304 | 11356 | } else { |
| 11305 | 11357 | _ = try case_block.addNoOp(.unreach); |
| ... | ... | @@ -11337,7 +11389,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11337 | 11389 | |
| 11338 | 11390 | case_block.instructions.shrinkRetainingCapacity(0); |
| 11339 | 11391 | case_block.wip_capture_scope = child_block.wip_capture_scope; |
| 11340 | | case_block.inline_case_capture = .none; |
| 11341 | 11392 | |
| 11342 | 11393 | // Generate all possible cases as scalar prongs. |
| 11343 | 11394 | if (info.is_inline) { |
| ... | ... | @@ -11367,7 +11418,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11367 | 11418 | cases_len += 1; |
| 11368 | 11419 | |
| 11369 | 11420 | const item_ref = try sema.addConstant(operand_ty, item); |
| 11370 | | case_block.inline_case_capture = item_ref; |
| 11371 | 11421 | |
| 11372 | 11422 | case_block.instructions.shrinkRetainingCapacity(0); |
| 11373 | 11423 | case_block.wip_capture_scope = child_block.wip_capture_scope; |
| ... | ... | @@ -11390,12 +11440,14 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11390 | 11440 | info.capture, |
| 11391 | 11441 | .{ .multi_capture = multi_i }, |
| 11392 | 11442 | undefined, // case_vals may be undefined for ranges |
| 11443 | item_ref, |
| 11444 | info.has_tag_capture, |
| 11393 | 11445 | ); |
| 11394 | 11446 | |
| 11395 | 11447 | try cases_extra.ensureUnusedCapacity(gpa, 3 + case_block.instructions.items.len); |
| 11396 | 11448 | cases_extra.appendAssumeCapacity(1); // items_len |
| 11397 | 11449 | cases_extra.appendAssumeCapacity(@intCast(u32, case_block.instructions.items.len)); |
| 11398 | | cases_extra.appendAssumeCapacity(@enumToInt(case_block.inline_case_capture)); |
| 11450 | cases_extra.appendAssumeCapacity(@enumToInt(item_ref)); |
| 11399 | 11451 | cases_extra.appendSliceAssumeCapacity(case_block.instructions.items); |
| 11400 | 11452 | } |
| 11401 | 11453 | } |
| ... | ... | @@ -11403,8 +11455,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11403 | 11455 | for (items, 0..) |item, item_i| { |
| 11404 | 11456 | cases_len += 1; |
| 11405 | 11457 | |
| 11406 | | case_block.inline_case_capture = item; |
| 11407 | | |
| 11408 | 11458 | case_block.instructions.shrinkRetainingCapacity(0); |
| 11409 | 11459 | case_block.wip_capture_scope = child_block.wip_capture_scope; |
| 11410 | 11460 | |
| ... | ... | @@ -11433,6 +11483,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11433 | 11483 | info.capture, |
| 11434 | 11484 | .{ .multi_capture = multi_i }, |
| 11435 | 11485 | &.{item}, |
| 11486 | item, |
| 11487 | info.has_tag_capture, |
| 11436 | 11488 | ); |
| 11437 | 11489 | } else { |
| 11438 | 11490 | _ = try case_block.addNoOp(.unreach); |
| ... | ... | @@ -11441,7 +11493,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11441 | 11493 | try cases_extra.ensureUnusedCapacity(gpa, 3 + case_block.instructions.items.len); |
| 11442 | 11494 | cases_extra.appendAssumeCapacity(1); // items_len |
| 11443 | 11495 | cases_extra.appendAssumeCapacity(@intCast(u32, case_block.instructions.items.len)); |
| 11444 | | cases_extra.appendAssumeCapacity(@enumToInt(case_block.inline_case_capture)); |
| 11496 | cases_extra.appendAssumeCapacity(@enumToInt(item)); |
| 11445 | 11497 | cases_extra.appendSliceAssumeCapacity(case_block.instructions.items); |
| 11446 | 11498 | } |
| 11447 | 11499 | |
| ... | ... | @@ -11478,6 +11530,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11478 | 11530 | info.capture, |
| 11479 | 11531 | .{ .multi_capture = multi_i }, |
| 11480 | 11532 | items, |
| 11533 | .none, |
| 11534 | false, |
| 11481 | 11535 | ); |
| 11482 | 11536 | } else { |
| 11483 | 11537 | _ = try case_block.addNoOp(.unreach); |
| ... | ... | @@ -11563,6 +11617,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11563 | 11617 | info.capture, |
| 11564 | 11618 | .{ .multi_capture = multi_i }, |
| 11565 | 11619 | items, |
| 11620 | .none, |
| 11621 | false, |
| 11566 | 11622 | ); |
| 11567 | 11623 | } |
| 11568 | 11624 | |
| ... | ... | @@ -11608,7 +11664,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11608 | 11664 | |
| 11609 | 11665 | const item_val = try mod.enumValueFieldIndex(operand_ty, @intCast(u32, i)); |
| 11610 | 11666 | const item_ref = try sema.addConstant(operand_ty, item_val); |
| 11611 | | case_block.inline_case_capture = item_ref; |
| 11612 | 11667 | |
| 11613 | 11668 | case_block.instructions.shrinkRetainingCapacity(0); |
| 11614 | 11669 | case_block.wip_capture_scope = child_block.wip_capture_scope; |
| ... | ... | @@ -11629,6 +11684,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11629 | 11684 | special.capture, |
| 11630 | 11685 | .special, |
| 11631 | 11686 | &.{item_ref}, |
| 11687 | item_ref, |
| 11688 | special.has_tag_capture, |
| 11632 | 11689 | ); |
| 11633 | 11690 | } else { |
| 11634 | 11691 | _ = try case_block.addNoOp(.unreach); |
| ... | ... | @@ -11637,7 +11694,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11637 | 11694 | try cases_extra.ensureUnusedCapacity(gpa, 3 + case_block.instructions.items.len); |
| 11638 | 11695 | cases_extra.appendAssumeCapacity(1); // items_len |
| 11639 | 11696 | cases_extra.appendAssumeCapacity(@intCast(u32, case_block.instructions.items.len)); |
| 11640 | | cases_extra.appendAssumeCapacity(@enumToInt(case_block.inline_case_capture)); |
| 11697 | cases_extra.appendAssumeCapacity(@enumToInt(item_ref)); |
| 11641 | 11698 | cases_extra.appendSliceAssumeCapacity(case_block.instructions.items); |
| 11642 | 11699 | } |
| 11643 | 11700 | }, |
| ... | ... | @@ -11657,7 +11714,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11657 | 11714 | .name = error_name, |
| 11658 | 11715 | } }); |
| 11659 | 11716 | const item_ref = try sema.addConstant(operand_ty, item_val.toValue()); |
| 11660 | | case_block.inline_case_capture = item_ref; |
| 11661 | 11717 | |
| 11662 | 11718 | case_block.instructions.shrinkRetainingCapacity(0); |
| 11663 | 11719 | case_block.wip_capture_scope = child_block.wip_capture_scope; |
| ... | ... | @@ -11672,12 +11728,14 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11672 | 11728 | special.capture, |
| 11673 | 11729 | .special, |
| 11674 | 11730 | &.{item_ref}, |
| 11731 | item_ref, |
| 11732 | special.has_tag_capture, |
| 11675 | 11733 | ); |
| 11676 | 11734 | |
| 11677 | 11735 | try cases_extra.ensureUnusedCapacity(gpa, 3 + case_block.instructions.items.len); |
| 11678 | 11736 | cases_extra.appendAssumeCapacity(1); // items_len |
| 11679 | 11737 | cases_extra.appendAssumeCapacity(@intCast(u32, case_block.instructions.items.len)); |
| 11680 | | cases_extra.appendAssumeCapacity(@enumToInt(case_block.inline_case_capture)); |
| 11738 | cases_extra.appendAssumeCapacity(@enumToInt(item_ref)); |
| 11681 | 11739 | cases_extra.appendSliceAssumeCapacity(case_block.instructions.items); |
| 11682 | 11740 | } |
| 11683 | 11741 | }, |
| ... | ... | @@ -11687,7 +11745,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11687 | 11745 | cases_len += 1; |
| 11688 | 11746 | |
| 11689 | 11747 | const item_ref = try sema.addConstant(operand_ty, cur.toValue()); |
| 11690 | | case_block.inline_case_capture = item_ref; |
| 11691 | 11748 | |
| 11692 | 11749 | case_block.instructions.shrinkRetainingCapacity(0); |
| 11693 | 11750 | case_block.wip_capture_scope = child_block.wip_capture_scope; |
| ... | ... | @@ -11702,19 +11759,20 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11702 | 11759 | special.capture, |
| 11703 | 11760 | .special, |
| 11704 | 11761 | &.{item_ref}, |
| 11762 | item_ref, |
| 11763 | special.has_tag_capture, |
| 11705 | 11764 | ); |
| 11706 | 11765 | |
| 11707 | 11766 | try cases_extra.ensureUnusedCapacity(gpa, 3 + case_block.instructions.items.len); |
| 11708 | 11767 | cases_extra.appendAssumeCapacity(1); // items_len |
| 11709 | 11768 | cases_extra.appendAssumeCapacity(@intCast(u32, case_block.instructions.items.len)); |
| 11710 | | cases_extra.appendAssumeCapacity(@enumToInt(case_block.inline_case_capture)); |
| 11769 | cases_extra.appendAssumeCapacity(@enumToInt(item_ref)); |
| 11711 | 11770 | cases_extra.appendSliceAssumeCapacity(case_block.instructions.items); |
| 11712 | 11771 | } |
| 11713 | 11772 | }, |
| 11714 | 11773 | .Bool => { |
| 11715 | 11774 | if (true_count == 0) { |
| 11716 | 11775 | cases_len += 1; |
| 11717 | | case_block.inline_case_capture = Air.Inst.Ref.bool_true; |
| 11718 | 11776 | |
| 11719 | 11777 | case_block.instructions.shrinkRetainingCapacity(0); |
| 11720 | 11778 | case_block.wip_capture_scope = child_block.wip_capture_scope; |
| ... | ... | @@ -11729,17 +11787,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11729 | 11787 | special.capture, |
| 11730 | 11788 | .special, |
| 11731 | 11789 | &.{Air.Inst.Ref.bool_true}, |
| 11790 | Air.Inst.Ref.bool_true, |
| 11791 | special.has_tag_capture, |
| 11732 | 11792 | ); |
| 11733 | 11793 | |
| 11734 | 11794 | try cases_extra.ensureUnusedCapacity(gpa, 3 + case_block.instructions.items.len); |
| 11735 | 11795 | cases_extra.appendAssumeCapacity(1); // items_len |
| 11736 | 11796 | cases_extra.appendAssumeCapacity(@intCast(u32, case_block.instructions.items.len)); |
| 11737 | | cases_extra.appendAssumeCapacity(@enumToInt(case_block.inline_case_capture)); |
| 11797 | cases_extra.appendAssumeCapacity(@enumToInt(Air.Inst.Ref.bool_true)); |
| 11738 | 11798 | cases_extra.appendSliceAssumeCapacity(case_block.instructions.items); |
| 11739 | 11799 | } |
| 11740 | 11800 | if (false_count == 0) { |
| 11741 | 11801 | cases_len += 1; |
| 11742 | | case_block.inline_case_capture = Air.Inst.Ref.bool_false; |
| 11743 | 11802 | |
| 11744 | 11803 | case_block.instructions.shrinkRetainingCapacity(0); |
| 11745 | 11804 | case_block.wip_capture_scope = child_block.wip_capture_scope; |
| ... | ... | @@ -11754,12 +11813,14 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11754 | 11813 | special.capture, |
| 11755 | 11814 | .special, |
| 11756 | 11815 | &.{Air.Inst.Ref.bool_false}, |
| 11816 | Air.Inst.Ref.bool_false, |
| 11817 | special.has_tag_capture, |
| 11757 | 11818 | ); |
| 11758 | 11819 | |
| 11759 | 11820 | try cases_extra.ensureUnusedCapacity(gpa, 3 + case_block.instructions.items.len); |
| 11760 | 11821 | cases_extra.appendAssumeCapacity(1); // items_len |
| 11761 | 11822 | cases_extra.appendAssumeCapacity(@intCast(u32, case_block.instructions.items.len)); |
| 11762 | | cases_extra.appendAssumeCapacity(@enumToInt(case_block.inline_case_capture)); |
| 11823 | cases_extra.appendAssumeCapacity(@enumToInt(Air.Inst.Ref.bool_false)); |
| 11763 | 11824 | cases_extra.appendSliceAssumeCapacity(case_block.instructions.items); |
| 11764 | 11825 | } |
| 11765 | 11826 | }, |
| ... | ... | @@ -11773,7 +11834,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11773 | 11834 | |
| 11774 | 11835 | case_block.instructions.shrinkRetainingCapacity(0); |
| 11775 | 11836 | case_block.wip_capture_scope = wip_captures.scope; |
| 11776 | | case_block.inline_case_capture = .none; |
| 11777 | 11837 | |
| 11778 | 11838 | if (mod.backendSupportsFeature(.is_named_enum_value) and special.body.len != 0 and block.wantSafety() and |
| 11779 | 11839 | operand_ty.zigTypeTag(mod) == .Enum and (!operand_ty.isNonexhaustiveEnum(mod) or union_originally)) |
| ... | ... | @@ -11804,6 +11864,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11804 | 11864 | special.capture, |
| 11805 | 11865 | .special, |
| 11806 | 11866 | undefined, // case_vals may be undefined for special prongs |
| 11867 | .none, |
| 11868 | false, |
| 11807 | 11869 | ); |
| 11808 | 11870 | } else { |
| 11809 | 11871 | // We still need a terminator in this block, but we have proven |