authorgravatar for enfipy@gmail.comDavid <enfipy@gmail.com> 2026-04-07 00:47:21+05:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-04-10 23:27:13+02:00
log2c6e5006ed3adb02f3bc7b364b2bbc688271d9f7
treeb12bcf10fc56dc56f8fcf6f91655610516bf8ae7
parent998b714708bd7f750a3a076e5afd47c80786e72c

Sema: fix comptime @ptrCast to optional slices


2 files changed, 24 insertions(+), 3 deletions(-)

src/Sema.zig+10-3
...@@ -21689,10 +21689,17 @@ fn ptrCastFull(...@@ -21689,10 +21689,17 @@ fn ptrCastFull(
21689 .equal_runtime_src_slice => unreachable,21689 .equal_runtime_src_slice => unreachable,
21690 .change_runtime_src_slice => unreachable,21690 .change_runtime_src_slice => unreachable,
21691 };21691 };
21692 return Air.internedToRef(try pt.intern(.{ .slice = .{21692 const dest_is_optional = dest_ty.zigTypeTag(zcu) == .optional;
21693 .ty = dest_ty.toIntern(),21693 const slice_ty = if (dest_is_optional) dest_ty.optionalChild(zcu) else dest_ty;
21694 .ptr = (try pt.getCoerced(ptr_val, dest_ty.slicePtrFieldType(zcu))).toIntern(),21694 const slice_val = try pt.intern(.{ .slice = .{
21695 .ty = slice_ty.toIntern(),
21696 .ptr = (try pt.getCoerced(ptr_val, slice_ty.slicePtrFieldType(zcu))).toIntern(),
21695 .len = len.toIntern(),21697 .len = len.toIntern(),
21698 } });
21699 if (!dest_is_optional) return Air.internedToRef(slice_val);
21700 return Air.internedToRef(try pt.intern(.{ .opt = .{
21701 .ty = dest_ty.toIntern(),
21702 .val = slice_val,
21696 } }));21703 } }));
21697 } else {21704 } else {
21698 // Any to non-slice21705 // Any to non-slice
test/behavior/cast.zig+14
...@@ -1544,6 +1544,20 @@ test "*const [N]null u8 to ?[]const u8" {...@@ -1544,6 +1544,20 @@ test "*const [N]null u8 to ?[]const u8" {
1544 try comptime S.doTheTest();1544 try comptime S.doTheTest();
1545}1545}
15461546
1547test "comptime @ptrCast to optional slice" {
1548 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1549 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1550 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1551
1552 const result: ?[]const u8 = comptime blk: {
1553 const slice: []const u8 = "123";
1554 break :blk @ptrCast(slice);
1555 };
1556
1557 comptime assert(mem.eql(u8, result.?, "123"));
1558 try expectEqualSlices(u8, "123", result.?);
1559}
1560
1547test "cast between [*c]T and ?[*:0]T on fn parameter" {1561test "cast between [*c]T and ?[*:0]T on fn parameter" {
1548 const S = struct {1562 const S = struct {
1549 const Handler = ?fn ([*c]const u8) callconv(.c) void;1563 const Handler = ?fn ([*c]const u8) callconv(.c) void;