| author | |
| committer | |
| log | 2c6e5006ed3adb02f3bc7b364b2bbc688271d9f7 |
| tree | b12bcf10fc56dc56f8fcf6f91655610516bf8ae7 |
| parent | 998b714708bd7f750a3a076e5afd47c80786e72c |
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-slice | 21705 | // 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 | } |
| 1546 | 1546 | ||
| 1547 | test "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 | |||
| 1547 | test "cast between [*c]T and ?[*:0]T on fn parameter" { | 1561 | test "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; |