From 6d0b8879728722d14561d747717f616cd4e7ae0c Mon Sep 17 00:00:00 2001 From: Justus Klausecker Date: Wed, 6 May 2026 09:42:40 +0200 Subject: [PATCH] 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. --- src/Sema.zig | 10 ++++++++++ .../compile_errors/ptrcast_anyopaque_to_slice.zig | 14 ++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 test/cases/compile_errors/ptrcast_anyopaque_to_slice.zig diff --git a/src/Sema.zig b/src/Sema.zig index 645e639f141e15c245de6648935a35598b8bbbba..f691a972982c7b5e5d20d4b5860c5fbab5761672 100644 --- 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 new file mode 100644 index 0000000000000000000000000000000000000000..12a9de61ee28192d87ffbb7e3ebd1091875e1659 --- /dev/null +++ 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 -- 2.54.0