| ... | @@ -8060,7 +8060,7 @@ fn analyzeCall( | ... | @@ -8060,7 +8060,7 @@ fn analyzeCall( |
| 8060 | }; | 8060 | }; |
| 8061 | | 8061 | |
| 8062 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).@"struct".fields.len + runtime_args.len); | 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 | .tag = call_tag, | 8064 | .tag = call_tag, |
| 8065 | .data = .{ .pl_op = .{ | 8065 | .data = .{ .pl_op = .{ |
| 8066 | .operand = runtime_func, | 8066 | .operand = runtime_func, |
| ... | @@ -8072,7 +8072,7 @@ fn analyzeCall( | ... | @@ -8072,7 +8072,7 @@ fn analyzeCall( |
| 8072 | sema.appendRefsAssumeCapacity(runtime_args); | 8072 | sema.appendRefsAssumeCapacity(runtime_args); |
| 8073 | | 8073 | |
| 8074 | if (ensure_result_used) { | 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 | if (call_tag == .call_always_tail) { | 8078 | if (call_tag == .call_always_tail) { |
| ... | @@ -8082,10 +8082,10 @@ fn analyzeCall( | ... | @@ -8082,10 +8082,10 @@ fn analyzeCall( |
| 8082 | .pointer => func_or_ptr_ty.childType(zcu), | 8082 | .pointer => func_or_ptr_ty.childType(zcu), |
| 8083 | else => unreachable, | 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 | const want_check = c: { | 8089 | const want_check = c: { |
| 8090 | if (!block.wantSafety()) break :c false; | 8090 | if (!block.wantSafety()) break :c false; |
| 8091 | if (func_val != null) break :c false; | 8091 | if (func_val != null) break :c false; |
| ... | @@ -8099,6 +8099,11 @@ fn analyzeCall( | ... | @@ -8099,6 +8099,11 @@ fn analyzeCall( |
| 8099 | return .unreachable_value; | 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 | return result; | 8107 | return result; |
| 8103 | } | 8108 | } |
| 8104 | | 8109 | |
| ... | @@ -8335,7 +8340,7 @@ fn analyzeCall( | ... | @@ -8335,7 +8340,7 @@ fn analyzeCall( |
| 8335 | break :result try sema.resolveAnalyzedBlock(block, call_src, &child_block, &inlining.merges, need_debug_scope); | 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 | const val_resolved = try sema.resolveAdHocInferredErrorSet(block, call_src, result_val.toIntern()); | 8344 | const val_resolved = try sema.resolveAdHocInferredErrorSet(block, call_src, result_val.toIntern()); |
| 8340 | break :r Air.internedToRef(val_resolved); | 8345 | break :r Air.internedToRef(val_resolved); |
| 8341 | } else r: { | 8346 | } else r: { |
| ... | @@ -8347,7 +8352,7 @@ fn analyzeCall( | ... | @@ -8347,7 +8352,7 @@ fn analyzeCall( |
| 8347 | }; | 8352 | }; |
| 8348 | | 8353 | |
| 8349 | if (block.isComptime()) { | 8354 | if (block.isComptime()) { |
| 8350 | const result_val = (try sema.resolveValue(result)).?; | 8355 | const result_val = (try sema.resolveValue(maybe_opv)).?; |
| 8351 | if (want_memoize and sema.allow_memoize and !result_val.canMutateComptimeVarState(zcu)) { | 8356 | if (want_memoize and sema.allow_memoize and !result_val.canMutateComptimeVarState(zcu)) { |
| 8352 | _ = try pt.intern(.{ .memoized_call = .{ | 8357 | _ = try pt.intern(.{ .memoized_call = .{ |
| 8353 | .func = func_val.?.toIntern(), | 8358 | .func = func_val.?.toIntern(), |
| ... | @@ -8359,10 +8364,10 @@ fn analyzeCall( | ... | @@ -8359,10 +8364,10 @@ fn analyzeCall( |
| 8359 | } | 8364 | } |
| 8360 | | 8365 | |
| 8361 | if (ensure_result_used) { | 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 | fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref { | 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,10 +9070,14 @@ fn zirOptionalPayload( |
| 9065 | }; | 9070 | }; |
| 9066 | | 9071 | |
| 9067 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { | 9072 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { |
| 9068 | return if (val.optionalValue(zcu)) |payload| | 9073 | if (val.optionalValue(zcu)) |payload| return Air.internedToRef(payload.toIntern()); |
| 9069 | Air.internedToRef(payload.toIntern()) | 9074 | if (block.isComptime()) return sema.fail(block, src, "unable to unwrap null", .{}); |
| 9070 | else | 9075 | if (safety_check and block.wantSafety()) { |
| 9071 | sema.fail(block, src, "unable to unwrap null", .{}); | 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 | try sema.requireRuntimeBlock(block, src, null); | 9083 | try sema.requireRuntimeBlock(block, src, null); |
| ... | @@ -36443,7 +36452,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36443,7 +36452,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36443 | .type_int_unsigned, // u0 handled above | 36452 | .type_int_unsigned, // u0 handled above |
| 36444 | .type_pointer, | 36453 | .type_pointer, |
| 36445 | .type_slice, | 36454 | .type_slice, |
| 36446 | .type_optional, // ?noreturn handled above | | |
| 36447 | .type_anyframe, | 36455 | .type_anyframe, |
| 36448 | .type_error_union, | 36456 | .type_error_union, |
| 36449 | .type_anyerror_union, | 36457 | .type_anyerror_union, |
| ... | @@ -36655,6 +36663,15 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -36655,6 +36663,15 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 36655 | | 36663 | |
| 36656 | else => unreachable, | 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 | } |