| ... | ... | @@ -8060,7 +8060,7 @@ fn analyzeCall( |
| 8060 | 8060 | }; |
| 8061 | 8061 | |
| 8062 | 8062 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).@"struct".fields.len + runtime_args.len); |
| 8063 | | const result = try block.addInst(.{ |
| 8063 | const maybe_opv = try block.addInst(.{ |
| 8064 | 8064 | .tag = call_tag, |
| 8065 | 8065 | .data = .{ .pl_op = .{ |
| 8066 | 8066 | .operand = runtime_func, |
| ... | ... | @@ -8072,7 +8072,7 @@ fn analyzeCall( |
| 8072 | 8072 | sema.appendRefsAssumeCapacity(runtime_args); |
| 8073 | 8073 | |
| 8074 | 8074 | if (ensure_result_used) { |
| 8075 | | try sema.ensureResultUsed(block, sema.typeOf(result), call_src); |
| 8075 | try sema.ensureResultUsed(block, sema.typeOf(maybe_opv), call_src); |
| 8076 | 8076 | } |
| 8077 | 8077 | |
| 8078 | 8078 | if (call_tag == .call_always_tail) { |
| ... | ... | @@ -8082,10 +8082,10 @@ fn analyzeCall( |
| 8082 | 8082 | .pointer => func_or_ptr_ty.childType(zcu), |
| 8083 | 8083 | else => unreachable, |
| 8084 | 8084 | }; |
| 8085 | | return sema.handleTailCall(block, call_src, runtime_func_ty, result); |
| 8085 | return sema.handleTailCall(block, call_src, runtime_func_ty, maybe_opv); |
| 8086 | 8086 | } |
| 8087 | 8087 | |
| 8088 | | if (resolved_ret_ty.toIntern() == .noreturn_type) { |
| 8088 | if (ip.isNoReturn(resolved_ret_ty.toIntern())) { |
| 8089 | 8089 | const want_check = c: { |
| 8090 | 8090 | if (!block.wantSafety()) break :c false; |
| 8091 | 8091 | if (func_val != null) break :c false; |
| ... | ... | @@ -8099,6 +8099,11 @@ fn analyzeCall( |
| 8099 | 8099 | return .unreachable_value; |
| 8100 | 8100 | } |
| 8101 | 8101 | |
| 8102 | const result: Air.Inst.Ref = if (try sema.typeHasOnePossibleValue(sema.typeOf(maybe_opv))) |opv| |
| 8103 | .fromValue(opv) |
| 8104 | else |
| 8105 | maybe_opv; |
| 8106 | |
| 8102 | 8107 | return result; |
| 8103 | 8108 | } |
| 8104 | 8109 | |
| ... | ... | @@ -8335,7 +8340,7 @@ fn analyzeCall( |
| 8335 | 8340 | break :result try sema.resolveAnalyzedBlock(block, call_src, &child_block, &inlining.merges, need_debug_scope); |
| 8336 | 8341 | }; |
| 8337 | 8342 | |
| 8338 | | const result: Air.Inst.Ref = if (try sema.resolveValue(result_raw)) |result_val| r: { |
| 8343 | const maybe_opv: Air.Inst.Ref = if (try sema.resolveValue(result_raw)) |result_val| r: { |
| 8339 | 8344 | const val_resolved = try sema.resolveAdHocInferredErrorSet(block, call_src, result_val.toIntern()); |
| 8340 | 8345 | break :r Air.internedToRef(val_resolved); |
| 8341 | 8346 | } else r: { |
| ... | ... | @@ -8347,7 +8352,7 @@ fn analyzeCall( |
| 8347 | 8352 | }; |
| 8348 | 8353 | |
| 8349 | 8354 | if (block.isComptime()) { |
| 8350 | | const result_val = (try sema.resolveValue(result)).?; |
| 8355 | const result_val = (try sema.resolveValue(maybe_opv)).?; |
| 8351 | 8356 | if (want_memoize and sema.allow_memoize and !result_val.canMutateComptimeVarState(zcu)) { |
| 8352 | 8357 | _ = try pt.intern(.{ .memoized_call = .{ |
| 8353 | 8358 | .func = func_val.?.toIntern(), |
| ... | ... | @@ -8359,10 +8364,10 @@ fn analyzeCall( |
| 8359 | 8364 | } |
| 8360 | 8365 | |
| 8361 | 8366 | if (ensure_result_used) { |
| 8362 | | try sema.ensureResultUsed(block, sema.typeOf(result), call_src); |
| 8367 | try sema.ensureResultUsed(block, sema.typeOf(maybe_opv), call_src); |
| 8363 | 8368 | } |
| 8364 | 8369 | |
| 8365 | | return result; |
| 8370 | return maybe_opv; |
| 8366 | 8371 | } |
| 8367 | 8372 | |
| 8368 | 8373 | fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref { |
| ... | ... | @@ -9065,10 +9070,14 @@ fn zirOptionalPayload( |
| 9065 | 9070 | }; |
| 9066 | 9071 | |
| 9067 | 9072 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { |
| 9068 | | return if (val.optionalValue(zcu)) |payload| |
| 9069 | | Air.internedToRef(payload.toIntern()) |
| 9070 | | else |
| 9071 | | sema.fail(block, src, "unable to unwrap null", .{}); |
| 9073 | if (val.optionalValue(zcu)) |payload| return Air.internedToRef(payload.toIntern()); |
| 9074 | if (block.isComptime()) return sema.fail(block, src, "unable to unwrap null", .{}); |
| 9075 | if (safety_check and block.wantSafety()) { |
| 9076 | try sema.safetyPanic(block, src, .unwrap_null); |
| 9077 | } else { |
| 9078 | _ = try block.addNoOp(.unreach); |
| 9079 | } |
| 9080 | return .unreachable_value; |
| 9072 | 9081 | } |
| 9073 | 9082 | |
| 9074 | 9083 | try sema.requireRuntimeBlock(block, src, null); |
| ... | ... | @@ -36443,7 +36452,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36443 | 36452 | .type_int_unsigned, // u0 handled above |
| 36444 | 36453 | .type_pointer, |
| 36445 | 36454 | .type_slice, |
| 36446 | | .type_optional, // ?noreturn handled above |
| 36447 | 36455 | .type_anyframe, |
| 36448 | 36456 | .type_error_union, |
| 36449 | 36457 | .type_anyerror_union, |
| ... | ... | @@ -36655,6 +36663,15 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36655 | 36663 | |
| 36656 | 36664 | else => unreachable, |
| 36657 | 36665 | }, |
| 36666 | |
| 36667 | .type_optional => { |
| 36668 | const payload_ip = ip.indexToKey(ty.toIntern()).opt_type; |
| 36669 | // Although ?noreturn is handled above, the element type |
| 36670 | // can be effectively noreturn for example via an empty |
| 36671 | // enum or error set. |
| 36672 | if (ip.isNoReturn(payload_ip)) return try pt.nullValue(ty); |
| 36673 | return null; |
| 36674 | }, |
| 36658 | 36675 | }, |
| 36659 | 36676 | }; |
| 36660 | 36677 | } |