| ... | @@ -277,9 +277,6 @@ pub const Block = struct { | ... | @@ -277,9 +277,6 @@ pub const Block = struct { |
| 277 | | 277 | |
| 278 | c_import_buf: ?*std.ArrayList(u8) = null, | 278 | c_import_buf: ?*std.ArrayList(u8) = null, |
| 279 | | 279 | |
| 280 | /// type of `err` in `else => |err|` | | |
| 281 | switch_else_err_ty: ?Type = null, | | |
| 282 | | | |
| 283 | /// Value for switch_capture in an inline case | 280 | /// Value for switch_capture in an inline case |
| 284 | inline_case_capture: Air.Inst.Ref = .none, | 281 | inline_case_capture: Air.Inst.Ref = .none, |
| 285 | | 282 | |
| ... | @@ -397,7 +394,6 @@ pub const Block = struct { | ... | @@ -397,7 +394,6 @@ pub const Block = struct { |
| 397 | .want_safety = parent.want_safety, | 394 | .want_safety = parent.want_safety, |
| 398 | .float_mode = parent.float_mode, | 395 | .float_mode = parent.float_mode, |
| 399 | .c_import_buf = parent.c_import_buf, | 396 | .c_import_buf = parent.c_import_buf, |
| 400 | .switch_else_err_ty = parent.switch_else_err_ty, | | |
| 401 | .error_return_trace_index = parent.error_return_trace_index, | 397 | .error_return_trace_index = parent.error_return_trace_index, |
| 402 | }; | 398 | }; |
| 403 | } | 399 | } |
| ... | @@ -1017,8 +1013,6 @@ fn analyzeBodyInner( | ... | @@ -1017,8 +1013,6 @@ fn analyzeBodyInner( |
| 1017 | .switch_block => try sema.zirSwitchBlock(block, inst), | 1013 | .switch_block => try sema.zirSwitchBlock(block, inst), |
| 1018 | .switch_cond => try sema.zirSwitchCond(block, inst, false), | 1014 | .switch_cond => try sema.zirSwitchCond(block, inst, false), |
| 1019 | .switch_cond_ref => try sema.zirSwitchCond(block, inst, true), | 1015 | .switch_cond_ref => try sema.zirSwitchCond(block, inst, true), |
| 1020 | .switch_capture => try sema.zirSwitchCapture(block, inst, false), | | |
| 1021 | .switch_capture_ref => try sema.zirSwitchCapture(block, inst, true), | | |
| 1022 | .switch_capture_tag => try sema.zirSwitchCaptureTag(block, inst), | 1016 | .switch_capture_tag => try sema.zirSwitchCaptureTag(block, inst), |
| 1023 | .type_info => try sema.zirTypeInfo(block, inst), | 1017 | .type_info => try sema.zirTypeInfo(block, inst), |
| 1024 | .size_of => try sema.zirSizeOf(block, inst), | 1018 | .size_of => try sema.zirSizeOf(block, inst), |
| ... | @@ -10083,61 +10077,160 @@ fn zirSliceLength(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10083,61 +10077,160 @@ fn zirSliceLength(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10083 | return sema.analyzeSlice(block, src, array_ptr, start, len, sentinel, sentinel_src, ptr_src, start_src, end_src, true); | 10077 | return sema.analyzeSlice(block, src, array_ptr, start, len, sentinel, sentinel_src, ptr_src, start_src, end_src, true); |
| 10084 | } | 10078 | } |
| 10085 | | 10079 | |
| 10086 | fn zirSwitchCapture( | 10080 | /// Resolve a switch prong which is determined at comptime to have no peers. Uses |
| | 10081 | /// `resolveBlockBody`. Sets up captures as needed. |
| | 10082 | fn resolveSwitchProngComptime( |
| 10087 | sema: *Sema, | 10083 | sema: *Sema, |
| 10088 | block: *Block, | 10084 | parent_block: *Block, |
| 10089 | inst: Zir.Inst.Index, | 10085 | child_block: *Block, |
| 10090 | is_ref: bool, | 10086 | src: LazySrcLoc, |
| | 10087 | operand: Air.Inst.Ref, |
| | 10088 | operand_ptr: Air.Inst.Ref, |
| | 10089 | prong_type: enum { normal, special }, |
| | 10090 | prong_body: []const Zir.Inst.Index, |
| | 10091 | capture: Zir.Inst.SwitchBlock.ProngInfo.Capture, |
| | 10092 | raw_capture_src: Module.SwitchProngSrc, |
| | 10093 | else_error_ty: ?Type, |
| | 10094 | case_vals: []const Air.Inst.Ref, |
| | 10095 | switch_block_inst: Zir.Inst.Index, |
| | 10096 | merges: *Block.Merges, |
| 10091 | ) CompileError!Air.Inst.Ref { | 10097 | ) CompileError!Air.Inst.Ref { |
| 10092 | const tracy = trace(@src()); | 10098 | switch (capture) { |
| 10093 | defer tracy.end(); | 10099 | .none => { |
| | 10100 | return sema.resolveBlockBody(parent_block, src, child_block, prong_body, switch_block_inst, merges); |
| | 10101 | }, |
| | 10102 | |
| | 10103 | .by_val, .by_ref => { |
| | 10104 | const zir_datas = sema.code.instructions.items(.data); |
| | 10105 | const switch_info = zir_datas[switch_block_inst].pl_node; |
| | 10106 | |
| | 10107 | const capture_ref = try sema.analyzeSwitchCapture( |
| | 10108 | child_block, |
| | 10109 | capture == .by_ref, |
| | 10110 | operand, |
| | 10111 | operand_ptr, |
| | 10112 | switch_info.src_node, |
| | 10113 | prong_type == .special, |
| | 10114 | raw_capture_src, |
| | 10115 | else_error_ty, |
| | 10116 | case_vals, |
| | 10117 | ); |
| | 10118 | |
| | 10119 | if (sema.typeOf(capture_ref).isNoReturn(sema.mod)) { |
| | 10120 | // This prong should be unreachable! |
| | 10121 | return Air.Inst.Ref.unreachable_value; |
| | 10122 | } |
| | 10123 | |
| | 10124 | sema.inst_map.putAssumeCapacity(switch_block_inst, capture_ref); |
| | 10125 | defer assert(sema.inst_map.remove(switch_block_inst)); |
| | 10126 | |
| | 10127 | return sema.resolveBlockBody(parent_block, src, child_block, prong_body, switch_block_inst, merges); |
| | 10128 | }, |
| | 10129 | } |
| | 10130 | } |
| | 10131 | |
| | 10132 | /// Analyze a switch prong which may have peers at runtime. Uses |
| | 10133 | /// `analyzeBodyRuntimeBreak`. Sets up captures as needed. |
| | 10134 | fn analyzeSwitchProngRuntime( |
| | 10135 | sema: *Sema, |
| | 10136 | case_block: *Block, |
| | 10137 | operand: Air.Inst.Ref, |
| | 10138 | operand_ptr: Air.Inst.Ref, |
| | 10139 | prong_type: enum { normal, special }, |
| | 10140 | prong_body: []const Zir.Inst.Index, |
| | 10141 | capture: Zir.Inst.SwitchBlock.ProngInfo.Capture, |
| | 10142 | raw_capture_src: Module.SwitchProngSrc, |
| | 10143 | else_error_ty: ?Type, |
| | 10144 | case_vals: []const Air.Inst.Ref, |
| | 10145 | switch_block_inst: Zir.Inst.Index, |
| | 10146 | ) CompileError!void { |
| | 10147 | switch (capture) { |
| | 10148 | .none => { |
| | 10149 | return sema.analyzeBodyRuntimeBreak(case_block, prong_body); |
| | 10150 | }, |
| | 10151 | |
| | 10152 | .by_val, .by_ref => { |
| | 10153 | const zir_datas = sema.code.instructions.items(.data); |
| | 10154 | const switch_info = zir_datas[switch_block_inst].pl_node; |
| | 10155 | |
| | 10156 | const capture_ref = try sema.analyzeSwitchCapture( |
| | 10157 | case_block, |
| | 10158 | capture == .by_ref, |
| | 10159 | operand, |
| | 10160 | operand_ptr, |
| | 10161 | switch_info.src_node, |
| | 10162 | prong_type == .special, |
| | 10163 | raw_capture_src, |
| | 10164 | else_error_ty, |
| | 10165 | case_vals, |
| | 10166 | ); |
| 10094 | | 10167 | |
| | 10168 | if (sema.typeOf(capture_ref).isNoReturn(sema.mod)) { |
| | 10169 | // No need to analyze any further, the prong is unreachable |
| | 10170 | return; |
| | 10171 | } |
| | 10172 | |
| | 10173 | sema.inst_map.putAssumeCapacity(switch_block_inst, capture_ref); |
| | 10174 | defer assert(sema.inst_map.remove(switch_block_inst)); |
| | 10175 | |
| | 10176 | return sema.analyzeBodyRuntimeBreak(case_block, prong_body); |
| | 10177 | }, |
| | 10178 | } |
| | 10179 | } |
| | 10180 | |
| | 10181 | fn analyzeSwitchCapture( |
| | 10182 | sema: *Sema, |
| | 10183 | /// Must be the child block so that `inline_case_capture` is set for inline prongs. |
| | 10184 | block: *Block, |
| | 10185 | capture_byref: bool, |
| | 10186 | /// The raw switch operand value. |
| | 10187 | operand: Air.Inst.Ref, |
| | 10188 | /// Pointer to the raw switch operand. May be undefined if `capture_byref` is false. |
| | 10189 | operand_ptr: Air.Inst.Ref, |
| | 10190 | switch_node_offset: i32, |
| | 10191 | /// `true` if this is the `else` or `_` prong of a switch. |
| | 10192 | is_special_prong: bool, |
| | 10193 | /// Must use the `scalar`, `special`, or `multi_capture` union field. |
| | 10194 | raw_capture_src: Module.SwitchProngSrc, |
| | 10195 | /// If this is the `else` prong of a switch on an error set, this is the |
| | 10196 | /// type that should be assigned to the capture. If `null`, the prong should |
| | 10197 | /// be unreachable. |
| | 10198 | else_error_ty: ?Type, |
| | 10199 | /// The set of all values which can reach this prong. May be undefined if |
| | 10200 | /// the prong has `is_special_prong` or contains ranges. |
| | 10201 | case_vals: []const Air.Inst.Ref, |
| | 10202 | ) CompileError!Air.Inst.Ref { |
| 10095 | const mod = sema.mod; | 10203 | const mod = sema.mod; |
| 10096 | const gpa = sema.gpa; | 10204 | const gpa = sema.gpa; |
| 10097 | const zir_datas = sema.code.instructions.items(.data); | 10205 | const operand_ty = sema.typeOf(operand); |
| 10098 | const capture_info = zir_datas[inst].switch_capture; | 10206 | const operand_ptr_ty = if (capture_byref) sema.typeOf(operand_ptr) else undefined; |
| 10099 | const switch_info = zir_datas[capture_info.switch_inst].pl_node; | 10207 | const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = switch_node_offset }; |
| 10100 | const switch_extra = sema.code.extraData(Zir.Inst.SwitchBlock, switch_info.payload_index); | | |
| 10101 | const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = switch_info.src_node }; | | |
| 10102 | const cond = try sema.resolveInst(switch_extra.data.operand); | | |
| 10103 | const cond_ty = sema.typeOf(cond); | | |
| 10104 | const cond_inst = Zir.refToIndex(switch_extra.data.operand).?; | | |
| 10105 | const cond_info = zir_datas[cond_inst].un_node; | | |
| 10106 | const cond_tag = sema.code.instructions.items(.tag)[cond_inst]; | | |
| 10107 | const operand_is_ref = cond_tag == .switch_cond_ref; | | |
| 10108 | const operand_ptr = try sema.resolveInst(cond_info.operand); | | |
| 10109 | const operand_ptr_ty = sema.typeOf(operand_ptr); | | |
| 10110 | const operand_ty = if (operand_is_ref) operand_ptr_ty.childType(mod) else operand_ptr_ty; | | |
| 10111 | | 10208 | |
| 10112 | if (block.inline_case_capture != .none) { | 10209 | if (block.inline_case_capture != .none) { |
| 10113 | const item_val = sema.resolveConstValue(block, .unneeded, block.inline_case_capture, undefined) catch unreachable; | 10210 | const item_val = sema.resolveConstValue(block, .unneeded, block.inline_case_capture, "") catch unreachable; |
| 10114 | const resolved_item_val = try sema.resolveLazyValue(item_val); | | |
| 10115 | if (operand_ty.zigTypeTag(mod) == .Union) { | 10211 | if (operand_ty.zigTypeTag(mod) == .Union) { |
| 10116 | const field_index = @intCast(u32, operand_ty.unionTagFieldIndex(resolved_item_val, mod).?); | 10212 | const field_index = @intCast(u32, operand_ty.unionTagFieldIndex(item_val, mod).?); |
| 10117 | const union_obj = mod.typeToUnion(operand_ty).?; | 10213 | const union_obj = mod.typeToUnion(operand_ty).?; |
| 10118 | const field_ty = union_obj.fields.values()[field_index].ty; | 10214 | const field_ty = union_obj.fields.values()[field_index].ty; |
| 10119 | if (try sema.resolveDefinedValue(block, sema.src, operand_ptr)) |union_val| { | 10215 | if (capture_byref) { |
| 10120 | if (is_ref) { | 10216 | if (try sema.resolveDefinedValue(block, sema.src, operand_ptr)) |union_ptr| { |
| 10121 | const ptr_field_ty = try Type.ptr(sema.arena, mod, .{ | 10217 | const ptr_field_ty = try Type.ptr(sema.arena, mod, .{ |
| 10122 | .pointee_type = field_ty, | 10218 | .pointee_type = field_ty, |
| 10123 | .mutable = operand_ptr_ty.ptrIsMutable(mod), | 10219 | .mutable = operand_ptr_ty.ptrIsMutable(mod), |
| 10124 | .@"volatile" = operand_ptr_ty.isVolatilePtr(mod), | 10220 | .@"volatile" = operand_ptr_ty.isVolatilePtr(mod), |
| 10125 | .@"addrspace" = operand_ptr_ty.ptrAddressSpace(mod), | 10221 | .@"addrspace" = operand_ptr_ty.ptrAddressSpace(mod), |
| 10126 | }); | 10222 | }); |
| 10127 | return sema.addConstant(ptr_field_ty, (try mod.intern(.{ .ptr = .{ | 10223 | return sema.addConstant( |
| 10128 | .ty = ptr_field_ty.toIntern(), | 10224 | ptr_field_ty, |
| 10129 | .addr = .{ .field = .{ | 10225 | (try mod.intern(.{ .ptr = .{ |
| 10130 | .base = union_val.toIntern(), | 10226 | .ty = ptr_field_ty.toIntern(), |
| 10131 | .index = field_index, | 10227 | .addr = .{ .field = .{ |
| 10132 | } }, | 10228 | .base = union_ptr.toIntern(), |
| 10133 | } })).toValue()); | 10229 | .index = field_index, |
| | 10230 | } }, |
| | 10231 | } })).toValue(), |
| | 10232 | ); |
| 10134 | } | 10233 | } |
| 10135 | return sema.addConstant( | | |
| 10136 | field_ty, | | |
| 10137 | mod.intern_pool.indexToKey(union_val.toIntern()).un.val.toValue(), | | |
| 10138 | ); | | |
| 10139 | } | | |
| 10140 | if (is_ref) { | | |
| 10141 | const ptr_field_ty = try Type.ptr(sema.arena, mod, .{ | 10234 | const ptr_field_ty = try Type.ptr(sema.arena, mod, .{ |
| 10142 | .pointee_type = field_ty, | 10235 | .pointee_type = field_ty, |
| 10143 | .mutable = operand_ptr_ty.ptrIsMutable(mod), | 10236 | .mutable = operand_ptr_ty.ptrIsMutable(mod), |
| ... | @@ -10146,29 +10239,27 @@ fn zirSwitchCapture( | ... | @@ -10146,29 +10239,27 @@ fn zirSwitchCapture( |
| 10146 | }); | 10239 | }); |
| 10147 | return block.addStructFieldPtr(operand_ptr, field_index, ptr_field_ty); | 10240 | return block.addStructFieldPtr(operand_ptr, field_index, ptr_field_ty); |
| 10148 | } else { | 10241 | } else { |
| 10149 | return block.addStructFieldVal(operand_ptr, field_index, field_ty); | 10242 | if (try sema.resolveDefinedValue(block, sema.src, operand)) |union_val| { |
| | 10243 | const tag_and_val = mod.intern_pool.indexToKey(union_val.toIntern()).un; |
| | 10244 | return sema.addConstant(field_ty, tag_and_val.val.toValue()); |
| | 10245 | } |
| | 10246 | return block.addStructFieldVal(operand, field_index, field_ty); |
| 10150 | } | 10247 | } |
| 10151 | } else if (is_ref) { | 10248 | } else if (capture_byref) { |
| 10152 | return sema.addConstantMaybeRef(block, operand_ty, resolved_item_val, true); | 10249 | return sema.addConstantMaybeRef(block, operand_ty, item_val, true); |
| 10153 | } else { | 10250 | } else { |
| 10154 | return block.inline_case_capture; | 10251 | return block.inline_case_capture; |
| 10155 | } | 10252 | } |
| 10156 | } | 10253 | } |
| 10157 | | 10254 | |
| 10158 | const operand = if (operand_is_ref) | 10255 | if (is_special_prong) { |
| 10159 | try sema.analyzeLoad(block, operand_src, operand_ptr, operand_src) | 10256 | if (capture_byref) { |
| 10160 | else | | |
| 10161 | operand_ptr; | | |
| 10162 | | | |
| 10163 | if (capture_info.prong_index == std.math.maxInt(@TypeOf(capture_info.prong_index))) { | | |
| 10164 | // It is the else/`_` prong. | | |
| 10165 | if (is_ref) { | | |
| 10166 | return operand_ptr; | 10257 | return operand_ptr; |
| 10167 | } | 10258 | } |
| 10168 | | 10259 | |
| 10169 | switch (operand_ty.zigTypeTag(mod)) { | 10260 | switch (operand_ty.zigTypeTag(mod)) { |
| 10170 | .ErrorSet => if (block.switch_else_err_ty) |some| { | 10261 | .ErrorSet => if (else_error_ty) |ty| { |
| 10171 | return sema.bitCast(block, some, operand, operand_src, null); | 10262 | return sema.bitCast(block, ty, operand, operand_src, null); |
| 10172 | } else { | 10263 | } else { |
| 10173 | try block.addUnreachable(false); | 10264 | try block.addUnreachable(false); |
| 10174 | return Air.Inst.Ref.unreachable_value; | 10265 | return Air.Inst.Ref.unreachable_value; |
| ... | @@ -10177,41 +10268,33 @@ fn zirSwitchCapture( | ... | @@ -10177,41 +10268,33 @@ fn zirSwitchCapture( |
| 10177 | } | 10268 | } |
| 10178 | } | 10269 | } |
| 10179 | | 10270 | |
| 10180 | // Note that these are the *uncasted* prong items. | | |
| 10181 | // Also note that items from ranges are not included so this only works for non-ranged types. | | |
| 10182 | const items = switch_extra.data.getProng(sema.code, switch_extra.end, capture_info.prong_index).items; | | |
| 10183 | | | |
| 10184 | switch (operand_ty.zigTypeTag(mod)) { | 10271 | switch (operand_ty.zigTypeTag(mod)) { |
| 10185 | .Union => { | 10272 | .Union => { |
| 10186 | const union_obj = mod.typeToUnion(operand_ty).?; | 10273 | const union_obj = mod.typeToUnion(operand_ty).?; |
| 10187 | const first_item = try sema.resolveInst(items[0]); | 10274 | const first_item_val = sema.resolveConstValue(block, .unneeded, case_vals[0], "") catch unreachable; |
| 10188 | // Previous switch validation ensured this will succeed | | |
| 10189 | const first_item_coerced = try sema.coerce(block, cond_ty, first_item, .unneeded); | | |
| 10190 | const first_item_val = sema.resolveConstValue(block, .unneeded, first_item_coerced, "") catch unreachable; | | |
| 10191 | | 10275 | |
| 10192 | const first_field_index = @intCast(u32, operand_ty.unionTagFieldIndex(first_item_val, mod).?); | 10276 | const first_field_index = @intCast(u32, operand_ty.unionTagFieldIndex(first_item_val, mod).?); |
| 10193 | const first_field = union_obj.fields.values()[first_field_index]; | 10277 | const first_field = union_obj.fields.values()[first_field_index]; |
| 10194 | | 10278 | |
| 10195 | for (items[1..], 0..) |item, i| { | 10279 | for (case_vals[1..], 0..) |item, i| { |
| 10196 | const item_ref = try sema.resolveInst(item); | 10280 | const item_val = sema.resolveConstValue(block, .unneeded, item, "") catch unreachable; |
| 10197 | // Previous switch validation ensured this will succeed | | |
| 10198 | const item_coerced = try sema.coerce(block, cond_ty, item_ref, .unneeded); | | |
| 10199 | const item_val = sema.resolveConstValue(block, .unneeded, item_coerced, "") catch unreachable; | | |
| 10200 | | 10281 | |
| 10201 | const field_index = operand_ty.unionTagFieldIndex(item_val, mod).?; | 10282 | const field_index = operand_ty.unionTagFieldIndex(item_val, mod).?; |
| 10202 | const field = union_obj.fields.values()[field_index]; | 10283 | const field = union_obj.fields.values()[field_index]; |
| 10203 | if (!field.ty.eql(first_field.ty, mod)) { | 10284 | if (!field.ty.eql(first_field.ty, mod)) { |
| 10204 | const msg = msg: { | 10285 | const msg = msg: { |
| 10205 | const raw_capture_src = Module.SwitchProngSrc{ .multi_capture = capture_info.prong_index }; | 10286 | const capture_src = raw_capture_src.resolve(mod, mod.declPtr(block.src_decl), switch_node_offset, .none); |
| 10206 | const capture_src = raw_capture_src.resolve(mod, mod.declPtr(block.src_decl), switch_info.src_node, .first); | | |
| 10207 | | 10287 | |
| 10208 | const msg = try sema.errMsg(block, capture_src, "capture group with incompatible types", .{}); | 10288 | const msg = try sema.errMsg(block, capture_src, "capture group with incompatible types", .{}); |
| 10209 | errdefer msg.destroy(gpa); | 10289 | errdefer msg.destroy(gpa); |
| 10210 | | 10290 | |
| 10211 | const raw_first_item_src = Module.SwitchProngSrc{ .multi = .{ .prong = capture_info.prong_index, .item = 0 } }; | 10291 | // This must be a multi-prong so this must be a `multi_capture` src |
| 10212 | const first_item_src = raw_first_item_src.resolve(mod, mod.declPtr(block.src_decl), switch_info.src_node, .first); | 10292 | const multi_idx = raw_capture_src.multi_capture; |
| 10213 | const raw_item_src = Module.SwitchProngSrc{ .multi = .{ .prong = capture_info.prong_index, .item = 1 + @intCast(u32, i) } }; | 10293 | |
| 10214 | const item_src = raw_item_src.resolve(mod, mod.declPtr(block.src_decl), switch_info.src_node, .first); | 10294 | const raw_first_item_src = Module.SwitchProngSrc{ .multi = .{ .prong = multi_idx, .item = 0 } }; |
| | 10295 | const first_item_src = raw_first_item_src.resolve(mod, mod.declPtr(block.src_decl), switch_node_offset, .first); |
| | 10296 | const raw_item_src = Module.SwitchProngSrc{ .multi = .{ .prong = multi_idx, .item = 1 + @intCast(u32, i) } }; |
| | 10297 | const item_src = raw_item_src.resolve(mod, mod.declPtr(block.src_decl), switch_node_offset, .first); |
| 10215 | try sema.errNote(block, first_item_src, msg, "type '{}' here", .{first_field.ty.fmt(mod)}); | 10298 | try sema.errNote(block, first_item_src, msg, "type '{}' here", .{first_field.ty.fmt(mod)}); |
| 10216 | try sema.errNote(block, item_src, msg, "type '{}' here", .{field.ty.fmt(mod)}); | 10299 | try sema.errNote(block, item_src, msg, "type '{}' here", .{field.ty.fmt(mod)}); |
| 10217 | break :msg msg; | 10300 | break :msg msg; |
| ... | @@ -10220,7 +10303,7 @@ fn zirSwitchCapture( | ... | @@ -10220,7 +10303,7 @@ fn zirSwitchCapture( |
| 10220 | } | 10303 | } |
| 10221 | } | 10304 | } |
| 10222 | | 10305 | |
| 10223 | if (is_ref) { | 10306 | if (capture_byref) { |
| 10224 | const field_ty_ptr = try Type.ptr(sema.arena, mod, .{ | 10307 | const field_ty_ptr = try Type.ptr(sema.arena, mod, .{ |
| 10225 | .pointee_type = first_field.ty, | 10308 | .pointee_type = first_field.ty, |
| 10226 | .@"addrspace" = .generic, | 10309 | .@"addrspace" = .generic, |
| ... | @@ -10250,31 +10333,35 @@ fn zirSwitchCapture( | ... | @@ -10250,31 +10333,35 @@ fn zirSwitchCapture( |
| 10250 | return block.addStructFieldVal(operand, first_field_index, first_field.ty); | 10333 | return block.addStructFieldVal(operand, first_field_index, first_field.ty); |
| 10251 | }, | 10334 | }, |
| 10252 | .ErrorSet => { | 10335 | .ErrorSet => { |
| 10253 | if (items.len > 1) { | 10336 | if (capture_byref) { |
| 10254 | var names: Module.Fn.InferredErrorSet.NameMap = .{}; | 10337 | const capture_src = raw_capture_src.resolve(mod, mod.declPtr(block.src_decl), switch_node_offset, .none); |
| 10255 | try names.ensureUnusedCapacity(sema.arena, items.len); | 10338 | return sema.fail( |
| 10256 | for (items) |item| { | 10339 | block, |
| 10257 | const item_ref = try sema.resolveInst(item); | 10340 | capture_src, |
| 10258 | // Previous switch validation ensured this will succeed | 10341 | "error set cannot be captured by reference", |
| 10259 | const item_val = sema.resolveConstLazyValue(block, .unneeded, item_ref, "") catch unreachable; | 10342 | .{}, |
| 10260 | names.putAssumeCapacityNoClobber(item_val.getErrorName(mod).unwrap().?, {}); | 10343 | ); |
| 10261 | } | 10344 | } |
| 10262 | const else_error_ty = try mod.errorSetFromUnsortedNames(names.keys()); | | |
| 10263 | | | |
| 10264 | return sema.bitCast(block, else_error_ty, operand, operand_src, null); | | |
| 10265 | } else { | | |
| 10266 | const item_ref = try sema.resolveInst(items[0]); | | |
| 10267 | // Previous switch validation ensured this will succeed | | |
| 10268 | const item_val = sema.resolveConstLazyValue(block, .unneeded, item_ref, "") catch unreachable; | | |
| 10269 | | 10345 | |
| | 10346 | if (case_vals.len == 1) { |
| | 10347 | const item_val = sema.resolveConstValue(block, .unneeded, case_vals[0], "") catch unreachable; |
| 10270 | const item_ty = try mod.singleErrorSetType(item_val.getErrorName(mod).unwrap().?); | 10348 | const item_ty = try mod.singleErrorSetType(item_val.getErrorName(mod).unwrap().?); |
| 10271 | return sema.bitCast(block, item_ty, operand, operand_src, null); | 10349 | return sema.bitCast(block, item_ty, operand, operand_src, null); |
| 10272 | } | 10350 | } |
| | 10351 | |
| | 10352 | var names: Module.Fn.InferredErrorSet.NameMap = .{}; |
| | 10353 | try names.ensureUnusedCapacity(sema.arena, case_vals.len); |
| | 10354 | for (case_vals) |err| { |
| | 10355 | const err_val = sema.resolveConstValue(block, .unneeded, err, "") catch unreachable; |
| | 10356 | names.putAssumeCapacityNoClobber(err_val.getErrorName(mod).unwrap().?, {}); |
| | 10357 | } |
| | 10358 | const error_ty = try mod.errorSetFromUnsortedNames(names.keys()); |
| | 10359 | return sema.bitCast(block, error_ty, operand, operand_src, null); |
| 10273 | }, | 10360 | }, |
| 10274 | else => { | 10361 | else => { |
| 10275 | // In this case the capture value is just the passed-through value of the | 10362 | // In this case the capture value is just the passed-through value |
| 10276 | // switch condition. | 10363 | // of the switch condition. |
| 10277 | if (is_ref) { | 10364 | if (capture_byref) { |
| 10278 | return operand_ptr; | 10365 | return operand_ptr; |
| 10279 | } else { | 10366 | } else { |
| 10280 | return operand; | 10367 | return operand; |
| ... | @@ -10415,28 +10502,42 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10415,28 +10502,42 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10415 | var case_vals = try std.ArrayListUnmanaged(Air.Inst.Ref).initCapacity(gpa, scalar_cases_len + 2 * multi_cases_len); | 10502 | var case_vals = try std.ArrayListUnmanaged(Air.Inst.Ref).initCapacity(gpa, scalar_cases_len + 2 * multi_cases_len); |
| 10416 | defer case_vals.deinit(gpa); | 10503 | defer case_vals.deinit(gpa); |
| 10417 | | 10504 | |
| | 10505 | const Special = struct { |
| | 10506 | body: []const Zir.Inst.Index, |
| | 10507 | end: usize, |
| | 10508 | capture: Zir.Inst.SwitchBlock.ProngInfo.Capture, |
| | 10509 | is_inline: bool, |
| | 10510 | }; |
| | 10511 | |
| 10418 | const special_prong = extra.data.bits.specialProng(); | 10512 | const special_prong = extra.data.bits.specialProng(); |
| 10419 | const special: struct { body: []const Zir.Inst.Index, end: usize, is_inline: bool } = switch (special_prong) { | 10513 | const special: Special = switch (special_prong) { |
| 10420 | .none => .{ .body = &.{}, .end = header_extra_index, .is_inline = false }, | 10514 | .none => .{ .body = &.{}, .end = header_extra_index, .capture = .none, .is_inline = false }, |
| 10421 | .under, .@"else" => blk: { | 10515 | .under, .@"else" => blk: { |
| 10422 | const body_len = @truncate(u31, sema.code.extra[header_extra_index]); | 10516 | const info = @bitCast(Zir.Inst.SwitchBlock.ProngInfo, sema.code.extra[header_extra_index]); |
| 10423 | const extra_body_start = header_extra_index + 1; | 10517 | const extra_body_start = header_extra_index + 1; |
| 10424 | break :blk .{ | 10518 | break :blk .{ |
| 10425 | .body = sema.code.extra[extra_body_start..][0..body_len], | 10519 | .body = sema.code.extra[extra_body_start..][0..info.body_len], |
| 10426 | .end = extra_body_start + body_len, | 10520 | .end = extra_body_start + info.body_len, |
| 10427 | .is_inline = sema.code.extra[header_extra_index] >> 31 != 0, | 10521 | .capture = info.capture, |
| | 10522 | .is_inline = info.is_inline, |
| 10428 | }; | 10523 | }; |
| 10429 | }, | 10524 | }, |
| 10430 | }; | 10525 | }; |
| 10431 | | 10526 | |
| 10432 | const maybe_union_ty = blk: { | 10527 | const raw_operand: struct { val: Air.Inst.Ref, ptr: Air.Inst.Ref } = blk: { |
| 10433 | const zir_tags = sema.code.instructions.items(.tag); | 10528 | const zir_tags = sema.code.instructions.items(.tag); |
| 10434 | const zir_data = sema.code.instructions.items(.data); | 10529 | const zir_data = sema.code.instructions.items(.data); |
| 10435 | const cond_index = Zir.refToIndex(extra.data.operand).?; | 10530 | const cond_index = Zir.refToIndex(extra.data.operand).?; |
| 10436 | const raw_operand = sema.resolveInst(zir_data[cond_index].un_node.operand) catch unreachable; | 10531 | const raw = sema.resolveInst(zir_data[cond_index].un_node.operand) catch unreachable; |
| 10437 | const target_ty = sema.typeOf(raw_operand); | 10532 | if (zir_tags[cond_index] == .switch_cond_ref) { |
| 10438 | break :blk if (zir_tags[cond_index] == .switch_cond_ref) target_ty.childType(mod) else target_ty; | 10533 | const val = try sema.analyzeLoad(block, src, raw, operand_src); |
| | 10534 | break :blk .{ .val = val, .ptr = raw }; |
| | 10535 | } else { |
| | 10536 | break :blk .{ .val = raw, .ptr = undefined }; |
| | 10537 | } |
| 10439 | }; | 10538 | }; |
| | 10539 | |
| | 10540 | const maybe_union_ty = sema.typeOf(raw_operand.val); |
| 10440 | const union_originally = maybe_union_ty.zigTypeTag(mod) == .Union; | 10541 | const union_originally = maybe_union_ty.zigTypeTag(mod) == .Union; |
| 10441 | | 10542 | |
| 10442 | // Duplicate checking variables later also used for `inline else`. | 10543 | // Duplicate checking variables later also used for `inline else`. |
| ... | @@ -10496,9 +10597,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10496,9 +10597,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10496 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { | 10597 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { |
| 10497 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); | 10598 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 10498 | extra_index += 1; | 10599 | extra_index += 1; |
| 10499 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | 10600 | const info = @bitCast(Zir.Inst.SwitchBlock.ProngInfo, sema.code.extra[extra_index]); |
| 10500 | extra_index += 1; | 10601 | extra_index += 1 + info.body_len; |
| 10501 | extra_index += body_len; | | |
| 10502 | | 10602 | |
| 10503 | case_vals.appendAssumeCapacity(try sema.validateSwitchItemEnum( | 10603 | case_vals.appendAssumeCapacity(try sema.validateSwitchItemEnum( |
| 10504 | block, | 10604 | block, |
| ... | @@ -10518,10 +10618,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10518,10 +10618,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10518 | extra_index += 1; | 10618 | extra_index += 1; |
| 10519 | const ranges_len = sema.code.extra[extra_index]; | 10619 | const ranges_len = sema.code.extra[extra_index]; |
| 10520 | extra_index += 1; | 10620 | extra_index += 1; |
| 10521 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | 10621 | const info = @bitCast(Zir.Inst.SwitchBlock.ProngInfo, sema.code.extra[extra_index]); |
| 10522 | extra_index += 1; | 10622 | extra_index += 1; |
| 10523 | const items = sema.code.refSlice(extra_index, items_len); | 10623 | const items = sema.code.refSlice(extra_index, items_len); |
| 10524 | extra_index += items_len + body_len; | 10624 | extra_index += items_len + info.body_len; |
| 10525 | | 10625 | |
| 10526 | try case_vals.ensureUnusedCapacity(gpa, items.len); | 10626 | try case_vals.ensureUnusedCapacity(gpa, items.len); |
| 10527 | for (items, 0..) |item_ref, item_i| { | 10627 | for (items, 0..) |item_ref, item_i| { |
| ... | @@ -10596,9 +10696,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10596,9 +10696,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10596 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { | 10696 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { |
| 10597 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); | 10697 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 10598 | extra_index += 1; | 10698 | extra_index += 1; |
| 10599 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | 10699 | const info = @bitCast(Zir.Inst.SwitchBlock.ProngInfo, sema.code.extra[extra_index]); |
| 10600 | extra_index += 1; | 10700 | extra_index += 1 + info.body_len; |
| 10601 | extra_index += body_len; | | |
| 10602 | | 10701 | |
| 10603 | case_vals.appendAssumeCapacity(try sema.validateSwitchItemError( | 10702 | case_vals.appendAssumeCapacity(try sema.validateSwitchItemError( |
| 10604 | block, | 10703 | block, |
| ... | @@ -10617,10 +10716,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10617,10 +10716,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10617 | extra_index += 1; | 10716 | extra_index += 1; |
| 10618 | const ranges_len = sema.code.extra[extra_index]; | 10717 | const ranges_len = sema.code.extra[extra_index]; |
| 10619 | extra_index += 1; | 10718 | extra_index += 1; |
| 10620 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | 10719 | const info = @bitCast(Zir.Inst.SwitchBlock.ProngInfo, sema.code.extra[extra_index]); |
| 10621 | extra_index += 1; | 10720 | extra_index += 1; |
| 10622 | const items = sema.code.refSlice(extra_index, items_len); | 10721 | const items = sema.code.refSlice(extra_index, items_len); |
| 10623 | extra_index += items_len + body_len; | 10722 | extra_index += items_len + info.body_len; |
| 10624 | | 10723 | |
| 10625 | try case_vals.ensureUnusedCapacity(gpa, items.len); | 10724 | try case_vals.ensureUnusedCapacity(gpa, items.len); |
| 10626 | for (items, 0..) |item_ref, item_i| { | 10725 | for (items, 0..) |item_ref, item_i| { |
| ... | @@ -10694,7 +10793,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10694,7 +10793,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10694 | .dbg_block_end, | 10793 | .dbg_block_end, |
| 10695 | .dbg_stmt, | 10794 | .dbg_stmt, |
| 10696 | .dbg_var_val, | 10795 | .dbg_var_val, |
| 10697 | .switch_capture, | | |
| 10698 | .ret_type, | 10796 | .ret_type, |
| 10699 | .as_node, | 10797 | .as_node, |
| 10700 | .ret_node, | 10798 | .ret_node, |
| ... | @@ -10739,9 +10837,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10739,9 +10837,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10739 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { | 10837 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { |
| 10740 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); | 10838 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 10741 | extra_index += 1; | 10839 | extra_index += 1; |
| 10742 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | 10840 | const info = @bitCast(Zir.Inst.SwitchBlock.ProngInfo, sema.code.extra[extra_index]); |
| 10743 | extra_index += 1; | 10841 | extra_index += 1 + info.body_len; |
| 10744 | extra_index += body_len; | | |
| 10745 | | 10842 | |
| 10746 | case_vals.appendAssumeCapacity(try sema.validateSwitchItemInt( | 10843 | case_vals.appendAssumeCapacity(try sema.validateSwitchItemInt( |
| 10747 | block, | 10844 | block, |
| ... | @@ -10760,7 +10857,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10760,7 +10857,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10760 | extra_index += 1; | 10857 | extra_index += 1; |
| 10761 | const ranges_len = sema.code.extra[extra_index]; | 10858 | const ranges_len = sema.code.extra[extra_index]; |
| 10762 | extra_index += 1; | 10859 | extra_index += 1; |
| 10763 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | 10860 | const info = @bitCast(Zir.Inst.SwitchBlock.ProngInfo, sema.code.extra[extra_index]); |
| 10764 | extra_index += 1; | 10861 | extra_index += 1; |
| 10765 | const items = sema.code.refSlice(extra_index, items_len); | 10862 | const items = sema.code.refSlice(extra_index, items_len); |
| 10766 | extra_index += items_len; | 10863 | extra_index += items_len; |
| ... | @@ -10798,7 +10895,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10798,7 +10895,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10798 | case_vals.appendAssumeCapacity(vals[1]); | 10895 | case_vals.appendAssumeCapacity(vals[1]); |
| 10799 | } | 10896 | } |
| 10800 | | 10897 | |
| 10801 | extra_index += body_len; | 10898 | extra_index += info.body_len; |
| 10802 | } | 10899 | } |
| 10803 | } | 10900 | } |
| 10804 | | 10901 | |
| ... | @@ -10835,9 +10932,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10835,9 +10932,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10835 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { | 10932 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { |
| 10836 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); | 10933 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 10837 | extra_index += 1; | 10934 | extra_index += 1; |
| 10838 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | 10935 | const info = @bitCast(Zir.Inst.SwitchBlock.ProngInfo, sema.code.extra[extra_index]); |
| 10839 | extra_index += 1; | 10936 | extra_index += 1 + info.body_len; |
| 10840 | extra_index += body_len; | | |
| 10841 | | 10937 | |
| 10842 | case_vals.appendAssumeCapacity(try sema.validateSwitchItemBool( | 10938 | case_vals.appendAssumeCapacity(try sema.validateSwitchItemBool( |
| 10843 | block, | 10939 | block, |
| ... | @@ -10856,10 +10952,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10856,10 +10952,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10856 | extra_index += 1; | 10952 | extra_index += 1; |
| 10857 | const ranges_len = sema.code.extra[extra_index]; | 10953 | const ranges_len = sema.code.extra[extra_index]; |
| 10858 | extra_index += 1; | 10954 | extra_index += 1; |
| 10859 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | 10955 | const info = @bitCast(Zir.Inst.SwitchBlock.ProngInfo, sema.code.extra[extra_index]); |
| 10860 | extra_index += 1; | 10956 | extra_index += 1; |
| 10861 | const items = sema.code.refSlice(extra_index, items_len); | 10957 | const items = sema.code.refSlice(extra_index, items_len); |
| 10862 | extra_index += items_len + body_len; | 10958 | extra_index += items_len + info.body_len; |
| 10863 | | 10959 | |
| 10864 | try case_vals.ensureUnusedCapacity(gpa, items.len); | 10960 | try case_vals.ensureUnusedCapacity(gpa, items.len); |
| 10865 | for (items, 0..) |item_ref, item_i| { | 10961 | for (items, 0..) |item_ref, item_i| { |
| ... | @@ -10918,9 +11014,9 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10918,9 +11014,9 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10918 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { | 11014 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { |
| 10919 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); | 11015 | const item_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 10920 | extra_index += 1; | 11016 | extra_index += 1; |
| 10921 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | 11017 | const info = @bitCast(Zir.Inst.SwitchBlock.ProngInfo, sema.code.extra[extra_index]); |
| 10922 | extra_index += 1; | 11018 | extra_index += 1; |
| 10923 | extra_index += body_len; | 11019 | extra_index += info.body_len; |
| 10924 | | 11020 | |
| 10925 | case_vals.appendAssumeCapacity(try sema.validateSwitchItemSparse( | 11021 | case_vals.appendAssumeCapacity(try sema.validateSwitchItemSparse( |
| 10926 | block, | 11022 | block, |
| ... | @@ -10939,10 +11035,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10939,10 +11035,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10939 | extra_index += 1; | 11035 | extra_index += 1; |
| 10940 | const ranges_len = sema.code.extra[extra_index]; | 11036 | const ranges_len = sema.code.extra[extra_index]; |
| 10941 | extra_index += 1; | 11037 | extra_index += 1; |
| 10942 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | 11038 | const info = @bitCast(Zir.Inst.SwitchBlock.ProngInfo, sema.code.extra[extra_index]); |
| 10943 | extra_index += 1; | 11039 | extra_index += 1; |
| 10944 | const items = sema.code.refSlice(extra_index, items_len); | 11040 | const items = sema.code.refSlice(extra_index, items_len); |
| 10945 | extra_index += items_len + body_len; | 11041 | extra_index += items_len + info.body_len; |
| 10946 | | 11042 | |
| 10947 | try case_vals.ensureUnusedCapacity(gpa, items.len); | 11043 | try case_vals.ensureUnusedCapacity(gpa, items.len); |
| 10948 | for (items, 0..) |item_ref, item_i| { | 11044 | for (items, 0..) |item_ref, item_i| { |
| ... | @@ -11006,7 +11102,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11006,7 +11102,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11006 | .is_comptime = block.is_comptime, | 11102 | .is_comptime = block.is_comptime, |
| 11007 | .comptime_reason = block.comptime_reason, | 11103 | .comptime_reason = block.comptime_reason, |
| 11008 | .is_typeof = block.is_typeof, | 11104 | .is_typeof = block.is_typeof, |
| 11009 | .switch_else_err_ty = else_error_ty, | | |
| 11010 | .c_import_buf = block.c_import_buf, | 11105 | .c_import_buf = block.c_import_buf, |
| 11011 | .runtime_cond = block.runtime_cond, | 11106 | .runtime_cond = block.runtime_cond, |
| 11012 | .runtime_loop = block.runtime_loop, | 11107 | .runtime_loop = block.runtime_loop, |
| ... | @@ -11024,19 +11119,31 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11024,19 +11119,31 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11024 | var scalar_i: usize = 0; | 11119 | var scalar_i: usize = 0; |
| 11025 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { | 11120 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { |
| 11026 | extra_index += 1; | 11121 | extra_index += 1; |
| 11027 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | 11122 | const info = @bitCast(Zir.Inst.SwitchBlock.ProngInfo, sema.code.extra[extra_index]); |
| 11028 | const is_inline = sema.code.extra[extra_index] >> 31 != 0; | | |
| 11029 | extra_index += 1; | 11123 | extra_index += 1; |
| 11030 | const body = sema.code.extra[extra_index..][0..body_len]; | 11124 | const body = sema.code.extra[extra_index..][0..info.body_len]; |
| 11031 | extra_index += body_len; | 11125 | extra_index += info.body_len; |
| 11032 | | 11126 | |
| 11033 | const item = case_vals.items[scalar_i]; | 11127 | const item = case_vals.items[scalar_i]; |
| 11034 | const item_val = sema.resolveConstLazyValue(&child_block, .unneeded, item, "") catch unreachable; | 11128 | const item_val = sema.resolveConstValue(&child_block, .unneeded, item, "") catch unreachable; |
| 11035 | if (resolved_operand_val.eql(item_val, operand_ty, mod)) { | 11129 | if (operand_val.eql(item_val, operand_ty, sema.mod)) { |
| 11036 | if (is_inline) child_block.inline_case_capture = operand; | 11130 | if (info.is_inline) child_block.inline_case_capture = operand; |
| 11037 | | | |
| 11038 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); | 11131 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); |
| 11039 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); | 11132 | return sema.resolveSwitchProngComptime( |
| | 11133 | block, |
| | 11134 | &child_block, |
| | 11135 | src, |
| | 11136 | raw_operand.val, |
| | 11137 | raw_operand.ptr, |
| | 11138 | .normal, |
| | 11139 | body, |
| | 11140 | info.capture, |
| | 11141 | .{ .scalar = @intCast(u32, scalar_i) }, |
| | 11142 | else_error_ty, |
| | 11143 | &.{item}, |
| | 11144 | inst, |
| | 11145 | merges, |
| | 11146 | ); |
| 11040 | } | 11147 | } |
| 11041 | } | 11148 | } |
| 11042 | } | 11149 | } |
| ... | @@ -11048,22 +11155,34 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11048,22 +11155,34 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11048 | extra_index += 1; | 11155 | extra_index += 1; |
| 11049 | const ranges_len = sema.code.extra[extra_index]; | 11156 | const ranges_len = sema.code.extra[extra_index]; |
| 11050 | extra_index += 1; | 11157 | extra_index += 1; |
| 11051 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | 11158 | const info = @bitCast(Zir.Inst.SwitchBlock.ProngInfo, sema.code.extra[extra_index]); |
| 11052 | const is_inline = sema.code.extra[extra_index] >> 31 != 0; | | |
| 11053 | extra_index += 1 + items_len; | 11159 | extra_index += 1 + items_len; |
| 11054 | const body = sema.code.extra[extra_index + 2 * ranges_len ..][0..body_len]; | 11160 | const body = sema.code.extra[extra_index + 2 * ranges_len ..][0..info.body_len]; |
| 11055 | | 11161 | |
| 11056 | const items = case_vals.items[case_val_idx..][0..items_len]; | 11162 | const items = case_vals.items[case_val_idx..][0..items_len]; |
| 11057 | case_val_idx += items_len; | 11163 | case_val_idx += items_len; |
| 11058 | | 11164 | |
| 11059 | for (items) |item| { | 11165 | for (items) |item| { |
| 11060 | // Validation above ensured these will succeed. | 11166 | // Validation above ensured these will succeed. |
| 11061 | const item_val = sema.resolveConstLazyValue(&child_block, .unneeded, item, "") catch unreachable; | 11167 | const item_val = sema.resolveConstValue(&child_block, .unneeded, item, "") catch unreachable; |
| 11062 | if (resolved_operand_val.eql(item_val, operand_ty, mod)) { | 11168 | if (operand_val.eql(item_val, operand_ty, sema.mod)) { |
| 11063 | if (is_inline) child_block.inline_case_capture = operand; | 11169 | if (info.is_inline) child_block.inline_case_capture = operand; |
| 11064 | | | |
| 11065 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); | 11170 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); |
| 11066 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); | 11171 | return sema.resolveSwitchProngComptime( |
| | 11172 | block, |
| | 11173 | &child_block, |
| | 11174 | src, |
| | 11175 | raw_operand.val, |
| | 11176 | raw_operand.ptr, |
| | 11177 | .normal, |
| | 11178 | body, |
| | 11179 | info.capture, |
| | 11180 | .{ .multi_capture = @intCast(u32, multi_i) }, |
| | 11181 | else_error_ty, |
| | 11182 | items, |
| | 11183 | inst, |
| | 11184 | merges, |
| | 11185 | ); |
| 11067 | } | 11186 | } |
| 11068 | } | 11187 | } |
| 11069 | | 11188 | |
| ... | @@ -11079,13 +11198,27 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11079,13 +11198,27 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11079 | if ((try sema.compareAll(resolved_operand_val, .gte, first_val, operand_ty)) and | 11198 | if ((try sema.compareAll(resolved_operand_val, .gte, first_val, operand_ty)) and |
| 11080 | (try sema.compareAll(resolved_operand_val, .lte, last_val, operand_ty))) | 11199 | (try sema.compareAll(resolved_operand_val, .lte, last_val, operand_ty))) |
| 11081 | { | 11200 | { |
| 11082 | if (is_inline) child_block.inline_case_capture = operand; | 11201 | if (info.is_inline) child_block.inline_case_capture = operand; |
| 11083 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); | 11202 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); |
| 11084 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); | 11203 | return sema.resolveSwitchProngComptime( |
| | 11204 | block, |
| | 11205 | &child_block, |
| | 11206 | src, |
| | 11207 | raw_operand.val, |
| | 11208 | raw_operand.ptr, |
| | 11209 | .normal, |
| | 11210 | body, |
| | 11211 | info.capture, |
| | 11212 | .{ .multi_capture = @intCast(u32, multi_i) }, |
| | 11213 | else_error_ty, |
| | 11214 | undefined, |
| | 11215 | inst, |
| | 11216 | merges, |
| | 11217 | ); |
| 11085 | } | 11218 | } |
| 11086 | } | 11219 | } |
| 11087 | | 11220 | |
| 11088 | extra_index += body_len; | 11221 | extra_index += info.body_len; |
| 11089 | } | 11222 | } |
| 11090 | } | 11223 | } |
| 11091 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, special.body, operand); | 11224 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, special.body, operand); |
| ... | @@ -11093,7 +11226,22 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11093,7 +11226,22 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11093 | if (empty_enum) { | 11226 | if (empty_enum) { |
| 11094 | return Air.Inst.Ref.void_value; | 11227 | return Air.Inst.Ref.void_value; |
| 11095 | } | 11228 | } |
| 11096 | return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges); | 11229 | |
| | 11230 | return sema.resolveSwitchProngComptime( |
| | 11231 | block, |
| | 11232 | &child_block, |
| | 11233 | src, |
| | 11234 | raw_operand.val, |
| | 11235 | raw_operand.ptr, |
| | 11236 | .special, |
| | 11237 | special.body, |
| | 11238 | special.capture, |
| | 11239 | .special, |
| | 11240 | else_error_ty, |
| | 11241 | undefined, |
| | 11242 | inst, |
| | 11243 | merges, |
| | 11244 | ); |
| 11097 | } | 11245 | } |
| 11098 | | 11246 | |
| 11099 | if (scalar_cases_len + multi_cases_len == 0 and !special.is_inline) { | 11247 | if (scalar_cases_len + multi_cases_len == 0 and !special.is_inline) { |
| ... | @@ -11113,7 +11261,22 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11113,7 +11261,22 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11113 | const ok = try block.addUnOp(.is_named_enum_value, operand); | 11261 | const ok = try block.addUnOp(.is_named_enum_value, operand); |
| 11114 | try sema.addSafetyCheck(block, ok, .corrupt_switch); | 11262 | try sema.addSafetyCheck(block, ok, .corrupt_switch); |
| 11115 | } | 11263 | } |
| 11116 | return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges); | 11264 | |
| | 11265 | return sema.resolveSwitchProngComptime( |
| | 11266 | block, |
| | 11267 | &child_block, |
| | 11268 | src, |
| | 11269 | raw_operand.val, |
| | 11270 | raw_operand.ptr, |
| | 11271 | .special, |
| | 11272 | special.body, |
| | 11273 | special.capture, |
| | 11274 | .special, |
| | 11275 | else_error_ty, |
| | 11276 | undefined, |
| | 11277 | inst, |
| | 11278 | merges, |
| | 11279 | ); |
| 11117 | } | 11280 | } |
| 11118 | | 11281 | |
| 11119 | if (child_block.is_comptime) { | 11282 | if (child_block.is_comptime) { |
| ... | @@ -11140,11 +11303,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11140,11 +11303,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11140 | var scalar_i: usize = 0; | 11303 | var scalar_i: usize = 0; |
| 11141 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { | 11304 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { |
| 11142 | extra_index += 1; | 11305 | extra_index += 1; |
| 11143 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | 11306 | const info = @bitCast(Zir.Inst.SwitchBlock.ProngInfo, sema.code.extra[extra_index]); |
| 11144 | const is_inline = sema.code.extra[extra_index] >> 31 != 0; | | |
| 11145 | extra_index += 1; | 11307 | extra_index += 1; |
| 11146 | const body = sema.code.extra[extra_index..][0..body_len]; | 11308 | const body = sema.code.extra[extra_index..][0..info.body_len]; |
| 11147 | extra_index += body_len; | 11309 | extra_index += info.body_len; |
| 11148 | | 11310 | |
| 11149 | var wip_captures = try WipCaptureScope.init(gpa, child_block.wip_capture_scope); | 11311 | var wip_captures = try WipCaptureScope.init(gpa, child_block.wip_capture_scope); |
| 11150 | defer wip_captures.deinit(); | 11312 | defer wip_captures.deinit(); |
| ... | @@ -11154,7 +11316,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11154,7 +11316,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11154 | case_block.inline_case_capture = .none; | 11316 | case_block.inline_case_capture = .none; |
| 11155 | | 11317 | |
| 11156 | const item = case_vals.items[scalar_i]; | 11318 | const item = case_vals.items[scalar_i]; |
| 11157 | if (is_inline) case_block.inline_case_capture = item; | 11319 | if (info.is_inline) case_block.inline_case_capture = item; |
| 11158 | // `item` is already guaranteed to be constant known. | 11320 | // `item` is already guaranteed to be constant known. |
| 11159 | | 11321 | |
| 11160 | const analyze_body = if (union_originally) blk: { | 11322 | const analyze_body = if (union_originally) blk: { |
| ... | @@ -11166,7 +11328,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11166,7 +11328,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11166 | if (err_set and try sema.maybeErrorUnwrap(&case_block, body, operand)) { | 11328 | if (err_set and try sema.maybeErrorUnwrap(&case_block, body, operand)) { |
| 11167 | // nothing to do here | 11329 | // nothing to do here |
| 11168 | } else if (analyze_body) { | 11330 | } else if (analyze_body) { |
| 11169 | try sema.analyzeBodyRuntimeBreak(&case_block, body); | 11331 | try sema.analyzeSwitchProngRuntime( |
| | 11332 | &case_block, |
| | 11333 | raw_operand.val, |
| | 11334 | raw_operand.ptr, |
| | 11335 | .normal, |
| | 11336 | body, |
| | 11337 | info.capture, |
| | 11338 | .{ .scalar = @intCast(u32, scalar_i) }, |
| | 11339 | else_error_ty, |
| | 11340 | &.{item}, |
| | 11341 | inst, |
| | 11342 | ); |
| 11170 | } else { | 11343 | } else { |
| 11171 | _ = try case_block.addNoOp(.unreach); | 11344 | _ = try case_block.addNoOp(.unreach); |
| 11172 | } | 11345 | } |
| ... | @@ -11195,8 +11368,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11195,8 +11368,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11195 | extra_index += 1; | 11368 | extra_index += 1; |
| 11196 | const ranges_len = sema.code.extra[extra_index]; | 11369 | const ranges_len = sema.code.extra[extra_index]; |
| 11197 | extra_index += 1; | 11370 | extra_index += 1; |
| 11198 | const body_len = @truncate(u31, sema.code.extra[extra_index]); | 11371 | const info = @bitCast(Zir.Inst.SwitchBlock.ProngInfo, sema.code.extra[extra_index]); |
| 11199 | const is_inline = sema.code.extra[extra_index] >> 31 != 0; | | |
| 11200 | extra_index += 1 + items_len; | 11372 | extra_index += 1 + items_len; |
| 11201 | | 11373 | |
| 11202 | const items = case_vals.items[case_val_idx..][0..items_len]; | 11374 | const items = case_vals.items[case_val_idx..][0..items_len]; |
| ... | @@ -11207,9 +11379,9 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11207,9 +11379,9 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11207 | case_block.inline_case_capture = .none; | 11379 | case_block.inline_case_capture = .none; |
| 11208 | | 11380 | |
| 11209 | // Generate all possible cases as scalar prongs. | 11381 | // Generate all possible cases as scalar prongs. |
| 11210 | if (is_inline) { | 11382 | if (info.is_inline) { |
| 11211 | const body_start = extra_index + 2 * ranges_len; | 11383 | const body_start = extra_index + 2 * ranges_len; |
| 11212 | const body = sema.code.extra[body_start..][0..body_len]; | 11384 | const body = sema.code.extra[body_start..][0..info.body_len]; |
| 11213 | var emit_bb = false; | 11385 | var emit_bb = false; |
| 11214 | | 11386 | |
| 11215 | var range_i: u32 = 0; | 11387 | var range_i: u32 = 0; |
| ... | @@ -11250,7 +11422,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11250,7 +11422,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11250 | }; | 11422 | }; |
| 11251 | emit_bb = true; | 11423 | emit_bb = true; |
| 11252 | | 11424 | |
| 11253 | try sema.analyzeBodyRuntimeBreak(&case_block, body); | 11425 | try sema.analyzeSwitchProngRuntime( |
| | 11426 | &case_block, |
| | 11427 | raw_operand.val, |
| | 11428 | raw_operand.ptr, |
| | 11429 | .normal, |
| | 11430 | body, |
| | 11431 | info.capture, |
| | 11432 | .{ .multi_capture = multi_i }, |
| | 11433 | else_error_ty, |
| | 11434 | undefined, |
| | 11435 | inst, |
| | 11436 | ); |
| 11254 | | 11437 | |
| 11255 | try cases_extra.ensureUnusedCapacity(gpa, 3 + case_block.instructions.items.len); | 11438 | try cases_extra.ensureUnusedCapacity(gpa, 3 + case_block.instructions.items.len); |
| 11256 | cases_extra.appendAssumeCapacity(1); // items_len | 11439 | cases_extra.appendAssumeCapacity(1); // items_len |
| ... | @@ -11286,7 +11469,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11286,7 +11469,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11286 | emit_bb = true; | 11469 | emit_bb = true; |
| 11287 | | 11470 | |
| 11288 | if (analyze_body) { | 11471 | if (analyze_body) { |
| 11289 | try sema.analyzeBodyRuntimeBreak(&case_block, body); | 11472 | try sema.analyzeSwitchProngRuntime( |
| | 11473 | &case_block, |
| | 11474 | raw_operand.val, |
| | 11475 | raw_operand.ptr, |
| | 11476 | .normal, |
| | 11477 | body, |
| | 11478 | info.capture, |
| | 11479 | .{ .multi_capture = multi_i }, |
| | 11480 | else_error_ty, |
| | 11481 | &.{item}, |
| | 11482 | inst, |
| | 11483 | ); |
| 11290 | } else { | 11484 | } else { |
| 11291 | _ = try case_block.addNoOp(.unreach); | 11485 | _ = try case_block.addNoOp(.unreach); |
| 11292 | } | 11486 | } |
| ... | @@ -11298,7 +11492,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11298,7 +11492,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11298 | cases_extra.appendSliceAssumeCapacity(case_block.instructions.items); | 11492 | cases_extra.appendSliceAssumeCapacity(case_block.instructions.items); |
| 11299 | } | 11493 | } |
| 11300 | | 11494 | |
| 11301 | extra_index += body_len; | 11495 | extra_index += info.body_len; |
| 11302 | continue; | 11496 | continue; |
| 11303 | } | 11497 | } |
| 11304 | | 11498 | |
| ... | @@ -11319,12 +11513,23 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11319,12 +11513,23 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11319 | else | 11513 | else |
| 11320 | true; | 11514 | true; |
| 11321 | | 11515 | |
| 11322 | const body = sema.code.extra[extra_index..][0..body_len]; | 11516 | const body = sema.code.extra[extra_index..][0..info.body_len]; |
| 11323 | extra_index += body_len; | 11517 | extra_index += info.body_len; |
| 11324 | if (err_set and try sema.maybeErrorUnwrap(&case_block, body, operand)) { | 11518 | if (err_set and try sema.maybeErrorUnwrap(&case_block, body, operand)) { |
| 11325 | // nothing to do here | 11519 | // nothing to do here |
| 11326 | } else if (analyze_body) { | 11520 | } else if (analyze_body) { |
| 11327 | try sema.analyzeBodyRuntimeBreak(&case_block, body); | 11521 | try sema.analyzeSwitchProngRuntime( |
| | 11522 | &case_block, |
| | 11523 | raw_operand.val, |
| | 11524 | raw_operand.ptr, |
| | 11525 | .normal, |
| | 11526 | body, |
| | 11527 | info.capture, |
| | 11528 | .{ .multi_capture = multi_i }, |
| | 11529 | else_error_ty, |
| | 11530 | items, |
| | 11531 | inst, |
| | 11532 | ); |
| 11328 | } else { | 11533 | } else { |
| 11329 | _ = try case_block.addNoOp(.unreach); | 11534 | _ = try case_block.addNoOp(.unreach); |
| 11330 | } | 11535 | } |
| ... | @@ -11397,12 +11602,23 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11397,12 +11602,23 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11397 | case_block.instructions.shrinkRetainingCapacity(0); | 11602 | case_block.instructions.shrinkRetainingCapacity(0); |
| 11398 | case_block.wip_capture_scope = wip_captures.scope; | 11603 | case_block.wip_capture_scope = wip_captures.scope; |
| 11399 | | 11604 | |
| 11400 | const body = sema.code.extra[extra_index..][0..body_len]; | 11605 | const body = sema.code.extra[extra_index..][0..info.body_len]; |
| 11401 | extra_index += body_len; | 11606 | extra_index += info.body_len; |
| 11402 | if (err_set and try sema.maybeErrorUnwrap(&case_block, body, operand)) { | 11607 | if (err_set and try sema.maybeErrorUnwrap(&case_block, body, operand)) { |
| 11403 | // nothing to do here | 11608 | // nothing to do here |
| 11404 | } else { | 11609 | } else { |
| 11405 | try sema.analyzeBodyRuntimeBreak(&case_block, body); | 11610 | try sema.analyzeSwitchProngRuntime( |
| | 11611 | &case_block, |
| | 11612 | raw_operand.val, |
| | 11613 | raw_operand.ptr, |
| | 11614 | .normal, |
| | 11615 | body, |
| | 11616 | info.capture, |
| | 11617 | .{ .multi_capture = multi_i }, |
| | 11618 | else_error_ty, |
| | 11619 | items, |
| | 11620 | inst, |
| | 11621 | ); |
| 11406 | } | 11622 | } |
| 11407 | | 11623 | |
| 11408 | try wip_captures.finalize(); | 11624 | try wip_captures.finalize(); |
| ... | @@ -11461,7 +11677,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11461,7 +11677,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11461 | emit_bb = true; | 11677 | emit_bb = true; |
| 11462 | | 11678 | |
| 11463 | if (analyze_body) { | 11679 | if (analyze_body) { |
| 11464 | try sema.analyzeBodyRuntimeBreak(&case_block, special.body); | 11680 | try sema.analyzeSwitchProngRuntime( |
| | 11681 | &case_block, |
| | 11682 | raw_operand.val, |
| | 11683 | raw_operand.ptr, |
| | 11684 | .special, |
| | 11685 | special.body, |
| | 11686 | special.capture, |
| | 11687 | .special, |
| | 11688 | else_error_ty, |
| | 11689 | &.{item_ref}, |
| | 11690 | inst, |
| | 11691 | ); |
| 11465 | } else { | 11692 | } else { |
| 11466 | _ = try case_block.addNoOp(.unreach); | 11693 | _ = try case_block.addNoOp(.unreach); |
| 11467 | } | 11694 | } |
| ... | @@ -11497,7 +11724,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11497,7 +11724,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11497 | if (emit_bb) try sema.emitBackwardBranch(block, special_prong_src); | 11724 | if (emit_bb) try sema.emitBackwardBranch(block, special_prong_src); |
| 11498 | emit_bb = true; | 11725 | emit_bb = true; |
| 11499 | | 11726 | |
| 11500 | try sema.analyzeBodyRuntimeBreak(&case_block, special.body); | 11727 | try sema.analyzeSwitchProngRuntime( |
| | 11728 | &case_block, |
| | 11729 | raw_operand.val, |
| | 11730 | raw_operand.ptr, |
| | 11731 | .special, |
| | 11732 | special.body, |
| | 11733 | special.capture, |
| | 11734 | .special, |
| | 11735 | else_error_ty, |
| | 11736 | &.{item_ref}, |
| | 11737 | inst, |
| | 11738 | ); |
| 11501 | | 11739 | |
| 11502 | try cases_extra.ensureUnusedCapacity(gpa, 3 + case_block.instructions.items.len); | 11740 | try cases_extra.ensureUnusedCapacity(gpa, 3 + case_block.instructions.items.len); |
| 11503 | cases_extra.appendAssumeCapacity(1); // items_len | 11741 | cases_extra.appendAssumeCapacity(1); // items_len |
| ... | @@ -11520,7 +11758,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11520,7 +11758,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11520 | if (emit_bb) try sema.emitBackwardBranch(block, special_prong_src); | 11758 | if (emit_bb) try sema.emitBackwardBranch(block, special_prong_src); |
| 11521 | emit_bb = true; | 11759 | emit_bb = true; |
| 11522 | | 11760 | |
| 11523 | try sema.analyzeBodyRuntimeBreak(&case_block, special.body); | 11761 | try sema.analyzeSwitchProngRuntime( |
| | 11762 | &case_block, |
| | 11763 | raw_operand.val, |
| | 11764 | raw_operand.ptr, |
| | 11765 | .special, |
| | 11766 | special.body, |
| | 11767 | special.capture, |
| | 11768 | .special, |
| | 11769 | else_error_ty, |
| | 11770 | &.{item_ref}, |
| | 11771 | inst, |
| | 11772 | ); |
| 11524 | | 11773 | |
| 11525 | try cases_extra.ensureUnusedCapacity(gpa, 3 + case_block.instructions.items.len); | 11774 | try cases_extra.ensureUnusedCapacity(gpa, 3 + case_block.instructions.items.len); |
| 11526 | cases_extra.appendAssumeCapacity(1); // items_len | 11775 | cases_extra.appendAssumeCapacity(1); // items_len |
| ... | @@ -11540,7 +11789,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11540,7 +11789,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11540 | if (emit_bb) try sema.emitBackwardBranch(block, special_prong_src); | 11789 | if (emit_bb) try sema.emitBackwardBranch(block, special_prong_src); |
| 11541 | emit_bb = true; | 11790 | emit_bb = true; |
| 11542 | | 11791 | |
| 11543 | try sema.analyzeBodyRuntimeBreak(&case_block, special.body); | 11792 | try sema.analyzeSwitchProngRuntime( |
| | 11793 | &case_block, |
| | 11794 | raw_operand.val, |
| | 11795 | raw_operand.ptr, |
| | 11796 | .special, |
| | 11797 | special.body, |
| | 11798 | special.capture, |
| | 11799 | .special, |
| | 11800 | else_error_ty, |
| | 11801 | &.{Air.Inst.Ref.bool_true}, |
| | 11802 | inst, |
| | 11803 | ); |
| 11544 | | 11804 | |
| 11545 | try cases_extra.ensureUnusedCapacity(gpa, 3 + case_block.instructions.items.len); | 11805 | try cases_extra.ensureUnusedCapacity(gpa, 3 + case_block.instructions.items.len); |
| 11546 | cases_extra.appendAssumeCapacity(1); // items_len | 11806 | cases_extra.appendAssumeCapacity(1); // items_len |
| ... | @@ -11558,7 +11818,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11558,7 +11818,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11558 | if (emit_bb) try sema.emitBackwardBranch(block, special_prong_src); | 11818 | if (emit_bb) try sema.emitBackwardBranch(block, special_prong_src); |
| 11559 | emit_bb = true; | 11819 | emit_bb = true; |
| 11560 | | 11820 | |
| 11561 | try sema.analyzeBodyRuntimeBreak(&case_block, special.body); | 11821 | try sema.analyzeSwitchProngRuntime( |
| | 11822 | &case_block, |
| | 11823 | raw_operand.val, |
| | 11824 | raw_operand.ptr, |
| | 11825 | .special, |
| | 11826 | special.body, |
| | 11827 | special.capture, |
| | 11828 | .special, |
| | 11829 | else_error_ty, |
| | 11830 | &.{Air.Inst.Ref.bool_false}, |
| | 11831 | inst, |
| | 11832 | ); |
| 11562 | | 11833 | |
| 11563 | try cases_extra.ensureUnusedCapacity(gpa, 3 + case_block.instructions.items.len); | 11834 | try cases_extra.ensureUnusedCapacity(gpa, 3 + case_block.instructions.items.len); |
| 11564 | cases_extra.appendAssumeCapacity(1); // items_len | 11835 | cases_extra.appendAssumeCapacity(1); // items_len |
| ... | @@ -11601,7 +11872,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11601,7 +11872,18 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11601 | { | 11872 | { |
| 11602 | // nothing to do here | 11873 | // nothing to do here |
| 11603 | } else if (special.body.len != 0 and analyze_body and !special.is_inline) { | 11874 | } else if (special.body.len != 0 and analyze_body and !special.is_inline) { |
| 11604 | try sema.analyzeBodyRuntimeBreak(&case_block, special.body); | 11875 | try sema.analyzeSwitchProngRuntime( |
| | 11876 | &case_block, |
| | 11877 | raw_operand.val, |
| | 11878 | raw_operand.ptr, |
| | 11879 | .special, |
| | 11880 | special.body, |
| | 11881 | special.capture, |
| | 11882 | .special, |
| | 11883 | else_error_ty, |
| | 11884 | undefined, |
| | 11885 | inst, |
| | 11886 | ); |
| 11605 | } else { | 11887 | } else { |
| 11606 | // We still need a terminator in this block, but we have proven | 11888 | // We still need a terminator in this block, but we have proven |
| 11607 | // that it is unreachable. | 11889 | // that it is unreachable. |
| ... | @@ -11746,7 +12028,7 @@ fn resolveSwitchItemVal( | ... | @@ -11746,7 +12028,7 @@ fn resolveSwitchItemVal( |
| 11746 | else => |e| return e, | 12028 | else => |e| return e, |
| 11747 | }; | 12029 | }; |
| 11748 | | 12030 | |
| 11749 | const val = sema.resolveConstLazyValue(block, .unneeded, item, "") catch |err| switch (err) { | 12031 | const maybe_lazy = sema.resolveConstValue(block, .unneeded, item, "") catch |err| switch (err) { |
| 11750 | error.NeededSourceLocation => { | 12032 | error.NeededSourceLocation => { |
| 11751 | const src = switch_prong_src.resolve(mod, mod.declPtr(block.src_decl), switch_node_offset, range_expand); | 12033 | const src = switch_prong_src.resolve(mod, mod.declPtr(block.src_decl), switch_node_offset, range_expand); |
| 11752 | _ = try sema.resolveConstValue(block, src, item, "switch prong values must be comptime-known"); | 12034 | _ = try sema.resolveConstValue(block, src, item, "switch prong values must be comptime-known"); |
| ... | @@ -11755,7 +12037,12 @@ fn resolveSwitchItemVal( | ... | @@ -11755,7 +12037,12 @@ fn resolveSwitchItemVal( |
| 11755 | else => |e| return e, | 12037 | else => |e| return e, |
| 11756 | }; | 12038 | }; |
| 11757 | | 12039 | |
| 11758 | return .{ .ref = item, .val = val.toIntern() }; | 12040 | const val = try sema.resolveLazyValue(maybe_lazy); |
| | 12041 | const new_item = if (val.toIntern() != maybe_lazy.toIntern()) blk: { |
| | 12042 | break :blk try sema.addConstant(coerce_ty, val); |
| | 12043 | } else item; |
| | 12044 | |
| | 12045 | return .{ .ref = new_item, .val = val.toIntern() }; |
| 11759 | } | 12046 | } |
| 11760 | | 12047 | |
| 11761 | fn validateSwitchRange( | 12048 | fn validateSwitchRange( |