From 955fd65cb1705d8279eb195bdbc69810df1b1d98 Mon Sep 17 00:00:00 2001 From: garrison hinson-hasty <71951273+garrisonhh@users.noreply.github.com> Date: Tue, 20 Feb 2024 19:55:29 -0500 Subject: [PATCH] Sema: fix peer type resolution for arrays of coercible elements --- src/Sema.zig | 16 +++++++++++++++- test/behavior/cast.zig | 17 +++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/Sema.zig b/src/Sema.zig index 81ee58b7c2..0a38cf93dc 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -34238,7 +34238,21 @@ fn resolvePeerTypesInner( .peer_idx_b = i, } }; - if (!ty.childType(mod).eql(elem_ty, mod)) { + const peer_elem_ty = ty.childType(mod); + if (!peer_elem_ty.eql(elem_ty, mod)) coerce: { + const peer_elem_coerces_to_elem = + try sema.coerceInMemoryAllowed(block, elem_ty, peer_elem_ty, false, mod.getTarget(), src, src); + if (peer_elem_coerces_to_elem == .ok) { + break :coerce; + } + + const elem_coerces_to_peer_elem = + try sema.coerceInMemoryAllowed(block, peer_elem_ty, elem_ty, false, mod.getTarget(), src, src); + if (elem_coerces_to_peer_elem == .ok) { + elem_ty = peer_elem_ty; + break :coerce; + } + return .{ .conflict = .{ .peer_idx_a = first_arr_idx, .peer_idx_b = i, diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index aa32752dbe..2ed29eb92d 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -2201,6 +2201,23 @@ test "peer type resolution: pointer attributes are combined correctly" { try expectEqualSlices(u8, std.mem.span(@volatileCast(r3)), "baz"); } +test "peer type resolution: arrays of compatible types" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + + var e0: u8 = 3; + var e1: u8 = 2; + var e2: u8 = 1; + const a = [3]*u8{ &e0, &e1, &e2 }; + const b = [3]*const u8{ &e0, &e1, &e2 }; + + comptime assert(@TypeOf(a, b) == [3]*const u8); + comptime assert(@TypeOf(b, a) == [3]*const u8); + + try expectEqual(@as(@TypeOf(a, b), a), b); +} + test "cast builtins can wrap result in optional" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO