aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2024-12-15 11:07:22 +0000
committermlugg <mlugg@mlugg.co.uk>2024-12-15 11:09:04 +0000
commitb5d3db5fc6104f9af8ab7d3f5cf05a5d4f30f721 (patch)
treed70f1a2640b46f2f0dfe64045d9367d0b9eea76e /src
parentaf89bb05d392b34a9ac257d166df1c794542f2e8 (diff)
downloadzig-b5d3db5fc6104f9af8ab7d3f5cf05a5d4f30f721.tar.gz
zig-b5d3db5fc6104f9af8ab7d3f5cf05a5d4f30f721.zip
Sema: do not allow coercing undefined to opaque types
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index f31e71047f..7cd8e0e635 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -30675,6 +30675,18 @@ fn coerceExtra(
else => {},
}
+ const can_coerce_to = switch (dest_ty.zigTypeTag(zcu)) {
+ .noreturn, .@"opaque" => false,
+ else => true,
+ };
+
+ if (can_coerce_to) {
+ // undefined to anything. We do this after the big switch above so that
+ // special logic has a chance to run first, such as `*[N]T` to `[]T` which
+ // should initialize the length field of the slice.
+ if (maybe_inst_val) |val| if (val.toIntern() == .undef) return pt.undefRef(dest_ty);
+ }
+
if (!opts.report_err) return error.NotCoercible;
if (opts.is_ret and dest_ty.zigTypeTag(zcu) == .noreturn) {
@@ -30692,15 +30704,14 @@ fn coerceExtra(
return sema.failWithOwnedErrorMsg(block, msg);
}
- // undefined to anything. We do this after the big switch above so that
- // special logic has a chance to run first, such as `*[N]T` to `[]T` which
- // should initialize the length field of the slice.
- if (maybe_inst_val) |val| if (val.toIntern() == .undef) return pt.undefRef(dest_ty);
-
const msg = msg: {
const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(pt), inst_ty.fmt(pt) });
errdefer msg.destroy(sema.gpa);
+ if (!can_coerce_to) {
+ try sema.errNote(inst_src, msg, "cannot coerce to '{}'", .{dest_ty.fmt(pt)});
+ }
+
// E!T to T
if (inst_ty.zigTypeTag(zcu) == .error_union and
(try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(zcu), dest_ty, false, target, dest_ty_src, inst_src, maybe_inst_val)) == .ok)