@@ -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
}
0 commit comments