| ... | @@ -747,10 +747,8 @@ fn analyzeBodyInner( | ... | @@ -747,10 +747,8 @@ fn analyzeBodyInner( |
| 747 | .int_to_enum => try sema.zirIntToEnum(block, inst), | 747 | .int_to_enum => try sema.zirIntToEnum(block, inst), |
| 748 | .err_union_code => try sema.zirErrUnionCode(block, inst), | 748 | .err_union_code => try sema.zirErrUnionCode(block, inst), |
| 749 | .err_union_code_ptr => try sema.zirErrUnionCodePtr(block, inst), | 749 | .err_union_code_ptr => try sema.zirErrUnionCodePtr(block, inst), |
| 750 | .err_union_payload_safe => try sema.zirErrUnionPayload(block, inst, true), | 750 | .err_union_payload_unsafe => try sema.zirErrUnionPayload(block, inst), |
| 751 | .err_union_payload_safe_ptr => try sema.zirErrUnionPayloadPtr(block, inst, true), | 751 | .err_union_payload_unsafe_ptr => try sema.zirErrUnionPayloadPtr(block, inst), |
| 752 | .err_union_payload_unsafe => try sema.zirErrUnionPayload(block, inst, false), | | |
| 753 | .err_union_payload_unsafe_ptr => try sema.zirErrUnionPayloadPtr(block, inst, false), | | |
| 754 | .error_union_type => try sema.zirErrorUnionType(block, inst), | 752 | .error_union_type => try sema.zirErrorUnionType(block, inst), |
| 755 | .error_value => try sema.zirErrorValue(block, inst), | 753 | .error_value => try sema.zirErrorValue(block, inst), |
| 756 | .field_ptr => try sema.zirFieldPtr(block, inst, false), | 754 | .field_ptr => try sema.zirFieldPtr(block, inst, false), |
| ... | @@ -1355,6 +1353,8 @@ fn analyzeBodyInner( | ... | @@ -1355,6 +1353,8 @@ fn analyzeBodyInner( |
| 1355 | const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]; | 1353 | const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]; |
| 1356 | const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition, "condition in comptime branch must be comptime known"); | 1354 | const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition, "condition in comptime branch must be comptime known"); |
| 1357 | const inline_body = if (cond.val.toBool()) then_body else else_body; | 1355 | const inline_body = if (cond.val.toBool()) then_body else else_body; |
| | 1356 | |
| | 1357 | try sema.maybeErrorUnwrapCondbr(block, inline_body, extra.data.condition, cond_src); |
| 1358 | const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse | 1358 | const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse |
| 1359 | break always_noreturn; | 1359 | break always_noreturn; |
| 1360 | if (inst == break_data.block_inst) { | 1360 | if (inst == break_data.block_inst) { |
| ... | @@ -7426,7 +7426,6 @@ fn zirErrUnionPayload( | ... | @@ -7426,7 +7426,6 @@ fn zirErrUnionPayload( |
| 7426 | sema: *Sema, | 7426 | sema: *Sema, |
| 7427 | block: *Block, | 7427 | block: *Block, |
| 7428 | inst: Zir.Inst.Index, | 7428 | inst: Zir.Inst.Index, |
| 7429 | safety_check: bool, | | |
| 7430 | ) CompileError!Air.Inst.Ref { | 7429 | ) CompileError!Air.Inst.Ref { |
| 7431 | const tracy = trace(@src()); | 7430 | const tracy = trace(@src()); |
| 7432 | defer tracy.end(); | 7431 | defer tracy.end(); |
| ... | @@ -7441,7 +7440,7 @@ fn zirErrUnionPayload( | ... | @@ -7441,7 +7440,7 @@ fn zirErrUnionPayload( |
| 7441 | err_union_ty.fmt(sema.mod), | 7440 | err_union_ty.fmt(sema.mod), |
| 7442 | }); | 7441 | }); |
| 7443 | } | 7442 | } |
| 7444 | return sema.analyzeErrUnionPayload(block, src, err_union_ty, operand, operand_src, safety_check); | 7443 | return sema.analyzeErrUnionPayload(block, src, err_union_ty, operand, operand_src, false); |
| 7445 | } | 7444 | } |
| 7446 | | 7445 | |
| 7447 | fn analyzeErrUnionPayload( | 7446 | fn analyzeErrUnionPayload( |
| ... | @@ -7479,7 +7478,6 @@ fn zirErrUnionPayloadPtr( | ... | @@ -7479,7 +7478,6 @@ fn zirErrUnionPayloadPtr( |
| 7479 | sema: *Sema, | 7478 | sema: *Sema, |
| 7480 | block: *Block, | 7479 | block: *Block, |
| 7481 | inst: Zir.Inst.Index, | 7480 | inst: Zir.Inst.Index, |
| 7482 | safety_check: bool, | | |
| 7483 | ) CompileError!Air.Inst.Ref { | 7481 | ) CompileError!Air.Inst.Ref { |
| 7484 | const tracy = trace(@src()); | 7482 | const tracy = trace(@src()); |
| 7485 | defer tracy.end(); | 7483 | defer tracy.end(); |
| ... | @@ -7488,7 +7486,7 @@ fn zirErrUnionPayloadPtr( | ... | @@ -7488,7 +7486,7 @@ fn zirErrUnionPayloadPtr( |
| 7488 | const operand = try sema.resolveInst(inst_data.operand); | 7486 | const operand = try sema.resolveInst(inst_data.operand); |
| 7489 | const src = inst_data.src(); | 7487 | const src = inst_data.src(); |
| 7490 | | 7488 | |
| 7491 | return sema.analyzeErrUnionPayloadPtr(block, src, operand, safety_check, false); | 7489 | return sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false); |
| 7492 | } | 7490 | } |
| 7493 | | 7491 | |
| 7494 | fn analyzeErrUnionPayloadPtr( | 7492 | fn analyzeErrUnionPayloadPtr( |
| ... | @@ -9247,6 +9245,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -9247,6 +9245,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9247 | var empty_enum = false; | 9245 | var empty_enum = false; |
| 9248 | | 9246 | |
| 9249 | const operand_ty = sema.typeOf(operand); | 9247 | const operand_ty = sema.typeOf(operand); |
| | 9248 | const err_set = operand_ty.zigTypeTag() == .ErrorSet; |
| 9250 | | 9249 | |
| 9251 | var else_error_ty: ?Type = null; | 9250 | var else_error_ty: ?Type = null; |
| 9252 | | 9251 | |
| ... | @@ -9829,6 +9828,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -9829,6 +9828,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9829 | // Validation above ensured these will succeed. | 9828 | // Validation above ensured these will succeed. |
| 9830 | const item_val = sema.resolveConstValue(&child_block, .unneeded, item, undefined) catch unreachable; | 9829 | const item_val = sema.resolveConstValue(&child_block, .unneeded, item, undefined) catch unreachable; |
| 9831 | if (operand_val.eql(item_val, operand_ty, sema.mod)) { | 9830 | if (operand_val.eql(item_val, operand_ty, sema.mod)) { |
| | 9831 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); |
| 9832 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); | 9832 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); |
| 9833 | } | 9833 | } |
| 9834 | } | 9834 | } |
| ... | @@ -9851,6 +9851,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -9851,6 +9851,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9851 | // Validation above ensured these will succeed. | 9851 | // Validation above ensured these will succeed. |
| 9852 | const item_val = sema.resolveConstValue(&child_block, .unneeded, item, undefined) catch unreachable; | 9852 | const item_val = sema.resolveConstValue(&child_block, .unneeded, item, undefined) catch unreachable; |
| 9853 | if (operand_val.eql(item_val, operand_ty, sema.mod)) { | 9853 | if (operand_val.eql(item_val, operand_ty, sema.mod)) { |
| | 9854 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); |
| 9854 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); | 9855 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); |
| 9855 | } | 9856 | } |
| 9856 | } | 9857 | } |
| ... | @@ -9868,6 +9869,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -9868,6 +9869,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9868 | if ((try sema.compare(block, src, operand_val, .gte, first_tv.val, operand_ty)) and | 9869 | if ((try sema.compare(block, src, operand_val, .gte, first_tv.val, operand_ty)) and |
| 9869 | (try sema.compare(block, src, operand_val, .lte, last_tv.val, operand_ty))) | 9870 | (try sema.compare(block, src, operand_val, .lte, last_tv.val, operand_ty))) |
| 9870 | { | 9871 | { |
| | 9872 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, body, operand); |
| 9871 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); | 9873 | return sema.resolveBlockBody(block, src, &child_block, body, inst, merges); |
| 9872 | } | 9874 | } |
| 9873 | } | 9875 | } |
| ... | @@ -9875,6 +9877,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -9875,6 +9877,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9875 | extra_index += body_len; | 9877 | extra_index += body_len; |
| 9876 | } | 9878 | } |
| 9877 | } | 9879 | } |
| | 9880 | if (err_set) try sema.maybeErrorUnwrapComptime(&child_block, special.body, operand); |
| 9878 | return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges); | 9881 | return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges); |
| 9879 | } | 9882 | } |
| 9880 | | 9883 | |
| ... | @@ -9885,6 +9888,9 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -9885,6 +9888,9 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9885 | if (special_prong == .none) { | 9888 | if (special_prong == .none) { |
| 9886 | return sema.fail(block, src, "switch must handle all possibilities", .{}); | 9889 | return sema.fail(block, src, "switch must handle all possibilities", .{}); |
| 9887 | } | 9890 | } |
| | 9891 | if (err_set and try sema.maybeErrorUnwrap(block, special.body, operand)) { |
| | 9892 | return Air.Inst.Ref.unreachable_value; |
| | 9893 | } |
| 9888 | return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges); | 9894 | return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges); |
| 9889 | } | 9895 | } |
| 9890 | | 9896 | |
| ... | @@ -9927,7 +9933,9 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -9927,7 +9933,9 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9927 | break :blk field_ty.zigTypeTag() != .NoReturn; | 9933 | break :blk field_ty.zigTypeTag() != .NoReturn; |
| 9928 | } else true; | 9934 | } else true; |
| 9929 | | 9935 | |
| 9930 | if (analyze_body) { | 9936 | if (err_set and try sema.maybeErrorUnwrap(&case_block, body, operand)) { |
| | 9937 | // nothing to do here |
| | 9938 | } else if (analyze_body) { |
| 9931 | _ = sema.analyzeBodyInner(&case_block, body) catch |err| switch (err) { | 9939 | _ = sema.analyzeBodyInner(&case_block, body) catch |err| switch (err) { |
| 9932 | error.ComptimeBreak => { | 9940 | error.ComptimeBreak => { |
| 9933 | const zir_datas = sema.code.instructions.items(.data); | 9941 | const zir_datas = sema.code.instructions.items(.data); |
| ... | @@ -9995,7 +10003,9 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -9995,7 +10003,9 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 9995 | | 10003 | |
| 9996 | const body = sema.code.extra[extra_index..][0..body_len]; | 10004 | const body = sema.code.extra[extra_index..][0..body_len]; |
| 9997 | extra_index += body_len; | 10005 | extra_index += body_len; |
| 9998 | if (analyze_body) { | 10006 | if (err_set and try sema.maybeErrorUnwrap(&case_block, body, operand)) { |
| | 10007 | // nothing to do here |
| | 10008 | } else if (analyze_body) { |
| 9999 | _ = sema.analyzeBodyInner(&case_block, body) catch |err| switch (err) { | 10009 | _ = sema.analyzeBodyInner(&case_block, body) catch |err| switch (err) { |
| 10000 | error.ComptimeBreak => { | 10010 | error.ComptimeBreak => { |
| 10001 | const zir_datas = sema.code.instructions.items(.data); | 10011 | const zir_datas = sema.code.instructions.items(.data); |
| ... | @@ -10085,18 +10095,22 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10085,18 +10095,22 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10085 | | 10095 | |
| 10086 | const body = sema.code.extra[extra_index..][0..body_len]; | 10096 | const body = sema.code.extra[extra_index..][0..body_len]; |
| 10087 | extra_index += body_len; | 10097 | extra_index += body_len; |
| 10088 | _ = sema.analyzeBodyInner(&case_block, body) catch |err| switch (err) { | 10098 | if (err_set and try sema.maybeErrorUnwrap(&case_block, body, operand)) { |
| 10089 | error.ComptimeBreak => { | 10099 | // nothing to do here |
| 10090 | const zir_datas = sema.code.instructions.items(.data); | 10100 | } else { |
| 10091 | const break_data = zir_datas[sema.comptime_break_inst].@"break"; | 10101 | _ = sema.analyzeBodyInner(&case_block, body) catch |err| switch (err) { |
| 10092 | try sema.addRuntimeBreak(&case_block, .{ | 10102 | error.ComptimeBreak => { |
| 10093 | .block_inst = break_data.block_inst, | 10103 | const zir_datas = sema.code.instructions.items(.data); |
| 10094 | .operand = break_data.operand, | 10104 | const break_data = zir_datas[sema.comptime_break_inst].@"break"; |
| 10095 | .inst = sema.comptime_break_inst, | 10105 | try sema.addRuntimeBreak(&case_block, .{ |
| 10096 | }); | 10106 | .block_inst = break_data.block_inst, |
| 10097 | }, | 10107 | .operand = break_data.operand, |
| 10098 | else => |e| return e, | 10108 | .inst = sema.comptime_break_inst, |
| 10099 | }; | 10109 | }); |
| | 10110 | }, |
| | 10111 | else => |e| return e, |
| | 10112 | }; |
| | 10113 | } |
| 10100 | | 10114 | |
| 10101 | try wip_captures.finalize(); | 10115 | try wip_captures.finalize(); |
| 10102 | | 10116 | |
| ... | @@ -10141,8 +10155,11 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10141,8 +10155,11 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10141 | } else false | 10155 | } else false |
| 10142 | else | 10156 | else |
| 10143 | true; | 10157 | true; |
| 10144 | | 10158 | if (special.body.len != 0 and err_set and |
| 10145 | if (special.body.len != 0 and analyze_body) { | 10159 | try sema.maybeErrorUnwrap(&case_block, special.body, operand)) |
| | 10160 | { |
| | 10161 | // nothing to do here |
| | 10162 | } else if (special.body.len != 0 and analyze_body) { |
| 10146 | _ = sema.analyzeBodyInner(&case_block, special.body) catch |err| switch (err) { | 10163 | _ = sema.analyzeBodyInner(&case_block, special.body) catch |err| switch (err) { |
| 10147 | error.ComptimeBreak => { | 10164 | error.ComptimeBreak => { |
| 10148 | const zir_datas = sema.code.instructions.items(.data); | 10165 | const zir_datas = sema.code.instructions.items(.data); |
| ... | @@ -10400,6 +10417,109 @@ fn validateSwitchNoRange( | ... | @@ -10400,6 +10417,109 @@ fn validateSwitchNoRange( |
| 10400 | return sema.failWithOwnedErrorMsg(msg); | 10417 | return sema.failWithOwnedErrorMsg(msg); |
| 10401 | } | 10418 | } |
| 10402 | | 10419 | |
| | 10420 | fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, operand: Air.Inst.Ref) !bool { |
| | 10421 | const this_feature_is_implemented_in_the_backend = |
| | 10422 | sema.mod.comp.bin_file.options.use_llvm; |
| | 10423 | |
| | 10424 | if (!this_feature_is_implemented_in_the_backend) return false; |
| | 10425 | |
| | 10426 | const tags = sema.code.instructions.items(.tag); |
| | 10427 | for (body) |inst| { |
| | 10428 | switch (tags[inst]) { |
| | 10429 | .dbg_block_begin, |
| | 10430 | .dbg_block_end, |
| | 10431 | .dbg_stmt, |
| | 10432 | .@"unreachable", |
| | 10433 | .str, |
| | 10434 | .as_node, |
| | 10435 | .panic, |
| | 10436 | .field_val, |
| | 10437 | => {}, |
| | 10438 | else => return false, |
| | 10439 | } |
| | 10440 | } |
| | 10441 | |
| | 10442 | for (body) |inst| { |
| | 10443 | const air_inst = switch (tags[inst]) { |
| | 10444 | .dbg_block_begin, |
| | 10445 | .dbg_block_end, |
| | 10446 | => continue, |
| | 10447 | .dbg_stmt => { |
| | 10448 | try sema.zirDbgStmt(block, inst); |
| | 10449 | continue; |
| | 10450 | }, |
| | 10451 | .str => try sema.zirStr(block, inst), |
| | 10452 | .as_node => try sema.zirAsNode(block, inst), |
| | 10453 | .field_val => try sema.zirFieldVal(block, inst), |
| | 10454 | .@"unreachable" => { |
| | 10455 | const inst_data = sema.code.instructions.items(.data)[inst].@"unreachable"; |
| | 10456 | const src = inst_data.src(); |
| | 10457 | |
| | 10458 | const panic_fn = try sema.getBuiltin(block, src, "panicUnwrapError"); |
| | 10459 | const err_return_trace = try sema.getErrorReturnTrace(block, src); |
| | 10460 | const args: [2]Air.Inst.Ref = .{ err_return_trace, operand }; |
| | 10461 | _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, &args, null); |
| | 10462 | return true; |
| | 10463 | }, |
| | 10464 | .panic => { |
| | 10465 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| | 10466 | const src = inst_data.src(); |
| | 10467 | const msg_inst = try sema.resolveInst(inst_data.operand); |
| | 10468 | |
| | 10469 | const panic_fn = try sema.getBuiltin(block, src, "panic"); |
| | 10470 | const err_return_trace = try sema.getErrorReturnTrace(block, src); |
| | 10471 | const args: [2]Air.Inst.Ref = .{ msg_inst, err_return_trace }; |
| | 10472 | _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, &args, null); |
| | 10473 | return true; |
| | 10474 | }, |
| | 10475 | else => unreachable, |
| | 10476 | }; |
| | 10477 | if (sema.typeOf(air_inst).isNoReturn()) |
| | 10478 | return true; |
| | 10479 | try sema.inst_map.put(sema.gpa, inst, air_inst); |
| | 10480 | } |
| | 10481 | unreachable; |
| | 10482 | } |
| | 10483 | |
| | 10484 | fn maybeErrorUnwrapCondbr(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, cond: Zir.Inst.Ref, cond_src: LazySrcLoc) !void { |
| | 10485 | const index = Zir.refToIndex(cond) orelse return; |
| | 10486 | if (sema.code.instructions.items(.tag)[index] != .is_non_err) return; |
| | 10487 | |
| | 10488 | const err_inst_data = sema.code.instructions.items(.data)[index].un_node; |
| | 10489 | const err_operand = try sema.resolveInst(err_inst_data.operand); |
| | 10490 | const operand_ty = sema.typeOf(err_operand); |
| | 10491 | if (operand_ty.zigTypeTag() == .ErrorSet) { |
| | 10492 | try sema.maybeErrorUnwrapComptime(block, body, err_operand); |
| | 10493 | return; |
| | 10494 | } |
| | 10495 | if (try sema.resolveDefinedValue(block, cond_src, err_operand)) |val| { |
| | 10496 | if (val.getError() == null) return; |
| | 10497 | try sema.maybeErrorUnwrapComptime(block, body, err_operand); |
| | 10498 | } |
| | 10499 | } |
| | 10500 | |
| | 10501 | fn maybeErrorUnwrapComptime(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, operand: Air.Inst.Ref) !void { |
| | 10502 | const tags = sema.code.instructions.items(.tag); |
| | 10503 | const inst = for (body) |inst| { |
| | 10504 | switch (tags[inst]) { |
| | 10505 | .dbg_block_begin, |
| | 10506 | .dbg_block_end, |
| | 10507 | .dbg_stmt, |
| | 10508 | => {}, |
| | 10509 | .@"unreachable" => break inst, |
| | 10510 | else => return, |
| | 10511 | } |
| | 10512 | } else return; |
| | 10513 | const inst_data = sema.code.instructions.items(.data)[inst].@"unreachable"; |
| | 10514 | const src = inst_data.src(); |
| | 10515 | |
| | 10516 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { |
| | 10517 | if (val.getError()) |name| { |
| | 10518 | return sema.fail(block, src, "caught unexpected error '{s}'", .{name}); |
| | 10519 | } |
| | 10520 | } |
| | 10521 | } |
| | 10522 | |
| 10403 | fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 10523 | fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 10404 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 10524 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 10405 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 10525 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| ... | @@ -15152,6 +15272,8 @@ fn zirCondbr( | ... | @@ -15152,6 +15272,8 @@ fn zirCondbr( |
| 15152 | | 15272 | |
| 15153 | if (try sema.resolveDefinedValue(parent_block, cond_src, cond)) |cond_val| { | 15273 | if (try sema.resolveDefinedValue(parent_block, cond_src, cond)) |cond_val| { |
| 15154 | const body = if (cond_val.toBool()) then_body else else_body; | 15274 | const body = if (cond_val.toBool()) then_body else else_body; |
| | 15275 | |
| | 15276 | try sema.maybeErrorUnwrapCondbr(parent_block, body, extra.data.condition, cond_src); |
| 15155 | // We use `analyzeBodyInner` since we want to propagate any possible | 15277 | // We use `analyzeBodyInner` since we want to propagate any possible |
| 15156 | // `error.ComptimeBreak` to the caller. | 15278 | // `error.ComptimeBreak` to the caller. |
| 15157 | return sema.analyzeBodyInner(parent_block, body); | 15279 | return sema.analyzeBodyInner(parent_block, body); |
| ... | @@ -15182,18 +15304,34 @@ fn zirCondbr( | ... | @@ -15182,18 +15304,34 @@ fn zirCondbr( |
| 15182 | const true_instructions = sub_block.instructions.toOwnedSlice(gpa); | 15304 | const true_instructions = sub_block.instructions.toOwnedSlice(gpa); |
| 15183 | defer gpa.free(true_instructions); | 15305 | defer gpa.free(true_instructions); |
| 15184 | | 15306 | |
| 15185 | _ = sema.analyzeBodyInner(&sub_block, else_body) catch |err| switch (err) { | 15307 | const err_cond = blk: { |
| 15186 | error.ComptimeBreak => { | 15308 | const index = Zir.refToIndex(extra.data.condition) orelse break :blk null; |
| 15187 | const zir_datas = sema.code.instructions.items(.data); | 15309 | if (sema.code.instructions.items(.tag)[index] != .is_non_err) break :blk null; |
| 15188 | const break_data = zir_datas[sema.comptime_break_inst].@"break"; | 15310 | |
| 15189 | try sema.addRuntimeBreak(&sub_block, .{ | 15311 | const err_inst_data = sema.code.instructions.items(.data)[index].un_node; |
| 15190 | .block_inst = break_data.block_inst, | 15312 | const err_operand = try sema.resolveInst(err_inst_data.operand); |
| 15191 | .operand = break_data.operand, | 15313 | const operand_ty = sema.typeOf(err_operand); |
| 15192 | .inst = sema.comptime_break_inst, | 15314 | assert(operand_ty.zigTypeTag() == .ErrorUnion); |
| 15193 | }); | 15315 | const result_ty = operand_ty.errorUnionSet(); |
| 15194 | }, | 15316 | break :blk try sub_block.addTyOp(.unwrap_errunion_err, result_ty, err_operand); |
| 15195 | else => |e| return e, | | |
| 15196 | }; | 15317 | }; |
| | 15318 | |
| | 15319 | if (err_cond != null and try sema.maybeErrorUnwrap(&sub_block, else_body, err_cond.?)) { |
| | 15320 | // nothing to do |
| | 15321 | } else { |
| | 15322 | _ = sema.analyzeBodyInner(&sub_block, else_body) catch |err| switch (err) { |
| | 15323 | error.ComptimeBreak => { |
| | 15324 | const zir_datas = sema.code.instructions.items(.data); |
| | 15325 | const break_data = zir_datas[sema.comptime_break_inst].@"break"; |
| | 15326 | try sema.addRuntimeBreak(&sub_block, .{ |
| | 15327 | .block_inst = break_data.block_inst, |
| | 15328 | .operand = break_data.operand, |
| | 15329 | .inst = sema.comptime_break_inst, |
| | 15330 | }); |
| | 15331 | }, |
| | 15332 | else => |e| return e, |
| | 15333 | }; |
| | 15334 | } |
| 15197 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).Struct.fields.len + | 15335 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).Struct.fields.len + |
| 15198 | true_instructions.len + sub_block.instructions.items.len); | 15336 | true_instructions.len + sub_block.instructions.items.len); |
| 15199 | _ = try parent_block.addInst(.{ | 15337 | _ = try parent_block.addInst(.{ |