| ... | ... | @@ -2418,6 +2418,32 @@ fn failWithModRemNegative(sema: *Sema, block: *Block, src: LazySrcLoc, lhs_ty: T |
| 2418 | 2418 | }); |
| 2419 | 2419 | } |
| 2420 | 2420 | |
| 2421 | fn failWithInvalidSwitchTagCapture(sema: *Sema, block: *Block, tag_capture_src: LazySrcLoc, operand_ty: Type) CompileError { |
| 2422 | const pt = sema.pt; |
| 2423 | const zcu = pt.zcu; |
| 2424 | |
| 2425 | if (operand_ty.zigTypeTag(zcu) == .@"union") { |
| 2426 | assert(operand_ty.containerLayout(zcu) == .@"packed"); |
| 2427 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 2428 | const msg = try sema.errMsg(tag_capture_src, "cannot capture tag of packed union", .{}); |
| 2429 | errdefer msg.destroy(sema.gpa); |
| 2430 | try sema.addDeclaredHereNote(msg, operand_ty); |
| 2431 | if (operand_ty.srcLocOrNull(zcu)) |ty_src| { |
| 2432 | try sema.errNote(ty_src, msg, "consider using a tagged union", .{}); |
| 2433 | } |
| 2434 | break :msg msg; |
| 2435 | }); |
| 2436 | } |
| 2437 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 2438 | const msg = try sema.errMsg(tag_capture_src, "cannot capture tag of non-union type '{f}'", .{ |
| 2439 | operand_ty.fmt(pt), |
| 2440 | }); |
| 2441 | errdefer msg.destroy(sema.gpa); |
| 2442 | try sema.addDeclaredHereNote(msg, operand_ty); |
| 2443 | break :msg msg; |
| 2444 | }); |
| 2445 | } |
| 2446 | |
| 2421 | 2447 | fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, non_optional_ty: Type) CompileError { |
| 2422 | 2448 | const pt = sema.pt; |
| 2423 | 2449 | const msg = msg: { |
| ... | ... | @@ -10216,7 +10242,7 @@ fn analyzeSwitchBlock( |
| 10216 | 10242 | |
| 10217 | 10243 | const case_vals = validated_switch.case_vals; |
| 10218 | 10244 | |
| 10219 | | const body, const capture, const has_tag_capture = find_prong: { |
| 10245 | const case_idx, const body, const capture, const has_tag_capture = find_prong: { |
| 10220 | 10246 | var case_val_idx: usize = 0; |
| 10221 | 10247 | var case_it = zir_switch.iterateCases(); |
| 10222 | 10248 | var extra_index = zir_switch.end; |
| ... | ... | @@ -10239,12 +10265,12 @@ fn analyzeSwitchBlock( |
| 10239 | 10265 | } |
| 10240 | 10266 | continue; |
| 10241 | 10267 | } |
| 10242 | | break :find_prong .{ prong_body, prong_info.capture, prong_info.has_tag_capture }; |
| 10268 | break :find_prong .{ case.index, prong_body, prong_info.capture, prong_info.has_tag_capture }; |
| 10243 | 10269 | } |
| 10244 | 10270 | if (has_else) { |
| 10245 | 10271 | // This *has* to be checked after iterating all regular cases because |
| 10246 | 10272 | // we allow simple noreturn else prongs when switching on error sets! |
| 10247 | | break :find_prong .{ else_case.body, else_case.capture, else_case.has_tag_capture }; |
| 10273 | break :find_prong .{ else_case.index, else_case.body, else_case.capture, else_case.has_tag_capture }; |
| 10248 | 10274 | } |
| 10249 | 10275 | unreachable; // malformed validated switch |
| 10250 | 10276 | }; |
| ... | ... | @@ -10289,6 +10315,13 @@ fn analyzeSwitchBlock( |
| 10289 | 10315 | |
| 10290 | 10316 | const tag_inst: Zir.Inst.Index = if (has_tag_capture) inst: { |
| 10291 | 10317 | const tag_inst = zir_switch.tag_capture_placeholder.unwrap() orelse switch_inst; |
| 10318 | if (!tagged_union_originally) { |
| 10319 | const tag_capture_src = block.src(.{ .switch_tag_capture = .{ |
| 10320 | .switch_node_offset = src_node_offset, |
| 10321 | .case_idx = case_idx, |
| 10322 | } }); |
| 10323 | return sema.failWithInvalidSwitchTagCapture(block, tag_capture_src, operand_ty); |
| 10324 | } |
| 10292 | 10325 | sema.inst_map.putAssumeCapacity(tag_inst, .fromValue(item_opv)); |
| 10293 | 10326 | break :inst tag_inst; |
| 10294 | 10327 | } else undefined; |
| ... | ... | @@ -12157,26 +12190,7 @@ fn analyzeSwitchCaptures( |
| 12157 | 12190 | .base_node_inst = capture_src.base_node_inst, |
| 12158 | 12191 | .offset = .{ .switch_tag_capture = capture_src.offset.switch_capture }, |
| 12159 | 12192 | }; |
| 12160 | | if (operand_ty.zigTypeTag(zcu) == .@"union") { |
| 12161 | | assert(operand_ty.containerLayout(zcu) == .@"packed"); |
| 12162 | | return sema.failWithOwnedErrorMsg(case_block, msg: { |
| 12163 | | const msg = try sema.errMsg(tag_capture_src, "cannot capture tag of packed union", .{}); |
| 12164 | | errdefer msg.destroy(sema.gpa); |
| 12165 | | try sema.addDeclaredHereNote(msg, operand_ty); |
| 12166 | | if (operand_ty.srcLocOrNull(zcu)) |ty_src| { |
| 12167 | | try sema.errNote(ty_src, msg, "consider using a tagged union", .{}); |
| 12168 | | } |
| 12169 | | break :msg msg; |
| 12170 | | }); |
| 12171 | | } |
| 12172 | | return sema.failWithOwnedErrorMsg(case_block, msg: { |
| 12173 | | const msg = try sema.errMsg(tag_capture_src, "cannot capture tag of non-union type '{f}'", .{ |
| 12174 | | operand_ty.fmt(pt), |
| 12175 | | }); |
| 12176 | | errdefer msg.destroy(sema.gpa); |
| 12177 | | try sema.addDeclaredHereNote(msg, operand_ty); |
| 12178 | | break :msg msg; |
| 12179 | | }); |
| 12193 | return sema.failWithInvalidSwitchTagCapture(case_block, tag_capture_src, operand_ty); |
| 12180 | 12194 | } |
| 12181 | 12195 | |
| 12182 | 12196 | return .{ .payload_ref = payload_ref, .tag_ref = .none }; |