zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 2c6e5006ed3adb02f3bc7b364b2bbc688271d9f7 (tree)
parent 998b714708bd7f750a3a076e5afd47c80786e72c
Author: David <enfipy@gmail.com>
Date:   Tue,  7 Apr 2026 00:47:21 +0500

Sema: fix comptime @ptrCast to optional slices

Diffstat:
Msrc/Sema.zig | 13++++++++++---
Mtest/behavior/cast.zig | 14++++++++++++++
2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/src/Sema.zig b/src/Sema.zig @@ -21689,10 +21689,17 @@ fn ptrCastFull( .equal_runtime_src_slice => unreachable, .change_runtime_src_slice => unreachable, }; - return Air.internedToRef(try pt.intern(.{ .slice = .{ - .ty = dest_ty.toIntern(), - .ptr = (try pt.getCoerced(ptr_val, dest_ty.slicePtrFieldType(zcu))).toIntern(), + const dest_is_optional = dest_ty.zigTypeTag(zcu) == .optional; + const slice_ty = if (dest_is_optional) dest_ty.optionalChild(zcu) else dest_ty; + const slice_val = try pt.intern(.{ .slice = .{ + .ty = slice_ty.toIntern(), + .ptr = (try pt.getCoerced(ptr_val, slice_ty.slicePtrFieldType(zcu))).toIntern(), .len = len.toIntern(), + } }); + if (!dest_is_optional) return Air.internedToRef(slice_val); + return Air.internedToRef(try pt.intern(.{ .opt = .{ + .ty = dest_ty.toIntern(), + .val = slice_val, } })); } else { // Any to non-slice diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig @@ -1544,6 +1544,20 @@ test "*const [N]null u8 to ?[]const u8" { try comptime S.doTheTest(); } +test "comptime @ptrCast to optional slice" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + + const result: ?[]const u8 = comptime blk: { + const slice: []const u8 = "123"; + break :blk @ptrCast(slice); + }; + + comptime assert(mem.eql(u8, result.?, "123")); + try expectEqualSlices(u8, "123", result.?); +} + test "cast between [*c]T and ?[*:0]T on fn parameter" { const S = struct { const Handler = ?fn ([*c]const u8) callconv(.c) void;