Skip to content

Commit 278db0a

Browse files
castholmandrewrk
authored andcommitted
Sema: support coercing ref to anonymous array init to many-pointer
1 parent fdd6c31 commit 278db0a

File tree

2 files changed

+73
-8
lines changed

2 files changed

+73
-8
lines changed

src/Sema.zig

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

807+
test "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+
820+
test "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+
836+
test "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+
807853
test "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

866+
test "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+
820879
test "tuple initialized through reference to anonymous array init provides result types" {
821880
const Tuple = struct { u64, *const u32 };
822881
const foo: *const Tuple = &.{

0 commit comments

Comments
 (0)