authorgravatar for carl@astholm.seCarl Åstholm <carl@astholm.se> 2024-02-13 22:30:14+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-04-07 15:10:49-07:00
log278db0ad4543d7a768c63c5482b8873b58690920
tree74dae2e3443bc7018ff2878f08a1c6e475931cfe
parentfdd6c31e8b25f9eed81c1e78fa71eca17fd29f68

Sema: support coercing ref to anonymous array init to many-pointer


2 files changed, 73 insertions(+), 8 deletions(-)

src/Sema.zig+14-8
......@@ -4557,14 +4557,20 @@ fn zirValidateArrayInitRefTy(
45574557 };
45584558 const ptr_ty = maybe_wrapped_ptr_ty.optEuBaseType(mod);
45594559 assert(ptr_ty.zigTypeTag(mod) == .Pointer); // validated by a previous instruction
4560 if (ptr_ty.isSlice(mod)) {
4561 // Use array of correct length
4562 const arr_ty = try mod.arrayType(.{
4563 .len = extra.elem_count,
4564 .child = ptr_ty.childType(mod).toIntern(),
4565 .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,
4566 });
4567 return Air.internedToRef(arr_ty.toIntern());
4560 switch (mod.intern_pool.indexToKey(ptr_ty.toIntern())) {
4561 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
4562 .Slice, .Many => {
4563 // Use array of correct length
4564 const arr_ty = try mod.arrayType(.{
4565 .len = extra.elem_count,
4566 .child = ptr_ty.childType(mod).toIntern(),
4567 .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,
4568 });
4569 return Air.internedToRef(arr_ty.toIntern());
4570 },
4571 else => {},
4572 },
4573 else => {},
45684574 }
45694575 // Otherwise, we just want the pointer child type
45704576 const ret_ty = ptr_ty.childType(mod);
test/behavior/array.zig+59
......@@ -804,6 +804,52 @@ test "slice initialized through reference to anonymous array init provides resul
804804 try std.testing.expectEqualSlices(u16, &.{ 123, 456, 123, 456 }, foo);
805805}
806806
807test "sentinel-terminated slice initialized through reference to anonymous array init provides result types" {
808 var my_u32: u32 = 123;
809 var my_u64: u64 = 456;
810 _ = .{ &my_u32, &my_u64 };
811 const foo: [:999]const u16 = &.{
812 @intCast(my_u32),
813 @intCast(my_u64),
814 @truncate(my_u32),
815 @truncate(my_u64),
816 };
817 try std.testing.expectEqualSentinel(u16, 999, &.{ 123, 456, 123, 456 }, foo);
818}
819
820test "many-item pointer initialized through reference to anonymous array init provides result types" {
821 var my_u32: u32 = 123;
822 var my_u64: u64 = 456;
823 _ = .{ &my_u32, &my_u64 };
824 const foo: [*]const u16 = &.{
825 @intCast(my_u32),
826 @intCast(my_u64),
827 @truncate(my_u32),
828 @truncate(my_u64),
829 };
830 try expectEqual(123, foo[0]);
831 try expectEqual(456, foo[1]);
832 try expectEqual(123, foo[2]);
833 try expectEqual(456, foo[3]);
834}
835
836test "many-item sentinel-terminated pointer initialized through reference to anonymous array init provides result types" {
837 var my_u32: u32 = 123;
838 var my_u64: u64 = 456;
839 _ = .{ &my_u32, &my_u64 };
840 const foo: [*:999]const u16 = &.{
841 @intCast(my_u32),
842 @intCast(my_u64),
843 @truncate(my_u32),
844 @truncate(my_u64),
845 };
846 try expectEqual(123, foo[0]);
847 try expectEqual(456, foo[1]);
848 try expectEqual(123, foo[2]);
849 try expectEqual(456, foo[3]);
850 try expectEqual(999, foo[4]);
851}
852
807853test "pointer to array initialized through reference to anonymous array init provides result types" {
808854 var my_u32: u32 = 123;
809855 var my_u64: u64 = 456;
......@@ -817,6 +863,19 @@ test "pointer to array initialized through reference to anonymous array init pro
817863 try std.testing.expectEqualSlices(u16, &.{ 123, 456, 123, 456 }, foo);
818864}
819865
866test "pointer to sentinel-terminated array initialized through reference to anonymous array init provides result types" {
867 var my_u32: u32 = 123;
868 var my_u64: u64 = 456;
869 _ = .{ &my_u32, &my_u64 };
870 const foo: *const [4:999]u16 = &.{
871 @intCast(my_u32),
872 @intCast(my_u64),
873 @truncate(my_u32),
874 @truncate(my_u64),
875 };
876 try std.testing.expectEqualSentinel(u16, 999, &.{ 123, 456, 123, 456 }, foo);
877}
878
820879test "tuple initialized through reference to anonymous array init provides result types" {
821880 const Tuple = struct { u64, *const u32 };
822881 const foo: *const Tuple = &.{