commit 6d0b8879728722d14561d747717f616cd4e7ae0c (tree)
parent fecd28371d5c0e25357dfb91f75c8790f8b4155b
Author: Justus Klausecker <justus@klausecker.de>
Date: Wed, 6 May 2026 09:42:40 +0200
Sema: disallow pointer cast from pointer to opaque type to slice
Fixes a regression where this conversion crashes. When the conversion was
still possible it would produce a slice with a length of zero, which doesn't
really make a lot of sense either. There's no way to determine the length
of the destination slice from a pointer to an opaque type, so it's a compile
error now. Users should just cast to a many-item pointer and slice to the
desired length manually instead.
Diffstat:
2 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/src/Sema.zig b/src/Sema.zig
@@ -21154,6 +21154,16 @@ fn ptrCastFull(
break :len if (opt_src_len) |l| .{ .constant = l } else .equal_runtime_src_slice;
}
if (!src_elem_ty.comptimeOnly(zcu) and !dest_elem_ty.comptimeOnly(zcu)) {
+ if (src_elem_ty.zigTypeTag(zcu) == .@"opaque") {
+ return sema.failWithOwnedErrorMsg(block, msg: {
+ const msg = try sema.errMsg(src, "cannot infer length of slice of '{f}' from pointer to opaque type '{f}' with unknown size", .{
+ dest_elem_ty.fmt(pt), src_elem_ty.fmt(pt),
+ });
+ errdefer msg.destroy(gpa);
+ try sema.addDeclaredHereNote(msg, src_elem_ty);
+ break :msg msg;
+ });
+ }
const src_elem_size = src_elem_ty.abiSize(zcu);
const dest_elem_size = dest_elem_ty.abiSize(zcu);
if (dest_elem_size == 0) {
diff --git a/test/cases/compile_errors/ptrcast_anyopaque_to_slice.zig b/test/cases/compile_errors/ptrcast_anyopaque_to_slice.zig
@@ -0,0 +1,14 @@
+export fn entry1(x: *anyopaque) void {
+ _ = @as([]u8, @ptrCast(x));
+}
+
+const Opaque = opaque {};
+export fn entry2(x: *Opaque) void {
+ _ = @as([]u8, @ptrCast(x));
+}
+
+// error
+//
+// :2:19: error: cannot infer length of slice of 'u8' from pointer to opaque type 'anyopaque' with unknown size
+// :7:19: error: cannot infer length of slice of 'u8' from pointer to opaque type 'tmp.Opaque' with unknown size
+// :5:16: note: opaque declared here