| ... | ... | @@ -6248,8 +6248,7 @@ fn zirErrUnionPayload( |
| 6248 | 6248 | } |
| 6249 | 6249 | try sema.requireRuntimeBlock(block, src); |
| 6250 | 6250 | if (safety_check and block.wantSafety()) { |
| 6251 | | const is_non_err = try block.addUnOp(.is_err, operand); |
| 6252 | | try sema.addSafetyCheck(block, is_non_err, .unwrap_errunion); |
| 6251 | try sema.panicUnwrapError(block, src, operand, .unwrap_errunion_err, .is_non_err); |
| 6253 | 6252 | } |
| 6254 | 6253 | const result_ty = operand_ty.errorUnionPayload(); |
| 6255 | 6254 | return block.addTyOp(.unwrap_errunion_payload, result_ty, operand); |
| ... | ... | @@ -6330,8 +6329,7 @@ fn analyzeErrUnionPayloadPtr( |
| 6330 | 6329 | |
| 6331 | 6330 | try sema.requireRuntimeBlock(block, src); |
| 6332 | 6331 | if (safety_check and block.wantSafety()) { |
| 6333 | | const is_non_err = try block.addUnOp(.is_err, operand); |
| 6334 | | try sema.addSafetyCheck(block, is_non_err, .unwrap_errunion); |
| 6332 | try sema.panicUnwrapError(block, src, operand, .unwrap_errunion_err_ptr, .is_non_err_ptr); |
| 6335 | 6333 | } |
| 6336 | 6334 | const air_tag: Air.Inst.Tag = if (initializing) |
| 6337 | 6335 | .errunion_payload_ptr_set |
| ... | ... | @@ -13400,6 +13398,10 @@ fn zirErrorReturnTrace( |
| 13400 | 13398 | extended: Zir.Inst.Extended.InstData, |
| 13401 | 13399 | ) CompileError!Air.Inst.Ref { |
| 13402 | 13400 | const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) }; |
| 13401 | return sema.getErrorReturnTrace(block, src); |
| 13402 | } |
| 13403 | |
| 13404 | fn getErrorReturnTrace(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError!Air.Inst.Ref { |
| 13403 | 13405 | const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace"); |
| 13404 | 13406 | const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty); |
| 13405 | 13407 | const opt_ptr_stack_trace_ty = try Type.Tag.optional_single_mut_pointer.create(sema.arena, stack_trace_ty); |
| ... | ... | @@ -16852,7 +16854,6 @@ fn explainWhyTypeIsComptime( |
| 16852 | 16854 | pub const PanicId = enum { |
| 16853 | 16855 | unreach, |
| 16854 | 16856 | unwrap_null, |
| 16855 | | unwrap_errunion, |
| 16856 | 16857 | cast_to_null, |
| 16857 | 16858 | incorrect_alignment, |
| 16858 | 16859 | invalid_error_code, |
| ... | ... | @@ -16962,12 +16963,100 @@ fn panicWithMsg( |
| 16962 | 16963 | try Type.optional(arena, ptr_stack_trace_ty), |
| 16963 | 16964 | Value.@"null", |
| 16964 | 16965 | ); |
| 16965 | | const args = try arena.create([2]Air.Inst.Ref); |
| 16966 | | args.* = .{ msg_inst, null_stack_trace }; |
| 16967 | | _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, args); |
| 16966 | const args: [2]Air.Inst.Ref = .{ msg_inst, null_stack_trace }; |
| 16967 | _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, &args); |
| 16968 | 16968 | return always_noreturn; |
| 16969 | 16969 | } |
| 16970 | 16970 | |
| 16971 | fn panicUnwrapError( |
| 16972 | sema: *Sema, |
| 16973 | parent_block: *Block, |
| 16974 | src: LazySrcLoc, |
| 16975 | operand: Air.Inst.Ref, |
| 16976 | unwrap_err_tag: Air.Inst.Tag, |
| 16977 | is_non_err_tag: Air.Inst.Tag, |
| 16978 | ) !void { |
| 16979 | const ok = try parent_block.addUnOp(is_non_err_tag, operand); |
| 16980 | const gpa = sema.gpa; |
| 16981 | |
| 16982 | var fail_block: Block = .{ |
| 16983 | .parent = parent_block, |
| 16984 | .sema = sema, |
| 16985 | .src_decl = parent_block.src_decl, |
| 16986 | .namespace = parent_block.namespace, |
| 16987 | .wip_capture_scope = parent_block.wip_capture_scope, |
| 16988 | .instructions = .{}, |
| 16989 | .inlining = parent_block.inlining, |
| 16990 | .is_comptime = parent_block.is_comptime, |
| 16991 | }; |
| 16992 | |
| 16993 | defer fail_block.instructions.deinit(gpa); |
| 16994 | |
| 16995 | { |
| 16996 | const this_feature_is_implemented_in_the_backend = |
| 16997 | sema.mod.comp.bin_file.options.object_format == .c or |
| 16998 | sema.mod.comp.bin_file.options.use_llvm; |
| 16999 | |
| 17000 | if (!this_feature_is_implemented_in_the_backend) { |
| 17001 | // TODO implement this feature in all the backends and then delete this branch |
| 17002 | _ = try fail_block.addNoOp(.breakpoint); |
| 17003 | _ = try fail_block.addNoOp(.unreach); |
| 17004 | } else { |
| 17005 | const panic_fn = try sema.getBuiltin(&fail_block, src, "panicUnwrapError"); |
| 17006 | const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand); |
| 17007 | const err_return_trace = try sema.getErrorReturnTrace(&fail_block, src); |
| 17008 | const args: [2]Air.Inst.Ref = .{ err_return_trace, err }; |
| 17009 | _ = try sema.analyzeCall(&fail_block, panic_fn, src, src, .auto, false, &args); |
| 17010 | } |
| 17011 | } |
| 17012 | |
| 17013 | try parent_block.instructions.ensureUnusedCapacity(gpa, 1); |
| 17014 | |
| 17015 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + |
| 17016 | 1 + // The main block only needs space for the cond_br. |
| 17017 | @typeInfo(Air.CondBr).Struct.fields.len + |
| 17018 | 1 + // The ok branch of the cond_br only needs space for the br. |
| 17019 | fail_block.instructions.items.len); |
| 17020 | |
| 17021 | try sema.air_instructions.ensureUnusedCapacity(gpa, 3); |
| 17022 | const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len); |
| 17023 | const cond_br_inst = block_inst + 1; |
| 17024 | const br_inst = cond_br_inst + 1; |
| 17025 | sema.air_instructions.appendAssumeCapacity(.{ |
| 17026 | .tag = .block, |
| 17027 | .data = .{ .ty_pl = .{ |
| 17028 | .ty = .void_type, |
| 17029 | .payload = sema.addExtraAssumeCapacity(Air.Block{ |
| 17030 | .body_len = 1, |
| 17031 | }), |
| 17032 | } }, |
| 17033 | }); |
| 17034 | sema.air_extra.appendAssumeCapacity(cond_br_inst); |
| 17035 | |
| 17036 | sema.air_instructions.appendAssumeCapacity(.{ |
| 17037 | .tag = .cond_br, |
| 17038 | .data = .{ .pl_op = .{ |
| 17039 | .operand = ok, |
| 17040 | .payload = sema.addExtraAssumeCapacity(Air.CondBr{ |
| 17041 | .then_body_len = 1, |
| 17042 | .else_body_len = @intCast(u32, fail_block.instructions.items.len), |
| 17043 | }), |
| 17044 | } }, |
| 17045 | }); |
| 17046 | sema.air_extra.appendAssumeCapacity(br_inst); |
| 17047 | sema.air_extra.appendSliceAssumeCapacity(fail_block.instructions.items); |
| 17048 | |
| 17049 | sema.air_instructions.appendAssumeCapacity(.{ |
| 17050 | .tag = .br, |
| 17051 | .data = .{ .br = .{ |
| 17052 | .block_inst = block_inst, |
| 17053 | .operand = .void_value, |
| 17054 | } }, |
| 17055 | }); |
| 17056 | |
| 17057 | parent_block.instructions.appendAssumeCapacity(block_inst); |
| 17058 | } |
| 17059 | |
| 16971 | 17060 | fn safetyPanic( |
| 16972 | 17061 | sema: *Sema, |
| 16973 | 17062 | block: *Block, |
| ... | ... | @@ -16977,7 +17066,6 @@ fn safetyPanic( |
| 16977 | 17066 | const msg = switch (panic_id) { |
| 16978 | 17067 | .unreach => "reached unreachable code", |
| 16979 | 17068 | .unwrap_null => "attempt to use null value", |
| 16980 | | .unwrap_errunion => "unreachable error occurred", |
| 16981 | 17069 | .cast_to_null => "cast causes pointer to be null", |
| 16982 | 17070 | .incorrect_alignment => "incorrect alignment", |
| 16983 | 17071 | .invalid_error_code => "invalid error code", |