Commit 955fd65cb1

garrison hinson-hasty <71951273+garrisonhh@users.noreply.github.com>
2024-02-21 01:55:29
Sema: fix peer type resolution for arrays of coercible elements
1 parent ec72934
Changed files (2)
src
test
behavior
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,
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