Sema: fix peer resolution alignment between slice and empty struct

An empty struct that coerces to an empty array should not force
`align(1)` on the resulting slice type.
This commit is contained in:
Jacob Young 2024-11-16 19:40:55 -05:00
parent 7266d4497e
commit a8ec306b49
2 changed files with 23 additions and 11 deletions

View File

@ -35010,6 +35010,7 @@ fn resolvePeerTypesInner(
// if there were no actual slices. Else, we want the slice index to report a conflict.
var opt_slice_idx: ?usize = null;
var any_abi_aligned = false;
var opt_ptr_info: ?InternPool.Key.PtrType = null;
var first_idx: usize = undefined;
var other_idx: usize = undefined; // We sometimes need a second peer index to report a generic error
@ -35054,17 +35055,14 @@ fn resolvePeerTypesInner(
} };
// Note that the align can be always non-zero; Type.ptr will canonicalize it
ptr_info.flags.alignment = Alignment.min(
if (ptr_info.flags.alignment != .none)
ptr_info.flags.alignment
else
try Type.fromInterned(ptr_info.child).abiAlignmentSema(pt),
if (peer_info.flags.alignment != .none)
peer_info.flags.alignment
else
try Type.fromInterned(peer_info.child).abiAlignmentSema(pt),
);
if (peer_info.flags.alignment == .none) {
any_abi_aligned = true;
} else if (ptr_info.flags.alignment == .none) {
any_abi_aligned = true;
ptr_info.flags.alignment = peer_info.flags.alignment;
} else {
ptr_info.flags.alignment = ptr_info.flags.alignment.minStrict(peer_info.flags.alignment);
}
if (ptr_info.flags.address_space != peer_info.flags.address_space) {
return generic_err;
@ -35312,6 +35310,12 @@ fn resolvePeerTypesInner(
},
}
if (any_abi_aligned and opt_ptr_info.?.flags.alignment != .none) {
opt_ptr_info.?.flags.alignment = opt_ptr_info.?.flags.alignment.minStrict(
try Type.fromInterned(pointee).abiAlignmentSema(pt),
);
}
return .{ .success = try pt.ptrTypeSema(opt_ptr_info.?) };
},

View File

@ -995,3 +995,11 @@ test "sentinel-terminated 0-length slices" {
try expect(comptime_known_array_value[0] == 2);
try expect(runtime_array_value[0] == 2);
}
test "peer slices keep abi alignment with empty struct" {
var cond: bool = undefined;
cond = false;
const slice = if (cond) &[1]u32{42} else &.{};
comptime assert(@TypeOf(slice) == []const u32);
try expect(slice.len == 0);
}