From a8ec306b493ddac701f279bfe82808525956f3f2 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 16 Nov 2024 19:40:55 -0500 Subject: [PATCH] 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. --- src/Sema.zig | 26 +++++++++++++++----------- test/behavior/slice.zig | 8 ++++++++ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index b99852fb0a..70212e0a63 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -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.?) }; }, diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index 15db19f1e8..4f5367ad85 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -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); +}