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(
2168921689 .equal_runtime_src_slice => unreachable,
2169021690 .change_runtime_src_slice => unreachable,
2169121691 };
21692 return Air.internedToRef(try pt.intern(.{ .slice = .{
21693 .ty = dest_ty.toIntern(),
21694 .ptr = (try pt.getCoerced(ptr_val, dest_ty.slicePtrFieldType(zcu))).toIntern(),
21692 const dest_is_optional = dest_ty.zigTypeTag(zcu) == .optional;
21693 const slice_ty = if (dest_is_optional) dest_ty.optionalChild(zcu) else dest_ty;
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(),
2169521697 .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,
2169621703 } }));
2169721704 } else {
2169821705 // Any to non-slice
test/behavior/cast.zig+14
......@@ -1544,6 +1544,20 @@ test "*const [N]null u8 to ?[]const u8" {
15441544 try comptime S.doTheTest();
15451545}
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
15471561test "cast between [*c]T and ?[*:0]T on fn parameter" {
15481562 const S = struct {
15491563 const Handler = ?fn ([*c]const u8) callconv(.c) void;