diff --git a/src/Sema.zig b/src/Sema.zig index 39d687c18a..3635d39b98 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -4557,14 +4557,20 @@ fn zirValidateArrayInitRefTy( }; const ptr_ty = maybe_wrapped_ptr_ty.optEuBaseType(mod); assert(ptr_ty.zigTypeTag(mod) == .Pointer); // validated by a previous instruction - if (ptr_ty.isSlice(mod)) { - // Use array of correct length - const arr_ty = try mod.arrayType(.{ - .len = extra.elem_count, - .child = ptr_ty.childType(mod).toIntern(), - .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none, - }); - return Air.internedToRef(arr_ty.toIntern()); + switch (mod.intern_pool.indexToKey(ptr_ty.toIntern())) { + .ptr_type => |ptr_type| switch (ptr_type.flags.size) { + .Slice, .Many => { + // Use array of correct length + const arr_ty = try mod.arrayType(.{ + .len = extra.elem_count, + .child = ptr_ty.childType(mod).toIntern(), + .sentinel = if (ptr_ty.sentinel(mod)) |s| s.toIntern() else .none, + }); + return Air.internedToRef(arr_ty.toIntern()); + }, + else => {}, + }, + else => {}, } // Otherwise, we just want the pointer child type const ret_ty = ptr_ty.childType(mod); diff --git a/test/behavior/array.zig b/test/behavior/array.zig index a56e382821..6397094398 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -804,6 +804,52 @@ test "slice initialized through reference to anonymous array init provides resul try std.testing.expectEqualSlices(u16, &.{ 123, 456, 123, 456 }, foo); } +test "sentinel-terminated slice initialized through reference to anonymous array init provides result types" { + var my_u32: u32 = 123; + var my_u64: u64 = 456; + _ = .{ &my_u32, &my_u64 }; + const foo: [:999]const u16 = &.{ + @intCast(my_u32), + @intCast(my_u64), + @truncate(my_u32), + @truncate(my_u64), + }; + try std.testing.expectEqualSentinel(u16, 999, &.{ 123, 456, 123, 456 }, foo); +} + +test "many-item pointer initialized through reference to anonymous array init provides result types" { + var my_u32: u32 = 123; + var my_u64: u64 = 456; + _ = .{ &my_u32, &my_u64 }; + const foo: [*]const u16 = &.{ + @intCast(my_u32), + @intCast(my_u64), + @truncate(my_u32), + @truncate(my_u64), + }; + try expectEqual(123, foo[0]); + try expectEqual(456, foo[1]); + try expectEqual(123, foo[2]); + try expectEqual(456, foo[3]); +} + +test "many-item sentinel-terminated pointer initialized through reference to anonymous array init provides result types" { + var my_u32: u32 = 123; + var my_u64: u64 = 456; + _ = .{ &my_u32, &my_u64 }; + const foo: [*:999]const u16 = &.{ + @intCast(my_u32), + @intCast(my_u64), + @truncate(my_u32), + @truncate(my_u64), + }; + try expectEqual(123, foo[0]); + try expectEqual(456, foo[1]); + try expectEqual(123, foo[2]); + try expectEqual(456, foo[3]); + try expectEqual(999, foo[4]); +} + test "pointer to array initialized through reference to anonymous array init provides result types" { var my_u32: u32 = 123; var my_u64: u64 = 456; @@ -817,6 +863,19 @@ test "pointer to array initialized through reference to anonymous array init pro try std.testing.expectEqualSlices(u16, &.{ 123, 456, 123, 456 }, foo); } +test "pointer to sentinel-terminated array initialized through reference to anonymous array init provides result types" { + var my_u32: u32 = 123; + var my_u64: u64 = 456; + _ = .{ &my_u32, &my_u64 }; + const foo: *const [4:999]u16 = &.{ + @intCast(my_u32), + @intCast(my_u64), + @truncate(my_u32), + @truncate(my_u64), + }; + try std.testing.expectEqualSentinel(u16, 999, &.{ 123, 456, 123, 456 }, foo); +} + test "tuple initialized through reference to anonymous array init provides result types" { const Tuple = struct { u64, *const u32 }; const foo: *const Tuple = &.{