mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
Sema: support coercing ref to anonymous array init to many-pointer
This commit is contained in:
parent
fdd6c31e8b
commit
278db0ad45
22
src/Sema.zig
22
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);
|
||||
|
||||
@ -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 = &.{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user