| ... | @@ -6248,8 +6248,7 @@ fn zirErrUnionPayload( | ... | @@ -6248,8 +6248,7 @@ fn zirErrUnionPayload( |
| 6248 | } | 6248 | } |
| 6249 | try sema.requireRuntimeBlock(block, src); | 6249 | try sema.requireRuntimeBlock(block, src); |
| 6250 | if (safety_check and block.wantSafety()) { | 6250 | if (safety_check and block.wantSafety()) { |
| 6251 | const is_non_err = try block.addUnOp(.is_err, operand); | 6251 | try sema.panicUnwrapError(block, src, operand, .unwrap_errunion_err, .is_non_err); |
| 6252 | try sema.addSafetyCheck(block, is_non_err, .unwrap_errunion); | | |
| 6253 | } | 6252 | } |
| 6254 | const result_ty = operand_ty.errorUnionPayload(); | 6253 | const result_ty = operand_ty.errorUnionPayload(); |
| 6255 | return block.addTyOp(.unwrap_errunion_payload, result_ty, operand); | 6254 | return block.addTyOp(.unwrap_errunion_payload, result_ty, operand); |
| ... | @@ -6330,8 +6329,7 @@ fn analyzeErrUnionPayloadPtr( | ... | @@ -6330,8 +6329,7 @@ fn analyzeErrUnionPayloadPtr( |
| 6330 | | 6329 | |
| 6331 | try sema.requireRuntimeBlock(block, src); | 6330 | try sema.requireRuntimeBlock(block, src); |
| 6332 | if (safety_check and block.wantSafety()) { | 6331 | if (safety_check and block.wantSafety()) { |
| 6333 | const is_non_err = try block.addUnOp(.is_err, operand); | 6332 | try sema.panicUnwrapError(block, src, operand, .unwrap_errunion_err_ptr, .is_non_err_ptr); |
| 6334 | try sema.addSafetyCheck(block, is_non_err, .unwrap_errunion); | | |
| 6335 | } | 6333 | } |
| 6336 | const air_tag: Air.Inst.Tag = if (initializing) | 6334 | const air_tag: Air.Inst.Tag = if (initializing) |
| 6337 | .errunion_payload_ptr_set | 6335 | .errunion_payload_ptr_set |
| ... | @@ -13400,6 +13398,10 @@ fn zirErrorReturnTrace( | ... | @@ -13400,6 +13398,10 @@ fn zirErrorReturnTrace( |
| 13400 | extended: Zir.Inst.Extended.InstData, | 13398 | extended: Zir.Inst.Extended.InstData, |
| 13401 | ) CompileError!Air.Inst.Ref { | 13399 | ) CompileError!Air.Inst.Ref { |
| 13402 | const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) }; | 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 | const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace"); | 13405 | const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace"); |
| 13404 | const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty); | 13406 | const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty); |
| 13405 | const opt_ptr_stack_trace_ty = try Type.Tag.optional_single_mut_pointer.create(sema.arena, stack_trace_ty); | 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,7 +16854,6 @@ fn explainWhyTypeIsComptime( |
| 16852 | pub const PanicId = enum { | 16854 | pub const PanicId = enum { |
| 16853 | unreach, | 16855 | unreach, |
| 16854 | unwrap_null, | 16856 | unwrap_null, |
| 16855 | unwrap_errunion, | | |
| 16856 | cast_to_null, | 16857 | cast_to_null, |
| 16857 | incorrect_alignment, | 16858 | incorrect_alignment, |
| 16858 | invalid_error_code, | 16859 | invalid_error_code, |
| ... | @@ -16962,12 +16963,100 @@ fn panicWithMsg( | ... | @@ -16962,12 +16963,100 @@ fn panicWithMsg( |
| 16962 | try Type.optional(arena, ptr_stack_trace_ty), | 16963 | try Type.optional(arena, ptr_stack_trace_ty), |
| 16963 | Value.@"null", | 16964 | Value.@"null", |
| 16964 | ); | 16965 | ); |
| 16965 | const args = try arena.create([2]Air.Inst.Ref); | 16966 | const args: [2]Air.Inst.Ref = .{ msg_inst, null_stack_trace }; |
| 16966 | args.* = .{ msg_inst, null_stack_trace }; | 16967 | _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, &args); |
| 16967 | _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, args); | | |
| 16968 | return always_noreturn; | 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 | fn safetyPanic( | 17060 | fn safetyPanic( |
| 16972 | sema: *Sema, | 17061 | sema: *Sema, |
| 16973 | block: *Block, | 17062 | block: *Block, |
| ... | @@ -16977,7 +17066,6 @@ fn safetyPanic( | ... | @@ -16977,7 +17066,6 @@ fn safetyPanic( |
| 16977 | const msg = switch (panic_id) { | 17066 | const msg = switch (panic_id) { |
| 16978 | .unreach => "reached unreachable code", | 17067 | .unreach => "reached unreachable code", |
| 16979 | .unwrap_null => "attempt to use null value", | 17068 | .unwrap_null => "attempt to use null value", |
| 16980 | .unwrap_errunion => "unreachable error occurred", | | |
| 16981 | .cast_to_null => "cast causes pointer to be null", | 17069 | .cast_to_null => "cast causes pointer to be null", |
| 16982 | .incorrect_alignment => "incorrect alignment", | 17070 | .incorrect_alignment => "incorrect alignment", |
| 16983 | .invalid_error_code => "invalid error code", | 17071 | .invalid_error_code => "invalid error code", |