authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-12-15 11:07:22+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-12-15 11:09:04+00:00
logb5d3db5fc6104f9af8ab7d3f5cf05a5d4f30f721
treed70f1a2640b46f2f0dfe64045d9367d0b9eea76e
parentaf89bb05d392b34a9ac257d166df1c794542f2e8
signaturelock-open Commit is signed but in an unrecognized format.

Sema: do not allow coercing undefined to opaque types


1 files changed, 16 insertions(+), 5 deletions(-)

src/Sema.zig+16-5
...@@ -30675,6 +30675,18 @@ fn coerceExtra(...@@ -30675,6 +30675,18 @@ fn coerceExtra(
30675 else => {},30675 else => {},
30676 }30676 }
3067730677
30678 const can_coerce_to = switch (dest_ty.zigTypeTag(zcu)) {
30679 .noreturn, .@"opaque" => false,
30680 else => true,
30681 };
30682
30683 if (can_coerce_to) {
30684 // undefined to anything. We do this after the big switch above so that
30685 // special logic has a chance to run first, such as `*[N]T` to `[]T` which
30686 // should initialize the length field of the slice.
30687 if (maybe_inst_val) |val| if (val.toIntern() == .undef) return pt.undefRef(dest_ty);
30688 }
30689
30678 if (!opts.report_err) return error.NotCoercible;30690 if (!opts.report_err) return error.NotCoercible;
3067930691
30680 if (opts.is_ret and dest_ty.zigTypeTag(zcu) == .noreturn) {30692 if (opts.is_ret and dest_ty.zigTypeTag(zcu) == .noreturn) {
...@@ -30692,15 +30704,14 @@ fn coerceExtra(...@@ -30692,15 +30704,14 @@ fn coerceExtra(
30692 return sema.failWithOwnedErrorMsg(block, msg);30704 return sema.failWithOwnedErrorMsg(block, msg);
30693 }30705 }
3069430706
30695 // undefined to anything. We do this after the big switch above so that
30696 // special logic has a chance to run first, such as `*[N]T` to `[]T` which
30697 // should initialize the length field of the slice.
30698 if (maybe_inst_val) |val| if (val.toIntern() == .undef) return pt.undefRef(dest_ty);
30699
30700 const msg = msg: {30707 const msg = msg: {
30701 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(pt), inst_ty.fmt(pt) });30708 const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(pt), inst_ty.fmt(pt) });
30702 errdefer msg.destroy(sema.gpa);30709 errdefer msg.destroy(sema.gpa);
3070330710
30711 if (!can_coerce_to) {
30712 try sema.errNote(inst_src, msg, "cannot coerce to '{}'", .{dest_ty.fmt(pt)});
30713 }
30714
30704 // E!T to T30715 // E!T to T
30705 if (inst_ty.zigTypeTag(zcu) == .error_union and30716 if (inst_ty.zigTypeTag(zcu) == .error_union and
30706 (try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(zcu), dest_ty, false, target, dest_ty_src, inst_src, maybe_inst_val)) == .ok)30717 (try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(zcu), dest_ty, false, target, dest_ty_src, inst_src, maybe_inst_val)) == .ok)