| ... | @@ -10581,7 +10581,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp | ... | @@ -10581,7 +10581,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 10581 | // Then we analyze the non-error prong if it's not comptime-unreachable. | 10581 | // Then we analyze the non-error prong if it's not comptime-unreachable. |
| 10582 | // Lastly, we analyze the error prong(s) as a regular switch. | 10582 | // Lastly, we analyze the error prong(s) as a regular switch. |
| 10583 | | 10583 | |
| 10584 | const raw_switch_operand, const non_err_reachable, const non_err_cond, const non_err_hint, const err_set_empty = non_err: { | 10584 | const raw_switch_operand, const non_err_cond, const non_err_hint = non_err: { |
| 10585 | const eu_maybe_ptr = try sema.resolveInst(zir_switch.main_operand); | 10585 | const eu_maybe_ptr = try sema.resolveInst(zir_switch.main_operand); |
| 10586 | const err_union_ty: Type = err_union_ty: { | 10586 | const err_union_ty: Type = err_union_ty: { |
| 10587 | const raw_operand_ty = sema.typeOf(eu_maybe_ptr); | 10587 | const raw_operand_ty = sema.typeOf(eu_maybe_ptr); |
| ... | @@ -10600,17 +10600,9 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp | ... | @@ -10600,17 +10600,9 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 10600 | else | 10600 | else |
| 10601 | try sema.analyzeIsNonErr(block, operand_src, eu_maybe_ptr); | 10601 | try sema.analyzeIsNonErr(block, operand_src, eu_maybe_ptr); |
| 10602 | | 10602 | |
| 10603 | const is_non_err = try sema.resolveDefinedValue(block, operand_src, non_err_cond); | | |
| 10604 | const non_err_reachable = if (is_non_err) |val| val.toBool() else true; | | |
| 10605 | | | |
| 10606 | const err_set_empty = err_set_empty: { | | |
| 10607 | const err_set_ty = err_union_ty.errorUnionSet(zcu); | | |
| 10608 | break :err_set_empty err_set_ty.errorSetIsEmpty(zcu); | | |
| 10609 | }; | | |
| 10610 | | | |
| 10611 | const non_err_hint: std.builtin.BranchHint = hint: { | 10603 | const non_err_hint: std.builtin.BranchHint = hint: { |
| 10612 | // don't analyze the non-error body if it's unreachable | 10604 | // don't analyze the non-error body if it's unreachable |
| 10613 | if (!non_err_reachable) { | 10605 | if (non_err_cond == .bool_false) { |
| 10614 | break :hint undefined; | 10606 | break :hint undefined; |
| 10615 | } | 10607 | } |
| 10616 | | 10608 | |
| ... | @@ -10622,8 +10614,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp | ... | @@ -10622,8 +10614,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 10622 | if (non_err_case.capture != .none) sema.inst_map.putAssumeCapacity(inst, eu_payload); | 10614 | if (non_err_case.capture != .none) sema.inst_map.putAssumeCapacity(inst, eu_payload); |
| 10623 | defer if (non_err_case.capture != .none) assert(sema.inst_map.remove(inst)); | 10615 | defer if (non_err_case.capture != .none) assert(sema.inst_map.remove(inst)); |
| 10624 | | 10616 | |
| 10625 | const always_non_err = if (is_non_err) |val| val.toBool() else err_set_empty; | 10617 | if (non_err_cond == .bool_true) { |
| 10626 | if (always_non_err) { | | |
| 10627 | // Early return; we don't analyze the switch as it's unreachable. | 10618 | // Early return; we don't analyze the switch as it's unreachable. |
| 10628 | return sema.resolveBlockBody(block, src, &non_err_block, non_err_case.body, inst, merges); | 10619 | return sema.resolveBlockBody(block, src, &non_err_block, non_err_case.body, inst, merges); |
| 10629 | } | 10620 | } |
| ... | @@ -10636,20 +10627,23 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp | ... | @@ -10636,20 +10627,23 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp |
| 10636 | else | 10627 | else |
| 10637 | try sema.analyzeErrUnionCode(&switch_block, operand_src, eu_maybe_ptr); | 10628 | try sema.analyzeErrUnionCode(&switch_block, operand_src, eu_maybe_ptr); |
| 10638 | | 10629 | |
| 10639 | break :non_err .{ eu_code, non_err_reachable, non_err_cond, non_err_hint, err_set_empty }; | 10630 | break :non_err .{ |
| | 10631 | eu_code, |
| | 10632 | non_err_cond, |
| | 10633 | non_err_hint, |
| | 10634 | }; |
| 10640 | }; | 10635 | }; |
| 10641 | | 10636 | |
| 10642 | const validated_switch = try sema.validateSwitchBlock(block, raw_switch_operand, false, inst, &zir_switch); | 10637 | const validated_switch = try sema.validateSwitchBlock(block, raw_switch_operand, false, inst, &zir_switch); |
| 10643 | | 10638 | |
| 10644 | const maybe_switch_ref: ?Air.Inst.Ref = ref: { | 10639 | const maybe_switch_ref: ?Air.Inst.Ref = ref: { |
| 10645 | if (err_set_empty) break :ref .unreachable_value; | | |
| 10646 | // make err capture (i.e. switch operand) available to switch prong bodies | 10640 | // make err capture (i.e. switch operand) available to switch prong bodies |
| 10647 | sema.inst_map.putAssumeCapacityNoClobber(inst, raw_switch_operand); | 10641 | sema.inst_map.putAssumeCapacityNoClobber(inst, raw_switch_operand); |
| 10648 | defer assert(sema.inst_map.remove(inst)); | 10642 | defer assert(sema.inst_map.remove(inst)); |
| 10649 | break :ref try sema.analyzeSwitchBlock(block, &switch_block, raw_switch_operand, false, merges, inst, &zir_switch, &validated_switch); | 10643 | break :ref try sema.analyzeSwitchBlock(block, &switch_block, raw_switch_operand, false, merges, inst, &zir_switch, &validated_switch); |
| 10650 | }; | 10644 | }; |
| 10651 | | 10645 | |
| 10652 | if (!non_err_reachable) { | 10646 | if (non_err_cond == .bool_false) { |
| 10653 | return maybe_switch_ref orelse { | 10647 | return maybe_switch_ref orelse { |
| 10654 | const switch_src = block.nodeOffset(zir_switch.switch_src_node_offset); | 10648 | const switch_src = block.nodeOffset(zir_switch.switch_src_node_offset); |
| 10655 | return sema.resolveAnalyzedBlock(block, switch_src, &switch_block, merges, false); | 10649 | return sema.resolveAnalyzedBlock(block, switch_src, &switch_block, merges, false); |